1. i deposit 100e18 crvUSD
2. smone deposit nft worth of 120e18
3. Funds is transferred to him
4. Lender want to withdraw but can't do it
pragma solidity ^0.8.19;
import {Test, console} from "lib/forge-std/src/Test.sol";
import "contracts/core/pools/LendingPool/LendingPool.sol";
import "contracts/core/tokens/RToken.sol";
import "contracts/core/tokens/DebtToken.sol";
import "contracts/core/tokens/RAACNFT.sol";
import "contracts/core/tokens/RAACToken.sol";
import "contracts/core/minters/RAACMinter/RAACMinter.sol";
import "contracts/core/pools/StabilityPool/StabilityPool.sol";
import "contracts/core/tokens/DEToken.sol";
interface ITokenERC20{
function approve(address spender, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
contract ArsenTest is Test{
RToken public rToken;
DebtToken public dToken;
RAACNFT public raacNFT;
RAACToken public raacToken;
DEToken public deToken;
RAACMinter public raacMinter;
HousePrices public housePrices;
PriceOracle public priceOracle;
LendingPool public lendingPool;
StabilityPool public stabilityPool;
address public attacker = address(8888);
address public user_1 = address(1111);
address public user_2 = address(2222);
address CRV_USD = address(0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E);
string ETH_RPC_URL = "https://mainnet.infura.io/v3/2cef90f9f3f44a1fb5201d8547183d42";
function setUp() public{
uint256 ethFork = vm.createFork(ETH_RPC_URL);
vm.selectFork(ethFork);
housePrices = new HousePrices();
priceOracle = new PriceOracle();
rToken = new RToken(
"rToken",
"RTOKEN",
address(this),
CRV_USD
);
dToken = new DebtToken(
"Debt Token",
"DBTTOKEN",
address(this)
);
raacNFT = new RAACNFT(
CRV_USD,
address(housePrices),
address(this)
);
raacToken = new RAACToken(
address(this),
500,
500
);
deToken = new DEToken(
"DeToken",
"deToken",
address(this),
address(rToken)
);
lendingPool = new LendingPool(
CRV_USD,
address(rToken),
address(dToken),
address(raacNFT),
address(priceOracle),
100000000000000000000000000
);
stabilityPool = new StabilityPool(address(this));
raacMinter = new RAACMinter(
address(raacToken),
address(stabilityPool),
address(lendingPool),
address(this)
);
stabilityPool.initialize(
address(rToken),
address(deToken),
address(raacToken),
address(raacMinter),
CRV_USD,
address(lendingPool)
);
rToken.setReservePool(address(lendingPool));
dToken.setReservePool(address(lendingPool));
}
function test_deposit() public{
deal(CRV_USD, attacker, 1_000e18);
vm.startPrank(attacker);
ITokenERC20(CRV_USD).approve(address(lendingPool), 1_000e18);
lendingPool.deposit(1_000e18);
vm.stopPrank();
deal(CRV_USD, user_1, 10_000e18);
vm.startPrank(user_1);
ITokenERC20(CRV_USD).approve(address(raacNFT), 10_000e18);
raacNFT.mint(1, 10_000e18);
raacNFT.approve(address(lendingPool), 1);
lendingPool.depositNFT(1);
lendingPool.borrow(1_000e18);
vm.stopPrank();
vm.startPrank(attacker);
vm.expectRevert();
lendingPool.withdraw(1_000e18);
vm.stopPrank();
}
}
contract HousePrices{
function tokenToHousePrice(uint256 _tokenId) external view returns (uint256){
return 10_000e18;
}
}
contract PriceOracle{
function getLatestPrice(uint256 _tokenId) external view returns (uint256, uint256){
return(10_000e18, block.timestamp);
}
}