The function borrow
in LendingPool.sol lets user borrow more collateral then there nft value, this happens due to there being a flawed check in the function borrow
itself, resulting in users being able to borrow more than what their nft is worth
The borrow function implements a collateralization check that is wrong, resulting in users being able to borrow more than what their nft should permit.
due to this and the uint256 public constant BASE_LIQUIDATION_THRESHOLD = 80 * 1e2; // 80% in basis points
(initialized to base in the constructor) now the problem leads to this
collateralValue < (userTotalDebt * 0.8), which lets users borrow up to userTotalDebt(as this is the first borrow so debt = the amount they are borrowing)/ 0.8 (or 125% of their collateral) instead of the intended 80%.
Proof of Concept
assume
User deposits NFT worth 100,000 crvUSD
Liquidation threshold is 80%(as initialized in the constructor)
Current implementation allows borrowing up to 125,000 crvUSD
due to https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/LendingPool/LendingPool.sol#L355-L356
this is transferring the exact amount the user wanted to borrow as its assuming the checks it passed is sufficient
Should only allow borrowing up to 80,000 crvUSD
user gains profit of 25,000 crvusd in an instant
user can keep repeating this again and again and gain a lot of profit\
Borrow more than the protocol's intended maximum
Put the protocol at immediate risk of bad debt
Potentially drain the protocol's crvUSD liquidity
manual audit
Reverse the comparison and multiply the collateral value by the liquidation threshold instead
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.