sherlock-audit / 2024-04-teller-finance-judging

10 stars 9 forks source link

KupiaSec - The `LenderCommitmentGroup_Smart` contract cannot use USDT as its principal token, because `USDT.transfer()` does not return a boolean value. #239

Closed sherlock-admin2 closed 3 months ago

sherlock-admin2 commented 4 months ago

KupiaSec

medium

The LenderCommitmentGroup_Smart contract cannot use USDT as its principal token, because USDT.transfer() does not return a boolean value.

Summary

The transferFrom(), transfer(), and approve() functions from the IERC20 standard return a boolean value, but the ones of USDT does not. This makes it impossible for USDT to be used as the principal token of the LenderCommitmentGroup_Smart contract.

Vulnerability Detail

The document of this protocol said, "We are allowing any standard token that would be compatible with Uniswap V3 to work with our codebase, just as was the case for the original audit of TellerV2.sol . The tokens are assumed to be able to work with Uniswap V3."

USDT is one of the most widely-used tokens on the Uniswap V3 decentralized exchange.

And, the USDT.transfer() function does not return a boolean value, which is different from other tokens that inherit the IERC20 standard.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol


    interface IERC20 {
        // ...
        function transfer(address to, uint256 value) external returns (bool);

        function approve(address spender, uint256 value) external returns (bool);

        function transferFrom(address from, address to, uint256 value) external returns (bool);
        // ...
    }

In the LenderCommitmentGroup_Smart.sol, however, the use of transferFrom(), transfer(), and approve() functions from the IERC20 standard makes it impossible for USDT to be used as the principal token, because any call to these functions would revert.

https://github.com/sherlock-audit/2024-04-teller-finance/blob/main/teller-protocol-v2-audit-2024/packages/contracts/contracts/LenderCommitmentForwarder/extensions/LenderCommitmentGroup/LenderCommitmentGroup_Smart.sol


contract LenderCommitmentGroup_Smart is
    // ...
85      IERC20 public principalToken;
    // ...
313     principalToken.transferFrom(msg.sender, address(this), _amount);
    // ...
373     principalToken.transfer(_recipient, principalTokenValueToWithdraw);
    // ...
412     principalToken.approve(address(TELLER_V2), _principalAmount);
    // ...

Impact

The LenderCommitmentGroup_Smart contract cannot use USDT as its principal token.

Code Snippet

https://github.com/sherlock-audit/2024-04-teller-finance/blob/defe55469a2576735af67483acf31d623e13592d/teller-protocol-v2-audit-2024/packages/contracts/contracts/LenderCommitmentForwarder/extensions/LenderCommitmentGroup/LenderCommitmentGroup_Smart.sol#L412

Tool used

Manual Review

Recommendation

SafeERC20 library should used for IERC20.

Duplicate of #50

sherlock-admin2 commented 4 months ago

The protocol team fixed this issue in the following PRs/commits: https://github.com/teller-protocol/teller-protocol-v2-audit-2024/pull/30

nevillehuang commented 3 months ago

Highlights only transfer/transferFrom boolean reverts

Highlights only approval boolean reverts

Highlights both transfer/transferfrom and approval boolean reverts

Highlights only unchecked boolean return values for certain tokens (e.g. ZRX, BNB)

Highlights both transfer/transferfrom reverts and unchecked boolean return values

There are 2 impacts, although same fix is employed. Likely duplicates given same root cause of not using safe ERC20 transfers/approve

[High] finding-token-unchecked-return-value

[Medium] finding-token-revert-boolean

nevillehuang commented 3 months ago

After discussions with @cvetanovv, planning to duplicate duplicates of #239 and #50 given same root cause of not using safe ERC20 transfers/approve. Given issue #239 has shown a potential high impact, all of its duplicates will be high severity as well based on sherlock duplications rules

Scenario A: There is a root cause/error/vulnerability A in the code. This vulnerability A -> leads to two attack paths:

  • B -> high severity path
  • C -> medium severity attack path/just identifying the vulnerability. Both B & C would not have been possible if error A did not exist in the first place. In this case, both B & C should be put together as duplicates.
sherlock-admin2 commented 2 months ago

The Lead Senior Watson signed off on the fix.