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

13 stars 11 forks source link

Bauchibred - Return values of transfers/approvals are not checked `LenderCommitmentGroup_Smart.sol` #194

Closed sherlock-admin2 closed 6 months ago

sherlock-admin2 commented 6 months ago

Bauchibred

high

Return values of transfers/approvals are not checked LenderCommitmentGroup_Smart.sol

Summary

In various functions such as burnSharesToWithdrawEarnings, addPrincipalToCommitmentGroup, and liquidateDefaultedLoanWithIncentive, silent transfer failures may occur, resulting in different scenarios: potential loss of user funds, loss of protocol funds, and flawed variable values, ultimately affecting collateral distribution.

A silent failure could also occur in acceptFundsForAcceptBid() for the approval

Vulnerability Detail

First note that this has been stated in the readme: https://github.com/sherlock-audit/2024-04-teller-finance/blob/defe55469a2576735af67483acf31d623e13592d/README.md#L12-L16

---
### Q: If you are integrating tokens, are you allowing only whitelisted tokens to work with the codebase or any complying with the standard? Are they assumed to have certain properties, e.g. be non-reentrant? Are there any types of <a href="https://github.com/d-xo/weird-erc20" target="_blank" rel="noopener noreferrer">weird tokens</a> you want to integrate?

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 .
---

Now in multiple instance in scope, the integrated ERC20 token is attempted to be approved/transferred/transferFrommed, however all instances of this in the LenderCommitmentGroup_Smart.sol contract calls the un-safe approve/transfer/transferFrom() defined in openzeppelin's ERC20 and the does not check the bool.

Now going to openzeppelin's ERC20's approvetransfer/transferFrom() implementation we can see them specified like this https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol#L41-L78 with the bool value to be returned.

    function transfer(address to, uint256 value) external returns (bool);
    (...snip)
    function approve(address spender, uint256 value) external returns (bool);
    (...snip)
    function transferFrom(address from, address to, uint256 value) external returns (bool);

This is done cause most standard ERC20 tokens do not revert on failures but rather return a bool.

Now in the current scope in the LenderCommitmentGroup_Smart.sol these unsafe methods of transfers are used in liquidateDefaultedLoanWithIncentive, burnSharesToWithdrawEarnings & addPrincipalToCommitmentGroup.

Since these attempts to transfer could silently fail, this then leads to multiple scenarios like:

Impact

As stated under ## Vulnerability Detail, current implementations in burnSharesToWithdrawEarnings, addPrincipalToCommitmentGroup, & liquidateDefaultedLoanWithIncentive are flawed, since silent transfer failures may occur, resulting in different scenarios: potential loss of user funds, loss of protocol funds, and flawed variable values, ultimately affecting collateral distribution.

As for the case of the approval's return value not being checked in acceptFundsForAcceptBid, this might break the implementation of the call to TellerV2.sol as they include some transfer logics that would need the approvals to succeed

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#L307-L322

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#L395C1-L416C1

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#L441C2-L468C10

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#L373

And all other instances of unsafe approve/transfer/transferFrom whose return values are not checked.

Tool used

Manual Review

Recommendation

Consider checking the return values and ensuring that these transfers/approvals were successful and revert when they are not successful.

Alternatively, just use openzeppelin's SafeERC20 instead just as is done in TellerV2.sol https://github.com/sherlock-audit/2024-04-teller-finance/blob/defe55469a2576735af67483acf31d623e13592d/teller-protocol-v2-audit-2024/packages/contracts/contracts/TellerV2.sol#L58

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
//(...snip)
    using SafeERC20 for IERC20;

Duplicate of #50