// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {Test} from "forge-std/Test.sol"; import {CompliantWrappedToken} from "../../contracts/tokens/CompliantWrappedToken.sol"; contract CompliantWrappedTokenTest is Test { CompliantWrappedToken public token; address public admin; address public bridge; address public user1; address public governanceExecutor; bytes32 constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 constant BURNER_ROLE = keccak256("BURNER_ROLE"); function setUp() public { admin = address(this); bridge = address(0xb); user1 = address(0x1); governanceExecutor = address(0x7777); token = new CompliantWrappedToken("Wrapped cUSDT", "cWUSDT", 6, admin); token.grantRole(MINTER_ROLE, bridge); token.grantRole(BURNER_ROLE, bridge); token.setGovernanceController(governanceExecutor); } function testDecimals() public view { assertEq(token.decimals(), 6); } function testMint() public { vm.prank(bridge); token.mint(user1, 1000e6); assertEq(token.balanceOf(user1), 1000e6); } function testMintRevertsNonMinter() public { vm.prank(user1); vm.expectRevert(); token.mint(user1, 1000e6); } function testBurn() public { vm.prank(bridge); token.mint(user1, 1000e6); vm.prank(bridge); token.burn(user1, 400e6); assertEq(token.balanceOf(user1), 600e6); } function testBurnFrom() public { vm.prank(bridge); token.mint(user1, 1000e6); vm.prank(bridge); token.burnFrom(user1, 400e6); assertEq(token.balanceOf(user1), 600e6); } function testBurnFromRevertsNonBurner() public { vm.prank(bridge); token.mint(user1, 1000e6); vm.prank(user1); vm.expectRevert(); token.burnFrom(user1, 400e6); } function testFreezeOperationalRolesBlocksFutureMinterChanges() public { token.freezeOperationalRoles(); vm.expectRevert(); token.grantRole(MINTER_ROLE, address(0xcafe)); } function testFreezeOperationalRolesBlocksFutureBurnerRevocations() public { token.freezeOperationalRoles(); vm.expectRevert(); token.revokeRole(BURNER_ROLE, bridge); } function testFreezeOperationalRolesDoesNotBreakExistingBridgePermissions() public { token.freezeOperationalRoles(); vm.prank(bridge); token.mint(user1, 250e6); vm.prank(bridge); token.burnFrom(user1, 100e6); assertEq(token.balanceOf(user1), 150e6); } function testGovernanceAndSupervisionMetadataCanBeManaged() public { vm.expectRevert(); token.setGovernanceProfileId(keccak256("cw-gov")); vm.startPrank(governanceExecutor); token.setGovernanceProfileId(keccak256("cw-gov")); token.setSupervisionProfileId(keccak256("cw-sup")); token.setStorageNamespace(keccak256("cw-storage")); token.setPrimaryJurisdiction("Avalanche"); token.setRegulatoryDisclosureURI("ipfs://cw-disclosure"); token.setReportingURI("ipfs://cw-reporting"); token.setCanonicalUnderlyingAsset(address(0x1234)); token.setSupervisionConfiguration(true, true, 21 days); vm.stopPrank(); assertEq(token.primaryJurisdiction(), "Avalanche"); assertEq(token.regulatoryDisclosureURI(), "ipfs://cw-disclosure"); assertEq(token.reportingURI(), "ipfs://cw-reporting"); assertEq(token.canonicalUnderlyingAsset(), address(0x1234)); assertTrue(token.supervisionRequired()); assertTrue(token.governmentApprovalRequired()); assertEq(token.minimumUpgradeNoticePeriod(), 21 days); assertTrue(token.wrappedTransport()); } function testEmergencyMetadataOverridesRemainAvailableOutsideGovernance() public { token.emergencySetGovernanceMetadata( keccak256("emergency-cw-gov"), keccak256("emergency-cw-sup"), keccak256("emergency-cw-storage"), "Emergency Wrapped Jurisdiction", address(0x5678), true, true, 30 days ); token.emergencySetDisclosureMetadata("ipfs://cw-emergency-disclosure", "ipfs://cw-emergency-reporting"); assertEq(token.primaryJurisdiction(), "Emergency Wrapped Jurisdiction"); assertEq(token.canonicalUnderlyingAsset(), address(0x5678)); assertEq(token.regulatoryDisclosureURI(), "ipfs://cw-emergency-disclosure"); assertEq(token.reportingURI(), "ipfs://cw-emergency-reporting"); assertEq(token.minimumUpgradeNoticePeriod(), 30 days); } function testWrappedBTCCanUseEightDecimalsAndFrozenBridgeRoles() public { CompliantWrappedToken wrappedBtc = new CompliantWrappedToken("Wrapped cBTC", "cWBTC", 8, admin); wrappedBtc.grantRole(MINTER_ROLE, bridge); wrappedBtc.grantRole(BURNER_ROLE, bridge); vm.prank(bridge); wrappedBtc.mint(user1, 125_000_000); assertEq(wrappedBtc.decimals(), 8); assertEq(wrappedBtc.balanceOf(user1), 125_000_000); wrappedBtc.freezeOperationalRoles(); vm.prank(bridge); wrappedBtc.burnFrom(user1, 25_000_000); assertEq(wrappedBtc.balanceOf(user1), 100_000_000); vm.expectRevert(); wrappedBtc.grantRole(MINTER_ROLE, address(0xCAFE)); } }