- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault. - Token-aggregation service routes, planner, chain config, relay env templates. - Config snapshots and multi-chain deployment markdown updates. - gitignore services/btc-intake/dist/ (tsc output); do not track dist. Run forge build && forge test before deploy (large solc graph). Made-with: Cursor
158 lines
5.4 KiB
Solidity
158 lines
5.4 KiB
Solidity
// 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));
|
|
}
|
|
}
|