Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: low
Invalid

`CapitalPool::approve` Inadequate Handling of Non-Standard ERC20 Approvals

Summary

The approve function in the CapitPool contract fails to account for some tokens (like USDT) that don't conform to the standard return value pattern or require resetting allowance to zero before updating. This oversight can lead to failed approvals for certain tokens. and its doesnt use safeTransfer/safeTransferFrom in the transfer functions

Vulnerability Details

The current implementation assumes all ERC20 tokens behave in a standard way:

function approve(address tokenAddr) external {
address tokenManager = tadleFactory.relatedContracts(
RelatedContractLibraries.TOKEN_MANAGER
);
(bool success, ) = tokenAddr.call(
abi.encodeWithSelector(
APPROVE_SELECTOR,
tokenManager,
type(uint256).max
)
);
if (!success) {
revert ApproveFailed();
}
}


This implementation has two main issues:

It doesn't handle tokens that don't return a boolean value on approval (e.g., USDT).

It doesn't reset the allowance to zero before setting a new value, which some tokens (like USDT) require.

Example Scenario:

  1. A user attempts to call the approve function for a USDT token.

  2. Since USDT does not return a boolean value, the success check might not detect a failed approval.

  3. The approval call might also revert if the current allowance is not set to 0 before being updated.

  4. As a result, the transaction fails, preventing the user from creating pairs with USDT.

Impact

Inability to use popular stablecoins like USDT, limiting the contract's functionality and user base.

Tools Used

Manual code Review


Recommendation

To mitigate this vulnerability, consider implementing the following changes:

  1. Use OpenZeppelin's SafeERC20 library for all ERC20 interactions for approve and transfer /. This library handles non-standard tokens gracefully

    1. import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    function approve(address tokenAddr) external {
    address tokenManager = tadleFactory.relatedContracts(
    RelatedContractLibraries.TOKEN_MANAGER
    );
    IERC20 token = IERC20(tokenAddr);
    SafeERC20.safeApprove(token, tokenManager, 0);
    SafeERC20.safeApprove(token, tokenManager, type(uint256).max);
    }
  2. Implement a token whitelist to ensure only properly vetted tokens can be used with the contract.

Updates

Lead Judging Commences

0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic
Assigned finding tags:

[invalid] finding-CapitalPool-approve-return-boolean

Invalid, low level call will always return true as long as the call succeeds without reverting, so this has no impact described, given approvals can only fail when some weird tokens do not allow a uint256.max approval, which is not described in any of the issues below.

Support

FAQs

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