The CapitalPool contract has a critical issue concerning its handling of ERC20 tokens that revert on large approvals and transfers. Some ERC20 tokens, such as UNI and COMP, revert when the value passed to approve or transfer exceeds uint96. The CapitalPool contract uses type(uint256).max for approvals, which can lead to unexpected behavior with these tokens.
The CapitalPool#approve() function is designed to grant approval to the TokenManager contract for token transfers. It uses type(uint256).max as the approval amount:
However some ERC20 tokens, such as UNI and COMP, have special logic that handles large approval values. For these tokens, using type(uint256).max could lead to issues.
The issue causes the CapitalPool contract to potentially malfunction with ERC20 tokens that revert on large approval values. This could lead to failures in granting approvals, causing withdrawal and transfer operations to fail.
Rather than using type(uint256).max, allow specifying a uint96 amount parameter in the approve function. This change ensures compatibility with tokens that have limitations on approval amounts.
Thanks for flagging, indeed since uint(-1) is representative of max uint256 value, when entering the `if` statement, it will be converted to uint96 max amout, so it will not revert as described. In issue #361, the mockToken utilized does not correctly reflect the below approval behavior. ```Solidity function approve(address spender, uint rawAmount) external returns (bool) { uint96 amount; if (rawAmount == uint(-1)) { amount = uint96(-1); } else { amount = safe96(rawAmount, "Comp::approve: amount exceeds 96 bits"); } ```
Thanks for flagging, indeed since uint(-1) is representative of max uint256 value, when entering the `if` statement, it will be converted to uint96 max amout, so it will not revert as described. In issue #361, the mockToken utilized does not correctly reflect the below approval behavior. ```Solidity function approve(address spender, uint rawAmount) external returns (bool) { uint96 amount; if (rawAmount == uint(-1)) { amount = uint96(-1); } else { amount = safe96(rawAmount, "Comp::approve: amount exceeds 96 bits"); } ```
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.