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
Rank: 28/47
Findings: 2
Award: $100.41
π Selected for report: 0
π Solo Findings: 0
π Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0xDjango, 0xkatana, BouSalman, CertoraInc, Dravee, FSchmoede, Hawkeye, Kenshin, Meta0xNull, PPrieditis, Ruhum, TerrierLover, VAD37, WatchPug, berndartmueller, csanuragjain, hake, horsefacts, hubble, m9800, rayn, reassor, robee, samruna, securerodd, shenwilly, sorrynotsorry, t11s, teryanarmen, tintin, z3s
67.476 USDC - $67.48
April 05, 2022
@securerodd
Contract: NFTLoanFacilitator.sol
The first time a loan is granted in the
lend(uint256 loanId, uint16 interestRate, uint128 amount, uint32 durationSeconds, address sendLendTicketTo)
function, the loanβs duration is set to the passed in argument of durationSeconds
. In order for another lender to take over this loan, they must offer a better loan (i.e. longer duration, better interest rate, or greater amount). Due to this check: require(durationSeconds >= previousDurationSeconds, 'NFTLoanFacilitator: duration too low');
, all loans must be offered for at least as long as the loan before it.
Scenario:
1. Alice creates a loan for 1000 UNI using her Milady as collateral 2. Bob lends to Alice by meeting her minimum duration, amount, and interest rate requirements 3. David comes by and replaces Bob's loan by matching the amount and interest rate, but sets the duration to 100 years 4. Anybody else who wants to lend to Alice would have to offer a duration of at least 100 years even if they have a much better rate and amount
Recommendation: Consider allowing a lender to meet the minimum duration if the interest rate and amount are more favorable.
There were locations in the NFTLoanFacilitator.sol
contract where the mint call was used instead of safeMint. safeMint performs a mint with an additional check that the receiver implements the onERC721Received() function. In both of these cases, the receiving address was a passed in parameter and as a result, it would be possible for a user to accidentally mint to a contract address that would lock the borrow or lend ticket NFT.
Locations:
createLoan(uint256 collateralTokenId, address collateralContractAddress, uint16 maxPerAnumInterest, uint128 minLoanAmount, address loanAssetContractAddress, uint32 minDurationSeconds, address mintBorrowTicketTo) -> L102: IERC721Mintable(borrowTicketContract).mint(mintBorrowTicketTo, id); lend(uint256 loanId, uint16 interestRate, uint128 amount, uint32 durationSeconds, address sendLendTicketTo) -> L161: IERC721Mintable(lendTicketContract).mint(sendLendTicketTo, loanId);
Recommendation: Use the safeMint call instead of mint.
There was a location in the NFTLoanFacilitator.sol
contract where the transferFrom call was used instead of safeTransferFrom. safeTransferFrom performs a transferFrom with an additional check that the receiver implements the onERC721Received() function. In this case, the receiving address was a passed in parameter and as a result, it would be possible for a user to accidentally transfer to a contract address that would lock the NFT that was being held as collateral.
Locations:
closeLoan(uint256 loanId, address sendCollateralTo) -> L124: IERC721(loan.collateralContractAddress).transferFrom(address(this), sendCollateralTo, loan.collateralTokenId);
Recommendation: Use the safeTransferFrom call instead of transferFrom.
π Selected for report: Dravee
Also found by: 0v3rf10w, 0x1f8b, 0xkatana, CertoraInc, FSchmoede, Funen, IllIllI, Kenshin, Meta0xNull, TerrierLover, Tomio, csanuragjain, joshie, obront, rayn, rfa, robee, saian, securerodd, sorrynotsorry, t11s, z3s
32.9299 USDC - $32.93
April 06, 2022
@securerodd
Contract: NFTLoanFacilitator.sol
Function: updateRequiredImprovementRate(uint256 _improvementRate)
Code: require(_improvementRate > 0, 'NFTLoanFacilitator: 0 improvement rate');
Gas: testUpdateRequiredImprovementRateRevertsIf0() (gas: 13310)
Recommended Code: require(_improvementRate != 0, 'NFTLoanFacilitator: 0 improvement rate');
Gas: testUpdateRequiredImprovementRateRevertsIf0() (gas: 13304)
#0 - wilsoncusack
2022-04-07T02:27:35Z
Duplicate to a few others. Will probably do this