The _transferToken function in the PerpetualVault contract fails to check the return value of the ERC20 transfer function when sending tokens to the recipient. This could result in silent transfer failures, where tokens are not successfully transferred but the contract proceeds as if they were.
Function: _transferToken(uint256, uint256)
Lines:
Ignored Return Value:
The transfer function for ERC20 tokens returns a boolean indicating success (true) or failure (false).
The _transferToken function does not check this return value, assuming the transfer always succeeds or it just reverts.
Ineffective try/catch:
Solidity’s try/catch only catches reverts, not false return values. If the token’s transfer function does not revert on failure (e.g., pre-OpenZeppelin 0.8.0), failed transfers will go undetected.
Fund Loss: If the transfer to the recipient fails (e.g., due to insufficient balance or a paused token contract), the contract proceeds as if the transfer succeeded.
Inconsistent State: The totalDepositAmount is decremented, and shares are burned, even if tokens were not actually transferred.
Token Configuration:
The collateralToken is a legacy ERC20 token that returns false (instead of reverting) on failed transfers.
Failed Transfer:
A user attempts to withdraw, but the recipient address has disabled receiving tokens (e.g., blacklisted).
collateralToken.transfer(...) returns false, but the try/catch does not trigger.
State Corruption:
The vault burns the user’s shares and reduces totalDepositAmount, but the tokens remain stuck in the contract.
safeTransfer for ERC20 TransfersReplace transfer with OpenZeppelin’s safeTransfer, which reverts on failure:
try/catchIf safeTransfer is used, the try/catch becomes unnecessary (as failures will revert):
If non-reverting tokens must be supported, explicitly check the return value:
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.
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.
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.