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

13 stars 11 forks source link

mgf15 - `executeOperation` will revert if _flashToken is USDT #195

Closed sherlock-admin3 closed 6 months ago

sherlock-admin3 commented 6 months ago

mgf15

medium

executeOperation will revert if _flashToken is USDT

Summary

executeOperation will revert if _flashToken is USDT

Vulnerability Detail

USDT will revert if the current allowance is greater than 0 and an non-zero approval is made. There are multiple instances throughout the contracts where this causes issues.

Impact

revert if asset is USDT due to lack of approve 0.

Code Snippet

function executeOperation(
        address _flashToken,
        uint256 _flashAmount,
        uint256 _flashFees,
        address _initiator,
        bytes calldata _data
    ) external virtual onlyFlashLoanPool returns (bool) {
        require(
            _initiator == address(this),
            "This contract must be the initiator"
        );

        RolloverCallbackArgs memory _rolloverArgs = abi.decode(
            _data,
            (RolloverCallbackArgs)
        );

        uint256 repaymentAmount = _repayLoanFull(
            _rolloverArgs.loanId,
            _flashToken,
            _flashAmount
        );

        AcceptCommitmentArgs memory acceptCommitmentArgs = abi.decode(
            _rolloverArgs.acceptCommitmentArgs,
            (AcceptCommitmentArgs)
        );

        // Accept commitment and receive funds to this contract

        (uint256 newLoanId, uint256 acceptCommitmentAmount) = _acceptCommitment(
            _rolloverArgs.lenderCommitmentForwarder,
            _rolloverArgs.borrower,
            _flashToken,
            acceptCommitmentArgs
        );

        //approve the repayment for the flash loan
        IERC20Upgradeable(_flashToken).approve(
            address(POOL()),
            _flashAmount + _flashFees
        );

        uint256 fundsRemaining = acceptCommitmentAmount +
            _rolloverArgs.borrowerAmount -
            repaymentAmount -
            _flashFees;

        if (fundsRemaining > 0) {
            IERC20Upgradeable(_flashToken).transfer(
                _rolloverArgs.borrower,
                fundsRemaining
            );
        }

        emit RolloverLoanComplete(
            _rolloverArgs.borrower,
            _rolloverArgs.loanId,
            newLoanId,
            fundsRemaining
        );

        return true;
    }

https://github.com/sherlock-audit/2024-04-teller-finance/blob/defe55469a2576735af67483acf31d623e13592d/teller-protocol-v2-audit-2024/packages/contracts/contracts/LenderCommitmentForwarder/extensions/FlashRolloverLoan_G5.sol#L156C5-L219C6

Tool used

Manual Review

Recommendation

Utilize the OZ safeERC20

Duplicate of #140