pragma solidity 0.8.20; import {Test} from "forge-std/Test.sol"; import {Fatso} from "../../src/FatsoERC20.sol"; import {GhostAuthority} from "../../src/GhostAuthority.sol"; import {GhostTreasury} from "../../src/Treasury.sol"; import {GhostBondingCalculator} from "../../src/StandardBondingCalculator.sol"; import {ERC20Mock} from "../../src/mocks/ERC20Mock.sol"; import {ITreasury} from "../../src/interfaces/ITreasury.sol"; import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "@openzeppelin-contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {SafeERC20} from "@openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; contract GhostTreasuryCoefficientLesserTest is Test { using SafeERC20 for IERC20; address public constant OWNER = 0x0000000000000000000000000000000000000001; address public constant GOVERNOR = 0x0000000000000000000000000000000000000002; address public constant GUARDIAN = 0x0000000000000000000000000000000000000003; address public constant ALICE = 0x0000000000000000000000000000000000000004; uint256 public constant AMOUNT = 69 * 1e18; Fatso ftso; ERC20Mock reserve; ERC20Mock liquidity; GhostTreasury treasury; GhostAuthority authority; GhostBondingCalculator calculator; function setUp() public { vm.startPrank(OWNER); authority = new GhostAuthority( GOVERNOR, GUARDIAN, OWNER, OWNER ); reserve = new ERC20Mock("Reserve Token", "RET"); liquidity = new ERC20Mock("Liquidity Token", "LDT"); ftso = new Fatso(address(authority), "Fatso", "FTSO"); treasury = new GhostTreasury(address(ftso), 69, address(authority)); calculator = new GhostBondingCalculator(address(ftso), 1, 20); vm.stopPrank(); vm.prank(GOVERNOR); authority.pushVault(address(treasury)); vm.startPrank(ALICE); reserve.mint(ALICE, AMOUNT); reserve.approve(address(treasury), type(uint256).max); ftso.approve(address(treasury), type(uint256).max); vm.stopPrank(); } function test_deposit_onlyIfApprovedTokenAndApprovedAddress() public { vm.expectRevert(); vm.prank(ALICE); treasury.deposit(address(reserve), AMOUNT, 0); vm.prank(GOVERNOR); treasury.enable(ITreasury.STATUS.RESERVEDEPOSITOR, ALICE, address(0)); vm.expectRevert(); vm.prank(ALICE); treasury.deposit(address(reserve), AMOUNT, 0); vm.prank(GOVERNOR); treasury.enable(ITreasury.STATUS.RESERVETOKEN, address(reserve), address(calculator)); vm.prank(ALICE); uint256 send = treasury.deposit(address(reserve), AMOUNT, 0); assertEq(ftso.balanceOf(ALICE), send); assertEq(reserve.balanceOf(address(treasury)), AMOUNT); vm.startPrank(GOVERNOR); treasury.enable(ITreasury.STATUS.RESERVEDEPOSITOR, ALICE, address(0)); treasury.enable(ITreasury.STATUS.RESERVETOKEN, address(reserve), address(calculator)); vm.stopPrank(); } function test_auditTreasuryReservesWithCoefficient() public { vm.startPrank(GOVERNOR); treasury.enable(ITreasury.STATUS.RESERVEDEPOSITOR, ALICE, address(0)); treasury.enable(ITreasury.STATUS.RESERVETOKEN, address(reserve), address(calculator)); vm.stopPrank(); assertEq(treasury.totalReserves(), 0); uint256 tokenValue = treasury.tokenValue(address(reserve), AMOUNT); vm.prank(ALICE); IERC20(reserve).safeTransfer(address(treasury), AMOUNT); assertEq(treasury.totalReserves(), 0); vm.prank(GOVERNOR); treasury.auditReserves(); assertEq(treasury.totalReserves(), tokenValue); uint256 coefficient = treasury.originalCoefficient(); uint256 decimals = IERC20Metadata(address(reserve)).decimals() + 9; uint256 convertedReserves = treasury.totalReserves() * 10**decimals / coefficient; uint256 convertedEps = convertedReserves * 1e5 / 1e12; // .000001% assertEq(convertedReserves + convertedEps >= convertedReserves, true); assertEq(convertedReserves - convertedEps <= convertedReserves, true); assertEq(treasury.excessReserves(), tokenValue); } function test_originalCoefficientCorrect() public { vm.startPrank(GOVERNOR); treasury.enable(ITreasury.STATUS.RESERVEDEPOSITOR, ALICE, address(0)); treasury.enable(ITreasury.STATUS.RESERVETOKEN, address(reserve), address(calculator)); vm.stopPrank(); uint256 estimation = 1e18 / 20; uint256 estimationEps = estimation * 1e5 / 1e12; // .000001% assertEq(estimation + estimationEps >= treasury.originalCoefficient(), true); assertEq(estimation - estimationEps <= treasury.originalCoefficient(), true); } }