75 lines
3.9 KiB
Solidity
75 lines
3.9 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "forge-std/Script.sol";
|
|
import {CREATE2Factory} from "../../contracts/utils/CREATE2Factory.sol";
|
|
import {MirrorRegistry} from "../../contracts/mirror/MirrorRegistry.sol";
|
|
import {UniversalCCIPBridge} from "../../contracts/bridge/UniversalCCIPBridge.sol";
|
|
import {UniversalAssetRegistry} from "../../contracts/registry/UniversalAssetRegistry.sol";
|
|
import {AlltraAdapter} from "../../contracts/bridge/adapters/evm/AlltraAdapter.sol";
|
|
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
|
|
|
/**
|
|
* @title DeployDeterministicCore
|
|
* @notice Deploy MirrorRegistry, UniversalCCIPBridge (proxy), UniversalAssetRegistry, AlltraAdapter via CREATE2 with fixed salts.
|
|
* @dev Use identical ADMIN and (where applicable) ASSET_REGISTRY per chain so addresses match. Call setCCIPRouter(router) on bridge after deploy on each chain.
|
|
* See docs/runbooks/MULTI_CHAIN_EXECUTION_DETERMINISTIC_DEPLOYMENT.md
|
|
* Refactored to avoid Yul stack-too-deep: single struct + internal deployAll to minimize run() stack.
|
|
*/
|
|
contract DeployDeterministicCore is Script {
|
|
uint256 constant SALT_MIRROR_REGISTRY = uint256(keccak256("MirrorRegistry"));
|
|
uint256 constant SALT_UNIVERSAL_ASSET_REGISTRY_IMPL = uint256(keccak256("UniversalAssetRegistry"));
|
|
uint256 constant SALT_UNIVERSAL_ASSET_REGISTRY_PROXY = uint256(keccak256("UniversalAssetRegistry.Proxy"));
|
|
uint256 constant SALT_CCIP_BRIDGE_IMPL = uint256(keccak256("UniversalCCIPBridge"));
|
|
uint256 constant SALT_CCIP_BRIDGE_PROXY = uint256(keccak256("UniversalCCIPBridge.Proxy"));
|
|
uint256 constant SALT_ALLTRA_ADAPTER = uint256(keccak256("AlltraAdapter"));
|
|
|
|
struct DeployResult {
|
|
address factory;
|
|
address registry;
|
|
address bridgeProxy;
|
|
address mirror;
|
|
address adapter;
|
|
}
|
|
|
|
function run() external {
|
|
uint256 pk = vm.envUint("PRIVATE_KEY");
|
|
address admin = vm.envOr("ADMIN", vm.addr(pk));
|
|
vm.startBroadcast(pk);
|
|
DeployResult memory r = _deployAll(admin);
|
|
vm.stopBroadcast();
|
|
console.log("CREATE2Factory:", r.factory);
|
|
console.log("UniversalAssetRegistry:", r.registry);
|
|
console.log("UniversalCCIPBridge proxy:", r.bridgeProxy);
|
|
console.log("MirrorRegistry:", r.mirror);
|
|
console.log("AlltraAdapter:", r.adapter);
|
|
console.log("\n--- Deterministic deployment summary ---");
|
|
console.log("Call UniversalCCIPBridge.setCCIPRouter(router) on each chain after deploy.");
|
|
}
|
|
|
|
function _deployAll(address admin) internal returns (DeployResult memory r) {
|
|
CREATE2Factory factory = new CREATE2Factory();
|
|
r.factory = address(factory);
|
|
|
|
address registryImpl = factory.deploy(type(UniversalAssetRegistry).creationCode, SALT_UNIVERSAL_ASSET_REGISTRY_IMPL);
|
|
bytes memory registryInitData = abi.encodeCall(UniversalAssetRegistry.initialize, (admin));
|
|
bytes memory registryProxyBytecode = abi.encodePacked(type(ERC1967Proxy).creationCode, abi.encode(registryImpl, registryInitData));
|
|
r.registry = factory.deploy(registryProxyBytecode, SALT_UNIVERSAL_ASSET_REGISTRY_PROXY);
|
|
|
|
address impl = factory.deploy(type(UniversalCCIPBridge).creationCode, SALT_CCIP_BRIDGE_IMPL);
|
|
address ccipRouter = vm.envOr("CCIP_ROUTER", address(0));
|
|
bytes memory initData = abi.encodeCall(UniversalCCIPBridge.initialize, (r.registry, ccipRouter, admin));
|
|
bytes memory proxyBytecode = abi.encodePacked(type(ERC1967Proxy).creationCode, abi.encode(impl, initData));
|
|
r.bridgeProxy = factory.deploy(proxyBytecode, SALT_CCIP_BRIDGE_PROXY);
|
|
|
|
r.mirror = factory.deploy(
|
|
abi.encodePacked(type(MirrorRegistry).creationCode, abi.encode(admin)),
|
|
SALT_MIRROR_REGISTRY
|
|
);
|
|
r.adapter = factory.deploy(
|
|
abi.encodePacked(type(AlltraAdapter).creationCode, abi.encode(admin, r.bridgeProxy)),
|
|
SALT_ALLTRA_ADAPTER
|
|
);
|
|
}
|
|
}
|