Description:
The emergencyWithdrawERC20
function in the OrderBook
contract currently lacks a check to verify that the contract holds a sufficient balance of the specified ERC20 token before attempting to process a withdrawal. As a result, if the contract owner tries to withdraw more tokens than are actually available in the contract, the function will proceed until it reaches the token.safeTransfer(_to, _amount);
statement, at which point the transaction will revert due to insufficient balance. This revert occurs only after the function has already performed other checks and computations, leading to unnecessary gas consumption and a less user-friendly experience.
Additionally, the absence of a pre-transfer balance check can make it harder for users and integrators to quickly diagnose why a withdrawal transaction failed, as the revert will be triggered deep within the ERC20 transfer logic rather than by a clear, descriptive error at the start of the function.
Impact:
Failing to check the contract's token balance before attempting a withdrawal can result in wasted gas for the contract owner, who may repeatedly attempt to withdraw an unavailable amount without understanding the cause of the failure. Each failed attempt incurs gas costs, and the error message may not be immediately clear, especially if the underlying ERC20 implementation does not provide detailed revert reasons. This inefficiency can be particularly frustrating in emergency situations where quick and predictable access to funds is critical. Moreover, the lack of an explicit check reduces the overall robustness and clarity of the contract's code.
Proof of Concept:
Suppose the contract holds 100 tokens of a particular ERC20 token.
The owner initiates a call to emergencyWithdrawERC20
with _amount = 200
.
The function performs its initial checks (such as verifying the token is not a core protocol token and that the recipient address is valid), but does not check the contract's token balance.
The function then calls token.safeTransfer(_to, _amount);
, which reverts because the contract does not have enough tokens to fulfill the transfer.
The owner pays gas for the failed transaction, and the revert message may not clearly indicate that the failure was due to insufficient contract balance.
Recommended Mitigation:
To address this issue, add an explicit check at the beginning of the emergencyWithdrawERC20
function to ensure that the contract's balance of the specified token is at least equal to the requested withdrawal amount. If the balance is insufficient, the function should revert immediately with a clear and descriptive error message, saving gas and improving the user experience. For example:
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.