chore: sync submodule state (parent ref update)
Made-with: Cursor
This commit is contained in:
125
test/integration/GRUCompliantTokensRegistry.t.sol
Normal file
125
test/integration/GRUCompliantTokensRegistry.t.sol
Normal file
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Test.sol";
|
||||
import "../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
import "../../contracts/registry/GRUAssetRegistryFacet.sol";
|
||||
import "../../contracts/tokens/CompliantUSDT.sol";
|
||||
import "../../contracts/tokens/CompliantUSDC.sol";
|
||||
import "../../contracts/tokens/CompliantFiatToken.sol";
|
||||
import "../../contracts/bridge/GRUCCIPBridge.sol";
|
||||
import "../../contracts/bridge/UniversalCCIPBridge.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
|
||||
/**
|
||||
* @title GRU Compliant Tokens Registry Integration Tests
|
||||
* @notice Ensures all c* tokens are integrated with GRU ERC-2535 facet path: UniversalAssetRegistry (AssetType.GRU) and GRUAssetRegistryFacet.
|
||||
*/
|
||||
contract GRUCompliantTokensRegistryTest is Test {
|
||||
UniversalAssetRegistry public registry;
|
||||
GRUAssetRegistryFacet public facet;
|
||||
CompliantUSDT public cusdt;
|
||||
CompliantUSDC public cusdc;
|
||||
CompliantFiatToken public ceurc;
|
||||
|
||||
address public admin;
|
||||
|
||||
function setUp() public {
|
||||
admin = makeAddr("admin");
|
||||
vm.startPrank(admin);
|
||||
|
||||
UniversalAssetRegistry impl = new UniversalAssetRegistry();
|
||||
bytes memory initData = abi.encodeCall(UniversalAssetRegistry.initialize, (admin));
|
||||
ERC1967Proxy proxy = new ERC1967Proxy(address(impl), initData);
|
||||
registry = UniversalAssetRegistry(address(proxy));
|
||||
|
||||
cusdt = new CompliantUSDT(admin, admin);
|
||||
cusdc = new CompliantUSDC(admin, admin);
|
||||
ceurc = new CompliantFiatToken(
|
||||
"Euro Coin (Compliant)",
|
||||
"cEURC",
|
||||
6,
|
||||
"EUR",
|
||||
admin,
|
||||
admin,
|
||||
1_000_000 * 10**6
|
||||
);
|
||||
|
||||
facet = new GRUAssetRegistryFacet();
|
||||
facet.setRegistry(address(registry));
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function test_registerGRUCompliantAsset_cUSDT() public {
|
||||
vm.prank(admin);
|
||||
registry.registerGRUCompliantAsset(
|
||||
address(cusdt),
|
||||
"Tether USD (Compliant)",
|
||||
"cUSDT",
|
||||
6,
|
||||
"International"
|
||||
);
|
||||
assertTrue(registry.isAssetActive(address(cusdt)));
|
||||
assertEq(uint256(registry.getAssetType(address(cusdt))), uint256(UniversalAssetRegistry.AssetType.GRU));
|
||||
UniversalAssetRegistry.UniversalAsset memory asset = registry.getAsset(address(cusdt));
|
||||
assertEq(asset.symbol, "cUSDT");
|
||||
assertEq(asset.decimals, 6);
|
||||
}
|
||||
|
||||
function test_registerGRUCompliantAsset_allThree() public {
|
||||
vm.startPrank(admin);
|
||||
registry.registerGRUCompliantAsset(address(cusdt), "Tether USD (Compliant)", "cUSDT", 6, "International");
|
||||
registry.registerGRUCompliantAsset(address(cusdc), "USD Coin (Compliant)", "cUSDC", 6, "International");
|
||||
registry.registerGRUCompliantAsset(address(ceurc), "Euro Coin (Compliant)", "cEURC", 6, "International");
|
||||
vm.stopPrank();
|
||||
|
||||
assertTrue(registry.isAssetActive(address(cusdt)));
|
||||
assertTrue(registry.isAssetActive(address(cusdc)));
|
||||
assertTrue(registry.isAssetActive(address(ceurc)));
|
||||
assertEq(uint256(registry.getAssetType(address(cusdt))), uint256(UniversalAssetRegistry.AssetType.GRU));
|
||||
assertEq(uint256(registry.getAssetType(address(cusdc))), uint256(UniversalAssetRegistry.AssetType.GRU));
|
||||
assertEq(uint256(registry.getAssetType(address(ceurc))), uint256(UniversalAssetRegistry.AssetType.GRU));
|
||||
|
||||
address[] memory gruAssets = registry.getAssetsByType(UniversalAssetRegistry.AssetType.GRU);
|
||||
assertEq(gruAssets.length, 3);
|
||||
}
|
||||
|
||||
function test_facet_delegates_to_registry() public {
|
||||
vm.prank(admin);
|
||||
registry.registerGRUCompliantAsset(address(cusdt), "Tether USD (Compliant)", "cUSDT", 6, "International");
|
||||
|
||||
assertTrue(facet.isAssetActive(address(cusdt)));
|
||||
assertEq(uint256(facet.getAssetType(address(cusdt))), uint256(UniversalAssetRegistry.AssetType.GRU));
|
||||
UniversalAssetRegistry.UniversalAsset memory viaFacet = facet.getAsset(address(cusdt));
|
||||
assertEq(viaFacet.symbol, "cUSDT");
|
||||
}
|
||||
|
||||
function test_GRUCCIPBridge_accepts_registered_GRU_asset() public {
|
||||
address mockRouter = makeAddr("router");
|
||||
vm.startPrank(admin);
|
||||
registry.registerGRUCompliantAsset(address(cusdt), "Tether USD (Compliant)", "cUSDT", 6, "International");
|
||||
|
||||
GRUCCIPBridge bridgeImpl = new GRUCCIPBridge();
|
||||
bytes memory bridgeInit = abi.encodeCall(UniversalCCIPBridge.initialize, (address(registry), mockRouter, admin));
|
||||
ERC1967Proxy bridgeProxy = new ERC1967Proxy(address(bridgeImpl), bridgeInit);
|
||||
GRUCCIPBridge bridge = GRUCCIPBridge(payable(address(bridgeProxy)));
|
||||
vm.stopPrank();
|
||||
|
||||
UniversalAssetRegistry.UniversalAsset memory asset = registry.getAsset(address(cusdt));
|
||||
assertEq(uint256(asset.assetType), uint256(UniversalAssetRegistry.AssetType.GRU), "cUSDT must be GRU for bridge");
|
||||
}
|
||||
|
||||
function test_revert_registerGRUCompliantAsset_notRegistrar() public {
|
||||
vm.prank(makeAddr("stranger"));
|
||||
vm.expectRevert();
|
||||
registry.registerGRUCompliantAsset(address(cusdt), "Tether USD (Compliant)", "cUSDT", 6, "International");
|
||||
}
|
||||
|
||||
function test_revert_registerGRUCompliantAsset_alreadyRegistered() public {
|
||||
vm.startPrank(admin);
|
||||
registry.registerGRUCompliantAsset(address(cusdt), "Tether USD (Compliant)", "cUSDT", 6, "International");
|
||||
vm.expectRevert("Already registered");
|
||||
registry.registerGRUCompliantAsset(address(cusdt), "Tether USD (Compliant)", "cUSDT", 6, "International");
|
||||
vm.stopPrank();
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,12 @@ import "../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
import "../../contracts/bridge/UniversalCCIPBridge.sol";
|
||||
import "../../contracts/bridge/BridgeOrchestrator.sol";
|
||||
import "../../contracts/governance/GovernanceController.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
|
||||
/**
|
||||
* @title UniversalBridge Integration Tests
|
||||
* @notice Comprehensive tests for all asset types through full bridge flow
|
||||
* @notice Comprehensive tests for all asset types through full bridge flow.
|
||||
* @dev Uses ERC1967Proxy for upgradeable contracts (registry, governance, bridge, orchestrator).
|
||||
*/
|
||||
contract UniversalBridgeTest is Test {
|
||||
UniversalAssetRegistry public registry;
|
||||
@@ -30,18 +32,26 @@ contract UniversalBridgeTest is Test {
|
||||
|
||||
vm.startPrank(admin);
|
||||
|
||||
// Deploy core contracts
|
||||
registry = new UniversalAssetRegistry();
|
||||
registry.initialize(admin);
|
||||
// Deploy upgradeable contracts via proxy (implementations use _disableInitializers())
|
||||
UniversalAssetRegistry registryImpl = new UniversalAssetRegistry();
|
||||
bytes memory registryInit = abi.encodeCall(UniversalAssetRegistry.initialize, (admin));
|
||||
ERC1967Proxy registryProxy = new ERC1967Proxy(address(registryImpl), registryInit);
|
||||
registry = UniversalAssetRegistry(address(registryProxy));
|
||||
|
||||
governance = new GovernanceController();
|
||||
governance.initialize(address(registry), admin);
|
||||
GovernanceController governanceImpl = new GovernanceController();
|
||||
bytes memory governanceInit = abi.encodeCall(GovernanceController.initialize, (address(registry), admin));
|
||||
ERC1967Proxy governanceProxy = new ERC1967Proxy(address(governanceImpl), governanceInit);
|
||||
governance = GovernanceController(address(governanceProxy));
|
||||
|
||||
bridge = new UniversalCCIPBridge();
|
||||
bridge.initialize(address(registry), mockCCIPRouter, admin);
|
||||
UniversalCCIPBridge bridgeImpl = new UniversalCCIPBridge();
|
||||
bytes memory bridgeInit = abi.encodeCall(UniversalCCIPBridge.initialize, (address(registry), mockCCIPRouter, admin));
|
||||
ERC1967Proxy bridgeProxy = new ERC1967Proxy(address(bridgeImpl), bridgeInit);
|
||||
bridge = UniversalCCIPBridge(payable(address(bridgeProxy)));
|
||||
|
||||
orchestrator = new BridgeOrchestrator();
|
||||
orchestrator.initialize(address(registry), address(bridge), admin);
|
||||
BridgeOrchestrator orchestratorImpl = new BridgeOrchestrator();
|
||||
bytes memory orchestratorInit = abi.encodeCall(BridgeOrchestrator.initialize, (address(registry), address(bridge), admin));
|
||||
ERC1967Proxy orchestratorProxy = new ERC1967Proxy(address(orchestratorImpl), orchestratorInit);
|
||||
orchestrator = BridgeOrchestrator(address(orchestratorProxy));
|
||||
|
||||
vm.stopPrank();
|
||||
}
|
||||
@@ -65,7 +75,7 @@ contract UniversalBridgeTest is Test {
|
||||
1000000e18
|
||||
);
|
||||
|
||||
assertEq(uint256(proposalId), 0, "Proposal should be non-zero");
|
||||
assertTrue(proposalId != bytes32(0), "Proposal should be non-zero");
|
||||
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user