DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Users have no way to withdraw their funds from the treasury after a failed withdrawal

Summary

The withdrawal flow requires the PerpetualVault::_transferToken function to successfully transfer the required tokens to the user. The transfer is executed inside a try-catch block, and on a failed transfer, the funds are sent to the PerpetualVault::treasury address. At this point, there is no way for the user to try to recover these funds.

Vulnerability Details

PerpetualVault::_transferToken contains the following code:

try collateralToken.transfer(depositInfo[depositId].recipient, amount - fee) {}
catch {
collateralToken.transfer(treasury, amount - fee);
emit TokenTranferFailed(depositInfo[depositId].recipient, amount - fee);
}

This function is executed in PerpetualVault::_handleReturn calls which happen at the end of the withdrawal flow as long as the withdrawal amount is non-zero. The recipient address and the relevant deposit ID have been through multiple checks for their validation. If the try block still fails, the funds are transferred to the treasury address, which the user has no way of interacting with. Thus, the user cannot attempt to withdraw their funds again.

Impact

Managing user funds is not the responsibility of the treasury, so at a minimum this is a centralization risk. Responding to a failed withdrawal would require trying to push the funds into the recipient's account, which is not recommended. At worst, this could lead to loss of user funds.

Recommendations

Create a function to respond to the event emitted in the catch block. This can be done in the treasury, if there is no logic relying on balance(this) or balanceOf(this) for handling accounting. Depending on the frequency of the issue, it may make sense to have a secondary address for this. Maintain a mapping of user => amount with the fixed amount calculated during the withdrawal flow. Create PerpetualVault::tryWithdrawalAgain so that users can retry withdrawing their funds without affecting internal accounting in PerpetualVault.

Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Suppositions

There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.

Users mistake, only impacting themselves.

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Suppositions

There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.

Users mistake, only impacting themselves.

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!