Files
smom-dbis-138/test/iso4217w/ISO4217WToken.t.sol
2026-03-02 12:14:09 -08:00

139 lines
4.2 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../../contracts/iso4217w/ISO4217WToken.sol";
import "../../contracts/iso4217w/ComplianceGuard.sol";
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
contract ISO4217WTokenTest is Test {
ISO4217WToken public token;
ComplianceGuard public complianceGuard;
address public admin = address(0x1);
address public custodian = address(0x2);
address public mintController = address(0x3);
address public burnController = address(0x4);
address public user = address(0x5);
string public constant CURRENCY_CODE = "USD";
string public constant TOKEN_SYMBOL = "USDW";
uint8 public constant DECIMALS = 2;
function setUp() public {
complianceGuard = new ComplianceGuard(admin);
// Deploy implementation
ISO4217WToken implementation = new ISO4217WToken();
// Deploy proxy
bytes memory initData = abi.encodeWithSelector(
ISO4217WToken.initialize.selector,
"USDW Token",
TOKEN_SYMBOL,
CURRENCY_CODE,
DECIMALS,
custodian,
mintController,
burnController,
address(complianceGuard),
admin
);
ERC1967Proxy proxy = new ERC1967Proxy(address(implementation), initData);
token = ISO4217WToken(address(proxy));
// Grant roles
vm.prank(admin);
token.grantRole(keccak256("MINTER_ROLE"), mintController);
vm.prank(admin);
token.grantRole(keccak256("BURNER_ROLE"), burnController);
vm.prank(admin);
token.grantRole(keccak256("RESERVE_UPDATE_ROLE"), admin);
}
function test_Initialize() public view {
assertEq(keccak256(bytes(token.currencyCode())), keccak256(bytes(CURRENCY_CODE)));
assertEq(token.custodian(), custodian);
assertEq(token.decimals(), DECIMALS);
}
function test_Mint() public {
vm.prank(admin);
token.updateVerifiedReserve(10000e2); // 10,000 USD reserve
vm.prank(mintController);
token.mint(user, 1000e2); // 1,000 USDW
assertEq(token.totalSupply(), 1000e2);
assertEq(token.balanceOf(user), 1000e2);
}
function test_Mint_RevertIfReserveInsufficient() public {
vm.prank(admin);
token.updateVerifiedReserve(500e2); // 500 USD reserve
vm.prank(mintController);
vm.expectRevert("ISO4217WToken: reserve insufficient - money multiplier violation");
token.mint(user, 1000e2); // Try to mint 1,000 USDW
}
function test_Burn() public {
vm.prank(admin);
token.updateVerifiedReserve(10000e2);
vm.prank(mintController);
token.mint(user, 1000e2);
vm.prank(burnController);
token.burn(user, 500e2);
assertEq(token.totalSupply(), 500e2);
assertEq(token.balanceOf(user), 500e2);
}
function test_UpdateVerifiedReserve() public {
vm.prank(admin);
token.updateVerifiedReserve(10000e2);
assertEq(token.verifiedReserve(), 10000e2);
assertTrue(token.isReserveSufficient()); // No supply yet
vm.prank(mintController);
token.mint(user, 5000e2);
vm.prank(admin);
token.updateVerifiedReserve(4000e2); // Reserve below supply
assertFalse(token.isReserveSufficient()); // Should flag but not revert
}
function test_IsReserveSufficient() public {
vm.prank(admin);
token.updateVerifiedReserve(10000e2);
assertTrue(token.isReserveSufficient());
vm.prank(mintController);
token.mint(user, 5000e2);
assertTrue(token.isReserveSufficient());
// Mint more (total 11k) - need reserve >= 11k first
vm.prank(admin);
token.updateVerifiedReserve(15000e2);
vm.prank(mintController);
token.mint(user, 6000e2); // Total: 11,000
assertTrue(token.isReserveSufficient()); // 15k reserve >= 11k supply
// Reduce reserve below supply - updateVerifiedReserve doesn't revert, just flags
vm.prank(admin);
token.updateVerifiedReserve(10000e2); // 10k < 11k supply
assertFalse(token.isReserveSufficient());
}
}