139 lines
4.2 KiB
Solidity
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());
|
|
}
|
|
}
|