Malicious user can prevent rDPX options from being exercised #488
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-1227
satisfactory
satisfies C4 submission criteria; eligible for awards
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L772-L774
https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/perp-vault/PerpetualAtlanticVault.sol#L346-L361
https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L199-L205
Vulnerability details
Impact
The Core contract admin can exercise/settle rDPX options at any point in time by calling
settle
to bring back the peg and back the backing reserves with more ETH.However a malicious user can send dust WETH directly to the
PerpetualAtlanticVaultLP.sol
contract to cause a check insubtractLoss
to consistently revert. This state can be persisted indefinitely and will prevent any rDPX options from being exercised and therefore the protocol admin cannot use this mechanism to control the DpxEth peg.Proof of Concept
When the admin wants to exercise some options they can call
settle
in the core contract, specifying the option ids they want to exercise:As you can see this makes the underlying call to
settle
in thePerpetualAtlanticVault
contract. The interesting part of this method is the part where the WETH is transferred from the LP contract to the core contract, and then the "loss" is accounted in a following call:where
subtractLoss
looks like:Here there is check that the actual WETH balance of the contract is exactly equal to the accounted
_totalCollateral
minus the amount of WETH we have transferred out. However a malicious user can send WETH to the LP contract at any time without_totalCollateral
being incremented, thereby causing the check to fail.This behaviour can be demonstrated with a diff to the existing test suite (execute with
forge test --match-path tests/rdpxV2-core/Unit.t.sol
):Tools Used
Manual review + Foundry
Recommended Mitigation Steps
Since
subtractLoss
in the LP contract can only be called by thePerpetualAtlanticVault.sol
contract the require check should be removed from the method. The precedingsafeTransferFrom
would fail anyway if the required amount of WETH couldn't be pulled from the LP contract.Below is a suggested diff:
Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: