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

6 stars 6 forks source link

samuraii77 - Lender might not be able to set a repayment listener #294

Closed sherlock-admin3 closed 2 months ago

sherlock-admin3 commented 2 months ago

samuraii77

medium

Lender might not be able to set a repayment listener

Summary

Lender might not be able to set a repayment listener because of a state change upon a lender claiming a loan NFT.

Vulnerability Detail

Lenders can call the claimLoanNFT() function in order to mint a loan NFT.

    function claimLoanNFT(uint256 _bidId)
        external
        acceptedLoan(_bidId, "claimLoanNFT")
        whenNotPaused
    {
        // Retrieve bid
        Bid storage bid = bids[_bidId];

        address sender = _msgSenderForMarket(bid.marketplaceId);
        require(sender == bid.lender, "only lender can claim NFT");

        // set lender address to the lender manager so we know to check the owner of the NFT for the true lender
        bid.lender = address(USING_LENDER_MANAGER);

        // mint an NFT with the lender manager
        lenderManager.registerLoan(_bidId, sender);
    }

This changes the bid.lender variable to the USING_LENDER_MANAGER address. The comment above the state change states that they should check the owner of the NFT for the actual lender. That is the reason they have a special getter function getLoanLender():

 function getLoanLender(uint256 _bidId)
        public
        view
        returns (address lender_)
    {
        lender_ = bids[_bidId].lender;

        if (lender_ == address(USING_LENDER_MANAGER)) {
            return lenderManager.ownerOf(_bidId);
        }

        //this is left in for backwards compatibility only
        if (lender_ == address(lenderManager)) {
            return lenderManager.ownerOf(_bidId);
        }
    }

The issue is that this function is not used when a lender tries to set a repayment listener for his bid:

function setRepaymentListenerForBid(uint256 _bidId, address _listener)
        external
    {
        address sender = _msgSenderForMarket(bids[_bidId].marketplaceId);

        require(
            sender == bids[_bidId].lender,
            "Only bid lender may set repayment listener"
        );

        repaymentListenerForBid[_bidId] = _listener;
    }

It compares the sender to the lender of the bid which was changed upon claiming of the loanNFT.

Impact

Lender might not be able to set a repayment listener

Code Snippet

https://github.com/sherlock-audit/2024-04-teller-finance/blob/defe55469a2576735af67483acf31d623e13592d/teller-protocol-v2-audit-2024/packages/contracts/contracts/TellerV2.sol#L578-L594 https://github.com/sherlock-audit/2024-04-teller-finance/blob/defe55469a2576735af67483acf31d623e13592d/teller-protocol-v2-audit-2024/packages/contracts/contracts/TellerV2.sol#L1248-L1259

Tool used

Manual Review

Recommendation

Use getLoanLender() instead.

Duplicate of #11