Backed Protocol contest - AuditsAreUS's results

Protocol for peer to peer NFT-Backed Loans.

General Information

Platform: Code4rena

Start Date: 05/04/2022

Pot Size: $30,000 USDC

Total HM: 10

Participants: 47

Period: 3 days

Judge: gzeon

Total Solo HM: 4

Id: 106

League: ETH

Backed Protocol

Findings Distribution

Researcher Performance

Rank: 18/47

Findings: 1

Award: $293.89

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: cmichel

Also found by: AuditsAreUS, IllIllI, Ruhum, csanuragjain, danb, joshie, t11s, tintin

Labels

bug
duplicate
3 (High Risk)

Awards

293.89 USDC - $293.89

External Links

Lines of code

https://github.com/code-423n4/2022-04-backed/blob/e8015d7c4b295af131f017e646ba1b99c8f608f0/contracts/NFTLoanFacilitator.sol#L142-L162

Vulnerability details

Impact

There is on limit on the upper bounds on the amount a lender may send to a borrower. Borrowers will then be forced to pay interest and facilitators fee on the full amount loaned.

The impact for a borrower is that they may be forced to repay significantly more than desired if the lent amount is set to a high value. The borrower also is responsible for the originator fee too which is a percentage of the loan amount.

A borrower is not motivated to repay a loan if the amount is greater than the value of the collateral. Hence the borrow amount is essentially capped at the value of the NFT (excluding risk related to duration of the loan). This may be significantly higher than the borrower has desired, especially if the value of the NFT has increased dramatically.

Proof of Concept

lend() should only that amount >= loan.loanAmount (similarly for buyouts which has amount >= previousAmount), therefore lender may set the amount arbitrarily high and the borrower will be charged both facilitatorTake = amount * originationFeeRate / SCALAR and interest.

        if (loan.lastAccumulatedTimestamp == 0) {
            address loanAssetContractAddress = loan.loanAssetContractAddress;
            require(loanAssetContractAddress != address(0), "NFTLoanFacilitator: invalid loan");

            require(interestRate <= loan.perAnumInterestRate, 'NFTLoanFacilitator: rate too high');
            require(durationSeconds >= loan.durationSeconds, 'NFTLoanFacilitator: duration too low');
            require(amount >= loan.loanAmount, 'NFTLoanFacilitator: amount too low');
        
            loan.perAnumInterestRate = interestRate;
            loan.lastAccumulatedTimestamp = uint40(block.timestamp);
            loan.durationSeconds = durationSeconds;
            loan.loanAmount = amount;

            ERC20(loanAssetContractAddress).safeTransferFrom(msg.sender, address(this), amount);
            uint256 facilitatorTake = amount * originationFeeRate / SCALAR;
            ERC20(loanAssetContractAddress).safeTransfer(
                IERC721(borrowTicketContract).ownerOf(loanId),
                amount - facilitatorTake
            );
            IERC721Mintable(lendTicketContract).mint(sendLendTicketTo, loanId);
        } else {

These costs may be avoided for a borrower by also allowing the borrower to set a maxAmount in createLoan() to which the amount lent cannot exceed this value.

#0 - wilsoncusack

2022-04-07T12:50:01Z

duplicate #30

#1 - gzeoneth

2022-04-15T12:47:51Z

Duplicate #24

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter