// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "forge-std/Test.sol"; 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. * @dev Uses ERC1967Proxy for upgradeable contracts (registry, governance, bridge, orchestrator). */ contract UniversalBridgeTest is Test { UniversalAssetRegistry public registry; UniversalCCIPBridge public bridge; BridgeOrchestrator public orchestrator; GovernanceController public governance; address public admin; address public user1; address public user2; address public mockCCIPRouter; function setUp() public { admin = makeAddr("admin"); user1 = makeAddr("user1"); user2 = makeAddr("user2"); mockCCIPRouter = makeAddr("ccipRouter"); vm.startPrank(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)); 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)); 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))); 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(); } function testRegisterStandardERC20() public { vm.startPrank(admin); address mockToken = makeAddr("mockToken"); vm.etch(mockToken, hex"00"); // Give it code bytes32 proposalId = registry.proposeAsset( mockToken, UniversalAssetRegistry.AssetType.ERC20Standard, UniversalAssetRegistry.ComplianceLevel.Public, "Test Token", "TEST", 18, "US", 50, // Medium volatility 1e15, 1000000e18 ); assertTrue(proposalId != bytes32(0), "Proposal should be non-zero"); vm.stopPrank(); } function testGovernanceFlow() public { vm.startPrank(admin); // Add validator registry.addValidator(user1); // Create proposal address mockToken = makeAddr("mockToken2"); vm.etch(mockToken, hex"00"); bytes32 proposalId = registry.proposeAsset( mockToken, UniversalAssetRegistry.AssetType.Stablecoin, UniversalAssetRegistry.ComplianceLevel.Public, "Stablecoin", "STBL", 6, "US", 10, 100e6, 10000000e6 ); vm.stopPrank(); // Vote on proposal vm.prank(user1); registry.voteOnProposal(proposalId, true); // Fast forward time vm.warp(block.timestamp + 2 days); // Execute proposal vm.prank(admin); registry.executeProposal(proposalId); // Verify asset registered assertTrue(registry.isAssetActive(mockToken), "Asset should be active"); } function testBridgeExecution() public { // Test would bridge a token through the full flow // This requires mock CCIP router and token contracts } function testPMMIntegration() public { // Test PMM liquidity provision during bridge } function testComplianceChecks() public { // Test compliance verification for different asset types } }