// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "forge-std/Test.sol"; import "../src/Treasury.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MockStablecoin is ERC20 { constructor() ERC20("USD Coin", "USDC") {} function decimals() public pure override returns (uint8) { return 6; } function mint(address to, uint256 amount) external { _mint(to, amount); } } contract TreasuryTest is Test { Treasury treasury; MockStablecoin usdc; address admin = address(1); address feeCollector = address(2); address issuer = address(3); address buyer = address(4); address seller = address(5); address claimant1 = address(6); address claimant2 = address(7); function setUp() public { vm.startPrank(admin); usdc = new MockStablecoin(); treasury = new Treasury(); treasury.initialize(address(usdc), feeCollector, admin); // Fund accounts usdc.mint(issuer, 100_000e6); usdc.mint(buyer, 100_000e6); usdc.mint(seller, 100_000e6); vm.stopPrank(); // Approvals vm.prank(issuer); usdc.approve(address(treasury), type(uint256).max); vm.prank(buyer); usdc.approve(address(treasury), type(uint256).max); vm.prank(seller); usdc.approve(address(treasury), type(uint256).max); } // === Guarantee Fund === function test_DepositGuaranteeFund() public { vm.prank(issuer); treasury.depositGuaranteeFund(10000e6); assertEq(treasury.guaranteeFunds(issuer), 10000e6); } function test_WithdrawGuaranteeFund() public { vm.prank(issuer); treasury.depositGuaranteeFund(10000e6); vm.prank(admin); treasury.withdrawGuaranteeFund(issuer, 5000e6); assertEq(treasury.guaranteeFunds(issuer), 5000e6); } function test_ActivateGuaranteeFund() public { vm.prank(issuer); treasury.depositGuaranteeFund(10000e6); address[] memory claimants = new address[](2); claimants[0] = claimant1; claimants[1] = claimant2; uint256[] memory amounts = new uint256[](2); amounts[0] = 3000e6; amounts[1] = 2000e6; vm.prank(admin); treasury.activateGuaranteeFund(issuer, claimants, amounts); assertEq(usdc.balanceOf(claimant1), 3000e6); assertEq(usdc.balanceOf(claimant2), 2000e6); assertEq(treasury.guaranteeFunds(issuer), 5000e6); } function test_ActivateInsufficientReverts() public { vm.prank(issuer); treasury.depositGuaranteeFund(1000e6); address[] memory claimants = new address[](1); claimants[0] = claimant1; uint256[] memory amounts = new uint256[](1); amounts[0] = 5000e6; vm.prank(admin); vm.expectRevert("Treasury: insufficient guarantee fund"); treasury.activateGuaranteeFund(issuer, claimants, amounts); } // === Escrow === function test_EscrowAndRelease() public { vm.prank(admin); treasury.escrow(1, buyer, 1000e6); assertEq(usdc.balanceOf(address(treasury)), 1000e6); vm.prank(admin); treasury.release(1, seller, 950e6, 50e6); assertEq(usdc.balanceOf(seller), 100_000e6 + 950e6); assertEq(usdc.balanceOf(feeCollector), 50e6); } function test_EscrowRefund() public { uint256 buyerBefore = usdc.balanceOf(buyer); vm.prank(admin); treasury.escrow(1, buyer, 1000e6); vm.prank(admin); treasury.refundEscrow(1); assertEq(usdc.balanceOf(buyer), buyerBefore); } function test_DoubleReleaseReverts() public { vm.prank(admin); treasury.escrow(1, buyer, 1000e6); vm.prank(admin); treasury.release(1, seller, 950e6, 50e6); vm.prank(admin); vm.expectRevert("Treasury: already settled"); treasury.release(1, seller, 950e6, 50e6); } function test_ReleaseExceedsEscrowReverts() public { vm.prank(admin); treasury.escrow(1, buyer, 1000e6); vm.prank(admin); vm.expectRevert("Treasury: exceeds escrow"); treasury.release(1, seller, 1000e6, 100e6); } function test_DuplicateEscrowReverts() public { vm.prank(admin); treasury.escrow(1, buyer, 1000e6); vm.prank(admin); vm.expectRevert("Treasury: escrow exists"); treasury.escrow(1, buyer, 500e6); } // === Sales Revenue === function test_FreezeSalesRevenue() public { vm.prank(issuer); treasury.freezeSalesRevenue(5000e6); assertEq(treasury.frozenSalesRevenue(issuer), 5000e6); } function test_ReleaseSalesRevenue() public { vm.prank(issuer); treasury.freezeSalesRevenue(5000e6); vm.prank(admin); treasury.releaseSalesRevenue(issuer, 3000e6); assertEq(treasury.frozenSalesRevenue(issuer), 2000e6); } // === Fee Collector === function test_SetPlatformFeeCollector() public { address newCollector = address(99); vm.prank(admin); treasury.setPlatformFeeCollector(newCollector); assertEq(treasury.platformFeeCollector(), newCollector); } }