Tadle

Tadle
DeFi
30,000 USDC
View results
Submission Details
Severity: low
Invalid

Weird ERC20 issues

Summary

Tadle has its own tokens transferring library which is prone to a lot of token-related issues.

Vulnerability Details

Rescuable.sol even tho it's not in scope but it's used in every core contract.

  1. _safe_transfer & _safe_transfer_from expect boolean values when transferring tokens but they don't check the values ZRX, and EURS are some examples, they return a false boolean when the txn fails.

  2. CapitalPool.sol#approve uses type(uint256.max) in encoding, tokens like cUSDC contain a special case for amount == type(uint256).max in their transfer functions that results in only the user's balance being transferred.

  3. If the amt is more than uin96 in case of UNI approval txn gets reverted tho in the case of COMP both txn and approval-txns get reverted.

  4. Some tokens (e.g. KNC) do not allow approving an amount M > 0 when an existing amount N > 0 is already approved.

Impact

In most cases, txn gets reverted but in some cases like the (zrx &EURS one) txn might fail but user will still get amount in internal accounting showcased on the tillIn function

Tools Used

Manual review

Recommendations

Follow these two guides for proper integration of erc20-compliant tokens: 1 & 2

Updates

Lead Judging Commences

0xnevi Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

[invalid] finding-CapitalPool-approve-uint256-max

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"); } ```

Appeal created

0xnevi Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[invalid] finding-CapitalPool-approve-uint256-max

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"); } ```

Support

FAQs

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