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

10 stars 9 forks source link

merlin - DOS vulnerability in the rolloverLoanWithFlash function in FlashRolloverLoan_G5.sol #210

Closed sherlock-admin3 closed 4 months ago

sherlock-admin3 commented 4 months ago

merlin

medium

DOS vulnerability in the rolloverLoanWithFlash function in FlashRolloverLoan_G5.sol

Summary

https://github.com/d-xo/weird-erc20#approval-race-protections Some tokens (e.g. KNC) do not allow approving an amount M > 0 when an existing amount N > 0 is already approved. Note: The KNC token returns true for the transfer and transferFrom functions. Comment from the previous Teller audit: https://github.com/sherlock-audit/2023-03-teller-judging/issues/423#issuecomment-1535401214

Vulnerability Detail

During the rolloverLoanWithFlash function call, the borrower repays the previous loan using borrowed principal tokens with an Aave simple flash loan. Here is how the _repayLoanFull function looks:

function _repayLoanFull(
        uint256 _bidId,
        address _principalToken,
        uint256 _repayAmount
    ) internal returns (uint256 repayAmount_) {
        uint256 fundsBeforeRepayment = IERC20Upgradeable(_principalToken)
            .balanceOf(address(this));

-->     IERC20Upgradeable(_principalToken).approve(
            address(TELLER_V2),
            _repayAmount
        );
        TELLER_V2.repayLoanFull(_bidId);

        uint256 fundsAfterRepayment = IERC20Upgradeable(_principalToken)
            .balanceOf(address(this));

        repayAmount_ = fundsBeforeRepayment - fundsAfterRepayment;
    }

A malicious borrower can cause a Denial of Service (DOS) attack on all future rolloverLoanWithFlash executions with the KNS token as the principal token for other borrowers. This can be achieved by borrowing from an Aave flash loan with an amount of owedPrincipal + interest + 1 wei KNS of borrower's bid. After a successful execution, the borrower leaves an allowance of 1 wei, creating a DOS situation.

// _repayAmount = owedPrincipal + interest + 1
 IERC20Upgradeable(_principalToken).approve(
            address(TELLER_V2),
            _repayAmount
        );
TELLER_V2.repayLoanFull(_bidId);      
// After repayLoanFull, 1 wei of allowance remains.

Impact

A malicious borrower can cause a Denial of Service (DOS) attack on all future rolloverLoanWithFlash executions for non-zero approve tokens.

Code Snippet

contracts/contracts/LenderCommitmentForwarder/extensions/FlashRolloverLoan_G5.sol#L243-L246

Tool used

Manual Review

Recommendation

It is necessary to call ITellerV2(TELLER_V2).calculateAmountOwed(_bidId, block.timestamp) to calculate the total amount owed for a loan bid at a specific timestamp and approve it.

Duplicate of #140