In PerpetualVault
contract, users can deposit collateral tokens to receive shares and later withdraw their collateral along with profits, minus fees. However, if the runNextFlow
function is called after depositing collateral tokens, the protocol becomes stuck in the FLOW.DEPOSIT
state after swapping tokens, preventing further operations.
requirements: positionIsClosed == false, beenLong == true and leverage is 1x.
User deposits some collateral tokens.
flow is set as FLOW.DEPOSIT
.
as the positionIsClosed is false nextAction.selector
is set to NextActionSelector.INCREASE_ACTION
.
runNextAction
is called by the keeper with metadata of length 1 as the PROTOCOL.DEX
.
if (_nextAction.selector == NextActionSelector.INCREASE_ACTION)
and if (_isLongOneLeverage(_isLong))
conditions are correct.
_runSwap(metadata, true, prices)
function will be called to swap collateral token for index token.
if (metadata.length == 2)
this function is false so the else statement will be called.
if (_protocol == PROTOCOL.DEX)
and if (flow == FLOW.DEPOSIT)
are true so after swapping tokens the _mint()
function is called and the necessary shares are allocated to the depositer.
Then the function returns true.
As seen above, the flow is never deleted, causing the protocol to remain stuck in the FLOW.DEPOSIT
state, which results in a denial of service (DoS) for the entire contract.
Users can inadvertently cause a denial of service (DoS) across the entire protocol, or an attacker can intentionally exploit this issue, preventing other users from depositing or withdrawing collateral tokens.
Add this function to the PerpetualVault.t.sol
and run forge test --mt test_swappingWillBeDoS --via-ir --rpc-url arbitrum -vvv
The function will revert with a FlowInProgress()
error, causing the protocol to become unresponsive and preventing users from interacting with it.
In PerpetualVault::_runSwap
call the _finalize
function to delete the flow, flowState and swapData
Likelihood: Medium/High, - Leverage = 1x - beenLong = True - positionIsClosed = False - Metadata → 1 length and Dex Swap Impact: Medium/High, DoS on any new action before the admin uses setVaultState Since this seems to be the most probable path for a 1x PerpVault, this one deserves a High.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.