code-423n4 / 2024-04-gondi-findings

0 stars 0 forks source link

settleWithBuyout() cannot pay triggerFee #30

Closed c4-bot-10 closed 7 months ago

c4-bot-10 commented 7 months ago

Lines of code

https://github.com/code-423n4/2024-04-gondi/blob/b9863d73c08fcdd2337dc80a8b5e0917e18b036c/src/lib/AuctionWithBuyoutLoanLiquidator.sol#L97

Vulnerability details

Vulnerability details

in settleWithBuyout use safeTransfer() to pay triggerFee

    function settleWithBuyout(
        address _nftAddress,
        uint256 _tokenId,
        Auction calldata _auction,
        IMultiSourceLoan.Loan calldata _loan
    ) external nonReentrant {
        /// TODO: Originator fee
        _checkAuction(_nftAddress, _tokenId, _auction);
        uint256 timeLimit = _auction.startTime + _timeForMainLenderToBuy;
        if (timeLimit < block.timestamp) {
            revert OptionToBuyExpiredError(timeLimit);
        }
        uint256 largestTrancheIdx;
        uint256 largestPrincipal;
        for (uint256 i = 0; i < _loan.tranche.length;) {
            if (_loan.tranche[i].principalAmount > largestPrincipal) {
                largestPrincipal = _loan.tranche[i].principalAmount;
                largestTrancheIdx = i;
            }
            unchecked {
                ++i;
            }
        }
        if (msg.sender != _loan.tranche[largestTrancheIdx].lender) {
            revert NotMainLenderError();
        }
        ERC20 asset = ERC20(_auction.asset); 
        uint256 totalOwed;
        for (uint256 i; i < _loan.tranche.length;) {
            if (i != largestTrancheIdx) {
                IMultiSourceLoan.Tranche calldata thisTranche = _loan.tranche[i];
                uint256 owed = thisTranche.principalAmount + thisTranche.accruedInterest
                    + thisTranche.principalAmount.getInterest(thisTranche.aprBps, block.timestamp - thisTranche.startTime);
                totalOwed += owed; 
                asset.safeTransferFrom(msg.sender, thisTranche.lender, owed);
            }
            unchecked {
                ++i;
            }
        }
        IMultiSourceLoan(_auction.loanAddress).loanLiquidated(_auction.loanId, _loan);

@>      asset.safeTransfer(_auction.originator, totalOwed.mulDivDown(_auction.triggerFee, _BPS));

        ERC721(_loan.nftCollateralAddress).transferFrom(address(this), msg.sender, _tokenId);

        delete _auctions[_nftAddress][_tokenId];

        emit AuctionSettledWithBuyout(_auction.loanAddress, _auction.loanId, _nftAddress, _tokenId, largestTrancheIdx);
    }

Unlike settleAuction() the funds are not in the contract and transfer() won't work.

Correct should be: asset.safeTransferFrom(msg.sender, _auction.originator, totalOwed.mulDivDown(_auction.triggerFee, _BPS));

Impact

cannot pay triggerFee

Recommended Mitigation

    function settleWithBuyout(
        address _nftAddress,
        uint256 _tokenId,
        Auction calldata _auction,
        IMultiSourceLoan.Loan calldata _loan
    ) external nonReentrant {
...
-       asset.safeTransfer(_auction.originator, totalOwed.mulDivDown(_auction.triggerFee, _BPS));
+       asset.safeTransferFrom(msg.sender, _auction.originator, totalOwed.mulDivDown(_auction.triggerFee, _BPS));`

        ERC721(_loan.nftCollateralAddress).transferFrom(address(this), msg.sender, _tokenId);

        delete _auctions[_nftAddress][_tokenId];

        emit AuctionSettledWithBuyout(_auction.loanAddress, _auction.loanId, _nftAddress, _tokenId, largestTrancheIdx);
    }

Assessed type

Context

c4-judge commented 7 months ago

0xA5DF marked the issue as duplicate of #50

c4-judge commented 7 months ago

0xA5DF marked the issue as satisfactory

c4-judge commented 7 months ago

0xA5DF changed the severity to 3 (High Risk)