// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "forge-std/Test.sol"; import "../../contracts/iso4217w/controllers/BurnController.sol"; import "../../contracts/iso4217w/ISO4217WToken.sol"; import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract BurnControllerTest is Test { BurnController public burnController; ISO4217WToken public token; address public admin = address(0x1); address public redeemer = address(0x2); address public user = address(0x3); address public custodian = address(0x4); function setUp() public { vm.startPrank(admin); burnController = new BurnController(admin); // Deploy token ISO4217WToken implementation = new ISO4217WToken(); bytes memory initData = abi.encodeWithSelector( ISO4217WToken.initialize.selector, "USDW Token", "USDW", "USD", 2, custodian, address(0x999), // mint controller placeholder address(burnController), address(0x888), // compliance guard placeholder admin ); ERC1967Proxy proxy = new ERC1967Proxy(address(implementation), initData); token = ISO4217WToken(address(proxy)); // Grant roles token.grantRole(keccak256("BURNER_ROLE"), address(burnController)); burnController.grantRole(keccak256("REDEEMER_ROLE"), redeemer); burnController.approveToken(address(token)); // Set reserve before mint (token enforces reserve >= supply) token.grantRole(keccak256("RESERVE_UPDATE_ROLE"), admin); token.updateVerifiedReserve(10000e2); // Mint some tokens to user token.grantRole(keccak256("MINTER_ROLE"), admin); token.mint(user, 1000e2); vm.stopPrank(); } function test_Redeem() public { assertEq(token.balanceOf(user), 1000e2); vm.prank(redeemer); bytes32 redemptionId = burnController.redeem(address(token), user, 500e2); assertEq(token.balanceOf(user), 500e2); assertEq(token.totalSupply(), 500e2); assertNotEq(redemptionId, bytes32(0)); // Check redemption record BurnController.Redemption memory redemption = burnController.getRedemption(redemptionId); assertEq(redemption.token, address(token)); assertEq(redemption.redeemer, user); assertEq(redemption.amount, 500e2); assertTrue(redemption.processed); } function test_Burn() public { vm.prank(admin); burnController.burn(address(token), user, 300e2); assertEq(token.balanceOf(user), 700e2); assertEq(token.totalSupply(), 700e2); } function test_CanRedeem() public { bool canRedeem = burnController.canRedeem(address(token), 500e2); assertTrue(canRedeem, "Should be able to redeem"); bool cannotRedeem = burnController.canRedeem(address(token), 2000e2); assertFalse(cannotRedeem, "Should not be able to redeem more than supply"); } function test_Redeem_RevertIfNotApprovedToken() public { address unapprovedToken = address(0x999); vm.prank(redeemer); vm.expectRevert("BurnController: token not approved"); burnController.redeem(unapprovedToken, user, 100e2); } }