Platform: Code4rena
Start Date: 27/04/2022
Pot Size: $50,000 MIM
Total HM: 6
Participants: 59
Period: 5 days
Judge: 0xean
Id: 113
League: ETH
Rank: 11/59
Findings: 3
Award: $1,265.22
🌟 Selected for report: 1
🚀 Solo Findings: 0
533.6961 MIM - $533.70
function get(address pair, uint256 tokenId) external returns (bool success, uint256 rate);
The get function of the INFTOracle interface returns two values, but the success value is not checked when used in the NFTPairWithOracle contract. When success is false, NFTOracle may return stale data.
https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/interfaces/INFTOracle.sol#L10-L10 https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPairWithOracle.sol#L287-L287 https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPairWithOracle.sol#L321-L321
None
(bool success, uint256 rate) = loanParams.oracle.get(address(this), tokenId); require(success);
#0 - cryptolyndon
2022-05-03T05:44:06Z
Agreed, and the first report of this issue.
#1 - 0xean
2022-05-20T22:47:41Z
I am upgrading this to High severity.
This is a direct path to assets being lost.
3 — High: Assets can be stolen/lost/compromised directly (or indirectly if there is a valid attack path that does not have hand-wavy hypotheticals).
🌟 Selected for report: 0x1337
Also found by: BowTiedWardens, GimelSec, catchup, cccz, gzeon, horsefacts, hyh, kenzo
In the updateLoanParams function of the NFTPairWithOracle contract, the lender can update the address of the oracle. A malicious lender can call the updateLoanParams function to update the oracle address to a malicious oracle. Then liquidate early by manipulating the return value of the oracle.
https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPairWithOracle.sol#L198-L223 https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPairWithOracle.sol#L267-L297
None
Add oracle address check in updateLoanParams()
function updateLoanParams(uint256 tokenId, TokenLoanParams memory params) public { TokenLoan memory loan = tokenLoan[tokenId]; if (loan.status == LOAN_OUTSTANDING) { // The lender can change terms so long as the changes are strictly // the same or better for the borrower: require(msg.sender == loan.lender, "NFTPair: not the lender"); TokenLoanParams memory cur = tokenLoanParams[tokenId]; require( params.duration >= cur.duration && params.valuation <= cur.valuation && params.annualInterestBPS <= cur.annualInterestBPS && params.ltvBPS <= cur.ltvBPS && + params.oracle == cur.oracle, "NFTPair: worse params" );
#0 - cryptolyndon
2022-05-05T04:41:15Z
Duplicate of #37, but confirmed
🌟 Selected for report: IllIllI
Also found by: 0x1337, 0x1f8b, 0xDjango, 0xf15ers, AuditsAreUS, BowTiedWardens, CertoraInc, Funen, GimelSec, MaratCerby, Ruhum, WatchPug, antonttc, berndartmueller, bobi, bobirichman, broccolirob, catchup, cccz, defsec, delfin454000, gs8nrv, gzeon, horsefacts, hubble, hyh, ilan, jah, joestakey, kebabsec, kenta, kenzo, m9800, mics, oyc_109, pauliax, reassor, robee, samruna, sikorico, simon135, throttle, unforgiven, z3s
72.6404 MIM - $72.64
The to/loan.borrower will receive the collateral NFT when removeCollateral()/repay() is called. However, if to/loan.borrower is a contract address that does not support ERC721, the collateral NFT can be frozen in the contract.
As per the documentation of EIP-721:
A wallet/broker/auction application MUST implement the wallet interface if it will accept safe transfers.
Ref: https://eips.ethereum.org/EIPS/eip-721
https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPair.sol#L266-L266 https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPair.sol#L540-L540 https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPairWithOracle.sol#L295-L295 https://github.com/code-423n4/2022-04-abranft/blob/5cd4edc3298c05748e952f8a8c93e42f930a78c2/contracts/NFTPairWithOracle.sol#L573-L573
None
Use safeTransferFrom instead of transferFrom
#0 - cryptolyndon
2022-05-03T05:40:27Z
Not an issue. safeTransferFrom
protects against some, but not all, avenues of losing tokens by misuse. The price for this is that an external call can get made, incurring a gas cost and introducing a potential reentrancy attack vector. With all this in mind, we have intentionally elected not to use it.
#1 - 0xean
2022-05-21T00:38:07Z
downgrading to QA, this is a design decision / low severity as the lender and borrower should understand how this contract will interact with theirs.
#2 - JeeberC4
2022-05-23T19:07:31Z
Preserving original title: to/loan.borrower is unchecked in removeCollateral()/repay(), which can cause user's collateral NFT to be frozen