// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {Test} from "forge-std/Test.sol"; import {CompliantUSDT} from "../../contracts/tokens/CompliantUSDT.sol"; import {ComplianceRegistry} from "../../contracts/compliance/ComplianceRegistry.sol"; contract CompliantUSDTTest is Test { CompliantUSDT public usdt; ComplianceRegistry public registry; address public owner; address public admin; address public user1; address public user2; function setUp() public { owner = address(this); admin = address(this); user1 = address(0x1); user2 = address(0x2); usdt = new CompliantUSDT(owner, admin); registry = new ComplianceRegistry(admin); } function testInitialSupply() public { assertEq(usdt.totalSupply(), 1000000 * 10**6); assertEq(usdt.balanceOf(address(this)), 1000000 * 10**6); } function testDecimals() public { assertEq(usdt.decimals(), 6); } function testTransfer() public { uint256 amount = 1000 * 10**6; // forge-lint: disable-next-line(erc20-unchecked-transfer) usdt.transfer(user1, amount); assertEq(usdt.balanceOf(user1), amount); assertEq(usdt.balanceOf(address(this)), 1000000 * 10**6 - amount); } function testPause() public { usdt.pause(); assertTrue(usdt.paused()); vm.expectRevert(); // forge-lint: disable-next-line(erc20-unchecked-transfer) usdt.transfer(user1, 1000 * 10**6); } function testUnpause() public { usdt.pause(); usdt.unpause(); assertFalse(usdt.paused()); // forge-lint: disable-next-line(erc20-unchecked-transfer) usdt.transfer(user1, 1000 * 10**6); assertEq(usdt.balanceOf(user1), 1000 * 10**6); } function testMint() public { uint256 amount = 5000 * 10**6; usdt.mint(user1, amount); assertEq(usdt.balanceOf(user1), amount); assertEq(usdt.totalSupply(), 1000000 * 10**6 + amount); } function testBurn() public { uint256 amount = 1000 * 10**6; // forge-lint: disable-next-line(erc20-unchecked-transfer) usdt.transfer(user1, amount); vm.prank(user1); usdt.burn(amount); assertEq(usdt.balanceOf(user1), 0); assertEq(usdt.totalSupply(), 1000000 * 10**6 - amount); } function testComplianceRegistration() public { registry.registerContract(address(usdt)); assertTrue(registry.isContractRegistered(address(usdt))); ComplianceRegistry.ContractComplianceStatus memory status = registry.getContractComplianceStatus(address(usdt)); assertTrue(status.isRegistered); assertEq(status.legalFrameworkVersion, "1.0.0"); } function testValueTransferEvent() public { uint256 amount = 1000 * 10**6; // Check that the ValueTransferDeclared event is emitted during transfer // The event is defined in LegallyCompliantBase and inherited by CompliantUSDT // We can't emit it directly from abstract contract, so we just verify it happens vm.expectEmit(true, true, false, false); // Check indexed params only, ignore data // Event signature: ValueTransferDeclared(address indexed, address indexed, uint256, bytes32) // We check the indexed parameters (from, to) and ignore the non-indexed ones emit ValueTransferDeclared( address(this), user1, amount, bytes32(0) ); // forge-lint: disable-next-line(erc20-unchecked-transfer) usdt.transfer(user1, amount); } // Helper event for testing (matches LegallyCompliantBase.ValueTransferDeclared) event ValueTransferDeclared( address indexed from, address indexed to, uint256 value, bytes32 legalReferenceHash ); }