chore: sync submodule state (parent ref update)
Made-with: Cursor
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
import "../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
import "../../contracts/governance/GovernanceController.sol";
|
||||
|
||||
@@ -12,14 +13,19 @@ contract DeployCore is Script {
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
UniversalAssetRegistry registry = new UniversalAssetRegistry();
|
||||
registry.initialize(deployer);
|
||||
|
||||
GovernanceController governance = new GovernanceController();
|
||||
governance.initialize(address(registry), deployer);
|
||||
|
||||
// Deploy UniversalAssetRegistry behind proxy (UUPS upgradeable)
|
||||
UniversalAssetRegistry registryImpl = new UniversalAssetRegistry();
|
||||
bytes memory registryInitData = abi.encodeCall(UniversalAssetRegistry.initialize, (deployer));
|
||||
ERC1967Proxy registryProxy = new ERC1967Proxy(address(registryImpl), registryInitData);
|
||||
UniversalAssetRegistry registry = UniversalAssetRegistry(address(registryProxy));
|
||||
registry.addValidator(deployer);
|
||||
|
||||
// Deploy GovernanceController behind proxy (UUPS upgradeable)
|
||||
GovernanceController governanceImpl = new GovernanceController();
|
||||
bytes memory governanceInitData = abi.encodeCall(GovernanceController.initialize, (address(registry), deployer));
|
||||
ERC1967Proxy governanceProxy = new ERC1967Proxy(address(governanceImpl), governanceInitData);
|
||||
GovernanceController governance = GovernanceController(address(governanceProxy));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("UNIVERSAL_ASSET_REGISTRY=", address(registry));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
import "../../contracts/bridge/UniversalCCIPBridge.sol";
|
||||
import "../../contracts/bridge/BridgeOrchestrator.sol";
|
||||
|
||||
@@ -14,15 +15,21 @@ contract DeployBridges is Script {
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
UniversalCCIPBridge bridge = new UniversalCCIPBridge();
|
||||
bridge.initialize(registry, ccipRouter, deployer);
|
||||
// UniversalCCIPBridge behind proxy (UUPS upgradeable)
|
||||
UniversalCCIPBridge bridgeImpl = new UniversalCCIPBridge();
|
||||
bytes memory bridgeInitData = abi.encodeCall(UniversalCCIPBridge.initialize, (registry, ccipRouter, deployer));
|
||||
ERC1967Proxy bridgeProxy = new ERC1967Proxy(address(bridgeImpl), bridgeInitData);
|
||||
address bridgeAddr = address(bridgeProxy);
|
||||
|
||||
BridgeOrchestrator orchestrator = new BridgeOrchestrator();
|
||||
orchestrator.initialize(registry, address(bridge), deployer);
|
||||
// BridgeOrchestrator behind proxy (UUPS upgradeable)
|
||||
BridgeOrchestrator orchestratorImpl = new BridgeOrchestrator();
|
||||
bytes memory orchestratorInitData = abi.encodeCall(BridgeOrchestrator.initialize, (registry, bridgeAddr, deployer));
|
||||
ERC1967Proxy orchestratorProxy = new ERC1967Proxy(address(orchestratorImpl), orchestratorInitData);
|
||||
address orchestratorAddr = address(orchestratorProxy);
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("UNIVERSAL_CCIP_BRIDGE=", address(bridge));
|
||||
console.log("BRIDGE_ORCHESTRATOR=", address(orchestrator));
|
||||
console.log("UNIVERSAL_CCIP_BRIDGE=", bridgeAddr);
|
||||
console.log("BRIDGE_ORCHESTRATOR=", orchestratorAddr);
|
||||
}
|
||||
}
|
||||
|
||||
38
script/deploy/DeployBridgeVaultDeterministic.s.sol
Normal file
38
script/deploy/DeployBridgeVaultDeterministic.s.sol
Normal file
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {CREATE2Factory} from "../../contracts/utils/CREATE2Factory.sol";
|
||||
import {BridgeVault138} from "../../contracts/emoney/BridgeVault138.sol";
|
||||
|
||||
/**
|
||||
* @title DeployBridgeVaultDeterministic
|
||||
* @notice Deploy BridgeVault138 via CREATE2 with fixed salt for chains 1, 137, 56 (Ethereum, Polygon, BSC).
|
||||
* @dev Use identical ADMIN, POLICY_MANAGER, COMPLIANCE_REGISTRY on all three chains so the vault address is the same.
|
||||
* Env: PRIVATE_KEY, ADMIN, POLICY_MANAGER, COMPLIANCE_REGISTRY.
|
||||
* See docs/runbooks/MULTI_CHAIN_EXECUTION_DETERMINISTIC_DEPLOYMENT.md
|
||||
*/
|
||||
contract DeployBridgeVaultDeterministic is Script {
|
||||
uint256 constant SALT_BRIDGE_VAULT = uint256(keccak256("BridgeVault"));
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address admin = vm.envOr("ADMIN", deployer);
|
||||
address policyManager = vm.envAddress("POLICY_MANAGER");
|
||||
address complianceRegistry = vm.envAddress("COMPLIANCE_REGISTRY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
CREATE2Factory factory = new CREATE2Factory();
|
||||
bytes memory bytecode = abi.encodePacked(
|
||||
type(BridgeVault138).creationCode,
|
||||
abi.encode(admin, policyManager, complianceRegistry)
|
||||
);
|
||||
address vaultAddr = factory.deploy(bytecode, SALT_BRIDGE_VAULT);
|
||||
console.log("BridgeVault138:", vaultAddr);
|
||||
console.log("CREATE2Factory:", address(factory));
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
57
script/deploy/DeployCWTokens.s.sol
Normal file
57
script/deploy/DeployCWTokens.s.sol
Normal file
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {CompliantWrappedToken} from "../../contracts/tokens/CompliantWrappedToken.sol";
|
||||
|
||||
/**
|
||||
* @title DeployCWTokens
|
||||
* @notice Deploy all cW* (CompliantWrappedToken) on the current chain; grant MINTER_ROLE and BURNER_ROLE to bridge.
|
||||
* @dev Run with --rpc-url <CHAIN_RPC> --chain-id <ID>. Set CW_BRIDGE_ADDRESS (or CCIP receiver) to receive MINTER_ROLE/BURNER_ROLE.
|
||||
*
|
||||
* Env:
|
||||
* PRIVATE_KEY (required)
|
||||
* CW_BRIDGE_ADDRESS (required) — address that can mint/burn (e.g. CCIP receiver or custom bridge)
|
||||
* DEPLOY_CWUSDT=1, DEPLOY_CWUSDC=1, DEPLOY_CWEURC=1, ... (default all 1; set 0 to skip a token)
|
||||
*/
|
||||
contract DeployCWTokens is Script {
|
||||
uint8 constant DECIMALS = 6;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address bridge = vm.envAddress("CW_BRIDGE_ADDRESS");
|
||||
require(bridge != address(0), "CW_BRIDGE_ADDRESS required");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
_deployOne(deployer, "Wrapped cUSDT", "cWUSDT", "DEPLOY_CWUSDT", bridge);
|
||||
_deployOne(deployer, "Wrapped cUSDC", "cWUSDC", "DEPLOY_CWUSDC", bridge);
|
||||
_deployOne(deployer, "Wrapped cEURC", "cWEURC", "DEPLOY_CWEURC", bridge);
|
||||
_deployOne(deployer, "Wrapped cEURT", "cWEURT", "DEPLOY_CWEURT", bridge);
|
||||
_deployOne(deployer, "Wrapped cGBPC", "cWGBPC", "DEPLOY_CWGBPC", bridge);
|
||||
_deployOne(deployer, "Wrapped cGBPT", "cWGBPT", "DEPLOY_CWGBPT", bridge);
|
||||
_deployOne(deployer, "Wrapped cAUDC", "cWAUDC", "DEPLOY_CWAUDC", bridge);
|
||||
_deployOne(deployer, "Wrapped cJPYC", "cWJPYC", "DEPLOY_CWJPYC", bridge);
|
||||
_deployOne(deployer, "Wrapped cCHFC", "cWCHFC", "DEPLOY_CWCHFC", bridge);
|
||||
_deployOne(deployer, "Wrapped cCADC", "cWCADC", "DEPLOY_CWCADC", bridge);
|
||||
_deployOne(deployer, "Wrapped cXAUC", "cWXAUC", "DEPLOY_CWXAUC", bridge);
|
||||
_deployOne(deployer, "Wrapped cXAUT", "cWXAUT", "DEPLOY_CWXAUT", bridge);
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _deployOne(
|
||||
address admin,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
string memory envKey,
|
||||
address bridge
|
||||
) internal {
|
||||
if (vm.envOr(envKey, uint256(1)) == 0) return;
|
||||
CompliantWrappedToken t = new CompliantWrappedToken(name, symbol, DECIMALS, admin);
|
||||
t.grantRole(t.MINTER_ROLE(), bridge);
|
||||
t.grantRole(t.BURNER_ROLE(), bridge);
|
||||
console.log(symbol, address(t));
|
||||
}
|
||||
}
|
||||
24
script/deploy/DeployChainRegistry.s.sol
Normal file
24
script/deploy/DeployChainRegistry.s.sol
Normal file
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
import "../../contracts/registry/ChainRegistry.sol";
|
||||
|
||||
contract DeployChainRegistry is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address admin = vm.addr(pk);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
ChainRegistry impl = new ChainRegistry();
|
||||
bytes memory initData = abi.encodeCall(ChainRegistry.initialize, (admin));
|
||||
ERC1967Proxy proxy = new ERC1967Proxy(address(impl), initData);
|
||||
address proxyAddr = address(proxy);
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("CHAIN_REGISTRY_ADDRESS_138=", proxyAddr);
|
||||
}
|
||||
}
|
||||
61
script/deploy/DeployCompliantFiatTokens.s.sol
Normal file
61
script/deploy/DeployCompliantFiatTokens.s.sol
Normal file
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {CREATE2Factory} from "../../contracts/utils/CREATE2Factory.sol";
|
||||
import {CompliantFiatToken} from "../../contracts/tokens/CompliantFiatToken.sol";
|
||||
|
||||
/**
|
||||
* @title DeployCompliantFiatTokens
|
||||
* @notice Deterministic deployment of CompliantFiatToken (cEURC, cEURT, cGBPC, cGBPT, cAUDC, cJPYC, cCHFC, cCADC, cXAUC, cXAUT; optional cCADT) via CREATE2.
|
||||
* @dev Use same ADMIN/OWNER and salts per chain for identical addresses. See docs/runbooks and TOKEN_SCOPE_GRU.md.
|
||||
*/
|
||||
contract DeployCompliantFiatTokens is Script {
|
||||
uint256 constant DECIMALS = 6;
|
||||
uint256 constant INITIAL_SUPPLY = 1_000_000 * 10**6; // 1M tokens
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("OWNER", deployer);
|
||||
address admin = vm.envOr("ADMIN", deployer);
|
||||
|
||||
address factoryAddr = vm.envAddress("CREATE2_FACTORY_ADDRESS");
|
||||
require(factoryAddr != address(0), "CREATE2_FACTORY_ADDRESS required");
|
||||
CREATE2Factory factory = CREATE2Factory(factoryAddr);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
_deploy(factory, owner, admin, "cEURC", "Euro Coin (Compliant)", "EUR");
|
||||
_deploy(factory, owner, admin, "cEURT", "Tether EUR (Compliant)", "EUR");
|
||||
_deploy(factory, owner, admin, "cGBPC", "Pound Sterling (Compliant)", "GBP");
|
||||
_deploy(factory, owner, admin, "cGBPT", "Tether GBP (Compliant)", "GBP");
|
||||
_deploy(factory, owner, admin, "cAUDC", "Australian Dollar (Compliant)", "AUD");
|
||||
_deploy(factory, owner, admin, "cJPYC", "Japanese Yen (Compliant)", "JPY");
|
||||
_deploy(factory, owner, admin, "cCHFC", "Swiss Franc (Compliant)", "CHF");
|
||||
_deploy(factory, owner, admin, "cCADC", "Canadian Dollar (Compliant)", "CAD");
|
||||
// Optional: Tether-style CAD (uncomment to deploy)
|
||||
// _deploy(factory, owner, admin, "cCADT", "Tether CAD (Compliant)", "CAD");
|
||||
_deploy(factory, owner, admin, "cXAUC", "Gold (Compliant)", "XAU");
|
||||
_deploy(factory, owner, admin, "cXAUT", "Tether XAU (Compliant)", "XAU");
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _deploy(
|
||||
CREATE2Factory factory,
|
||||
address owner,
|
||||
address admin,
|
||||
string memory symbol,
|
||||
string memory name,
|
||||
string memory currencyCode
|
||||
) internal {
|
||||
uint256 salt = uint256(keccak256(abi.encodePacked("CompliantFiatToken.", symbol)));
|
||||
bytes memory bytecode = abi.encodePacked(
|
||||
type(CompliantFiatToken).creationCode,
|
||||
abi.encode(name, symbol, uint8(DECIMALS), currencyCode, owner, admin, INITIAL_SUPPLY)
|
||||
);
|
||||
address addr = factory.deploy(bytecode, salt);
|
||||
console.log(symbol, addr);
|
||||
}
|
||||
}
|
||||
95
script/deploy/DeployCompliantFiatTokensForChain.s.sol
Normal file
95
script/deploy/DeployCompliantFiatTokensForChain.s.sol
Normal file
@@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {CompliantUSDT} from "../../contracts/tokens/CompliantUSDT.sol";
|
||||
import {CompliantUSDC} from "../../contracts/tokens/CompliantUSDC.sol";
|
||||
import {CompliantFiatToken} from "../../contracts/tokens/CompliantFiatToken.sol";
|
||||
|
||||
/**
|
||||
* @title DeployCompliantFiatTokensForChain
|
||||
* @notice Deploy compliant tokens (cUSDT, cUSDC, and optionally cEURC, etc.) to the current chain.
|
||||
* @dev Chain-agnostic: run with any RPC (--rpc-url <URL> --chain-id <ID>). Use when CUSDT_<CHAIN> / CUSDC_<CHAIN> are not set.
|
||||
* Owner/admin get mint; deployer is default owner. No CREATE2 required.
|
||||
*
|
||||
* Env:
|
||||
* PRIVATE_KEY (required)
|
||||
* OWNER, ADMIN (optional; default deployer)
|
||||
* DEPLOY_CUSDT=1, DEPLOY_CUSDC=1 (default both 1)
|
||||
* DEPLOY_CEURC=1, DEPLOY_CEURT=1, ... (optional; deploy extra CompliantFiatToken)
|
||||
*/
|
||||
contract DeployCompliantFiatTokensForChain is Script {
|
||||
uint256 constant DECIMALS = 6;
|
||||
uint256 constant INITIAL_SUPPLY = 1_000_000 * 10**6; // 1M
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("OWNER", deployer);
|
||||
address admin = vm.envOr("ADMIN", deployer);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
if (vm.envOr("DEPLOY_CUSDT", uint256(1)) != 0) {
|
||||
CompliantUSDT cusdt = new CompliantUSDT(owner, admin);
|
||||
console.log("cUSDT", address(cusdt));
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CUSDC", uint256(1)) != 0) {
|
||||
CompliantUSDC cusdc = new CompliantUSDC(owner, admin);
|
||||
console.log("cUSDC", address(cusdc));
|
||||
}
|
||||
|
||||
if (vm.envOr("DEPLOY_CEURC", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cEURC", "Euro Coin (Compliant)", "EUR");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CEURT", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cEURT", "Tether EUR (Compliant)", "EUR");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CGBPC", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cGBPC", "Pound Sterling (Compliant)", "GBP");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CGBPT", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cGBPT", "Tether GBP (Compliant)", "GBP");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CAUDC", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cAUDC", "Australian Dollar (Compliant)", "AUD");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CJPYC", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cJPYC", "Japanese Yen (Compliant)", "JPY");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CCHFC", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cCHFC", "Swiss Franc (Compliant)", "CHF");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CCADC", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cCADC", "Canadian Dollar (Compliant)", "CAD");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CXAUC", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cXAUC", "Gold (Compliant)", "XAU");
|
||||
}
|
||||
if (vm.envOr("DEPLOY_CXAUT", uint256(0)) != 0) {
|
||||
_deployFiat(owner, admin, "cXAUT", "Tether XAU (Compliant)", "XAU");
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _deployFiat(
|
||||
address owner,
|
||||
address admin,
|
||||
string memory symbol,
|
||||
string memory name,
|
||||
string memory currencyCode
|
||||
) internal {
|
||||
CompliantFiatToken t = new CompliantFiatToken(
|
||||
name,
|
||||
symbol,
|
||||
// forge-lint: disable-next-line(unsafe-typecast) -- DECIMALS is 6 or 18
|
||||
uint8(DECIMALS),
|
||||
currencyCode,
|
||||
owner,
|
||||
admin,
|
||||
INITIAL_SUPPLY
|
||||
);
|
||||
console.log(symbol, address(t));
|
||||
}
|
||||
}
|
||||
74
script/deploy/DeployDeterministicCore.s.sol
Normal file
74
script/deploy/DeployDeterministicCore.s.sol
Normal file
@@ -0,0 +1,74 @@
|
||||
// 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
|
||||
);
|
||||
}
|
||||
}
|
||||
49
script/deploy/RegisterGRUCompliantTokens.s.sol
Normal file
49
script/deploy/RegisterGRUCompliantTokens.s.sol
Normal file
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import {UniversalAssetRegistry} from "../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
|
||||
/**
|
||||
* @title RegisterGRUCompliantTokens
|
||||
* @notice Register all c* (GRU compliant) tokens in UniversalAssetRegistry as AssetType.GRU for bridge and pool integration.
|
||||
* @dev Run after deploying c* tokens. Uses registerGRUCompliantAsset (no timelock). Env: UNIVERSAL_ASSET_REGISTRY; optional per-token: CUSDT_ADDRESS_138, CUSDC_ADDRESS_138, CEURC_ADDRESS_138, etc.
|
||||
*/
|
||||
contract RegisterGRUCompliantTokens is Script {
|
||||
function run() external {
|
||||
address registryAddr = vm.envAddress("UNIVERSAL_ASSET_REGISTRY");
|
||||
UniversalAssetRegistry registry = UniversalAssetRegistry(registryAddr);
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
_register(registry, vm.envOr("CUSDT_ADDRESS_138", address(0)), "Tether USD (Compliant)", "cUSDT");
|
||||
_register(registry, vm.envOr("CUSDC_ADDRESS_138", address(0)), "USD Coin (Compliant)", "cUSDC");
|
||||
_register(registry, vm.envOr("CEURC_ADDRESS_138", address(0)), "Euro Coin (Compliant)", "cEURC");
|
||||
_register(registry, vm.envOr("CEURT_ADDRESS_138", address(0)), "Tether EUR (Compliant)", "cEURT");
|
||||
_register(registry, vm.envOr("CGBPC_ADDRESS_138", address(0)), "Pound Sterling (Compliant)", "cGBPC");
|
||||
_register(registry, vm.envOr("CGBPT_ADDRESS_138", address(0)), "Tether GBP (Compliant)", "cGBPT");
|
||||
_register(registry, vm.envOr("CAUDC_ADDRESS_138", address(0)), "Australian Dollar (Compliant)", "cAUDC");
|
||||
_register(registry, vm.envOr("CJPYC_ADDRESS_138", address(0)), "Japanese Yen (Compliant)", "cJPYC");
|
||||
_register(registry, vm.envOr("CCHFC_ADDRESS_138", address(0)), "Swiss Franc (Compliant)", "cCHFC");
|
||||
_register(registry, vm.envOr("CCADC_ADDRESS_138", address(0)), "Canadian Dollar (Compliant)", "cCADC");
|
||||
_register(registry, vm.envOr("CXAUC_ADDRESS_138", address(0)), "Gold (Compliant)", "cXAUC");
|
||||
_register(registry, vm.envOr("CXAUT_ADDRESS_138", address(0)), "Tether XAU (Compliant)", "cXAUT");
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _register(
|
||||
UniversalAssetRegistry registry,
|
||||
address tokenAddr,
|
||||
string memory name,
|
||||
string memory symbol
|
||||
) internal {
|
||||
if (tokenAddr == address(0)) return;
|
||||
if (registry.isAssetActive(tokenAddr)) {
|
||||
console.log("Skip (already registered):", symbol, vm.toString(tokenAddr));
|
||||
return;
|
||||
}
|
||||
registry.registerGRUCompliantAsset(tokenAddr, name, symbol, 6, "International");
|
||||
console.log("Registered GRU:", symbol, vm.toString(tokenAddr));
|
||||
}
|
||||
}
|
||||
29
script/deploy/UpgradeUniversalAssetRegistry.s.sol
Normal file
29
script/deploy/UpgradeUniversalAssetRegistry.s.sol
Normal file
@@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {UniversalAssetRegistry} from "../../contracts/registry/UniversalAssetRegistry.sol";
|
||||
|
||||
/**
|
||||
* @title UpgradeUniversalAssetRegistry
|
||||
* @notice Deploy a new UniversalAssetRegistry implementation and upgrade the proxy to it.
|
||||
* @dev Caller must have UPGRADER_ROLE on the proxy. Env: UNIVERSAL_ASSET_REGISTRY (proxy address), PRIVATE_KEY.
|
||||
* Use when the current implementation does not expose registerGRUCompliantAsset (e.g. older deployment).
|
||||
*/
|
||||
contract UpgradeUniversalAssetRegistry is Script {
|
||||
function run() external {
|
||||
address proxyAddr = vm.envAddress("UNIVERSAL_ASSET_REGISTRY");
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
UniversalAssetRegistry newImpl = new UniversalAssetRegistry();
|
||||
console.log("New implementation deployed at:", address(newImpl));
|
||||
|
||||
UniversalAssetRegistry proxy = UniversalAssetRegistry(proxyAddr);
|
||||
proxy.upgradeToAndCall(address(newImpl), "");
|
||||
console.log("Proxy", proxyAddr, "upgraded to", address(newImpl));
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
21
script/deploy/bridge/DeployEtherlinkRelayReceiver.s.sol
Normal file
21
script/deploy/bridge/DeployEtherlinkRelayReceiver.s.sol
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../../../contracts/bridge/EtherlinkRelayReceiver.sol";
|
||||
|
||||
/**
|
||||
* Deploy EtherlinkRelayReceiver on Etherlink (chain 42793).
|
||||
* Env: PRIVATE_KEY, ETHERLINK_RPC_URL (optional; --rpc-url overrides).
|
||||
* Run: forge script script/deploy/bridge/DeployEtherlinkRelayReceiver.s.sol --rpc-url $ETHERLINK_RPC_URL --broadcast
|
||||
*/
|
||||
contract DeployEtherlinkRelayReceiverScript is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
vm.startBroadcast(pk);
|
||||
EtherlinkRelayReceiver receiver = new EtherlinkRelayReceiver(deployer);
|
||||
vm.stopBroadcast();
|
||||
console.log("EtherlinkRelayReceiver deployed at:", address(receiver));
|
||||
}
|
||||
}
|
||||
96
script/deploy/bridge/DeployWETHBridges.s.sol
Normal file
96
script/deploy/bridge/DeployWETHBridges.s.sol
Normal file
@@ -0,0 +1,96 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {CCIPWETH9Bridge} from "../../../contracts/ccip/CCIPWETH9Bridge.sol";
|
||||
import {CCIPWETH10Bridge} from "../../../contracts/ccip/CCIPWETH10Bridge.sol";
|
||||
|
||||
/**
|
||||
* @title DeployWETHBridges
|
||||
* @notice Deployment script for WETH9 and WETH10 bridges to ChainID 138
|
||||
* @dev Deploys bridges with full interface including addDestination and getDestinationChains
|
||||
*/
|
||||
contract DeployWETHBridges is Script {
|
||||
CCIPWETH9Bridge public weth9Bridge;
|
||||
CCIPWETH10Bridge public weth10Bridge;
|
||||
|
||||
// Configuration
|
||||
address public admin;
|
||||
address public ccipRouter;
|
||||
address public weth9;
|
||||
address public weth10;
|
||||
address public linkToken;
|
||||
|
||||
// Mainnet configuration (checksummed addresses)
|
||||
uint64 public constant MAINNET_CHAIN_SELECTOR = 5009297550715157269;
|
||||
address public mainnetWeth9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
address public mainnetWeth10 = 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F;
|
||||
|
||||
function run() external {
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
admin = vm.addr(deployerPrivateKey);
|
||||
|
||||
// Get addresses from environment or use defaults (checksummed).
|
||||
// Default router: working CCIP router (0x8078A...) with code; do not use 0x80226... (no code).
|
||||
ccipRouter = vm.envOr("CCIP_ROUTER_ADDRESS", address(0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e));
|
||||
weth9 = vm.envOr("WETH9_ADDRESS", address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2));
|
||||
weth10 = vm.envOr("WETH10_ADDRESS", address(0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F));
|
||||
linkToken = vm.envOr("LINK_TOKEN_ADDRESS", address(0x514910771AF9Ca656af840dff83E8264EcF986CA));
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
console.log("=== Deploying WETH Bridges to ChainID 138 ===");
|
||||
console.log("Admin:", admin);
|
||||
console.log("CCIP Router:", ccipRouter);
|
||||
console.log("WETH9:", weth9);
|
||||
console.log("WETH10:", weth10);
|
||||
console.log("LINK Token:", linkToken);
|
||||
|
||||
// Deploy WETH9 Bridge (constructor: ccipRouter, weth9, feeToken)
|
||||
console.log("\n1. Deploying WETH9 Bridge...");
|
||||
weth9Bridge = new CCIPWETH9Bridge(ccipRouter, weth9, linkToken);
|
||||
console.log("WETH9 Bridge:", address(weth9Bridge));
|
||||
|
||||
// Deploy WETH10 Bridge (constructor: ccipRouter, weth10, feeToken)
|
||||
console.log("\n2. Deploying WETH10 Bridge...");
|
||||
weth10Bridge = new CCIPWETH10Bridge(ccipRouter, weth10, linkToken);
|
||||
console.log("WETH10 Bridge:", address(weth10Bridge));
|
||||
|
||||
// Configure Mainnet destination (addDestination: chainSelector, receiverBridge)
|
||||
address mainnetWeth9Receiver = vm.envOr("MAINNET_WETH9_BRIDGE_ADDRESS", address(0));
|
||||
address mainnetWeth10Receiver = vm.envOr("MAINNET_WETH10_BRIDGE_ADDRESS", address(0));
|
||||
if (mainnetWeth9Receiver != address(0)) {
|
||||
weth9Bridge.addDestination(MAINNET_CHAIN_SELECTOR, mainnetWeth9Receiver);
|
||||
console.log("WETH9 Bridge: Mainnet destination added");
|
||||
}
|
||||
if (mainnetWeth10Receiver != address(0)) {
|
||||
weth10Bridge.addDestination(MAINNET_CHAIN_SELECTOR, mainnetWeth10Receiver);
|
||||
console.log("WETH10 Bridge: Mainnet destination added");
|
||||
}
|
||||
|
||||
// Verify destinations (optional when MAINNET_*_BRIDGE_ADDRESS not set)
|
||||
console.log("\n4. Verifying destinations...");
|
||||
uint64[] memory weth9Chains = weth9Bridge.getDestinationChains();
|
||||
uint64[] memory weth10Chains = weth10Bridge.getDestinationChains();
|
||||
if (mainnetWeth9Receiver != address(0)) {
|
||||
require(weth9Chains.length == 1, "WETH9 should have 1 destination");
|
||||
require(weth9Chains[0] == MAINNET_CHAIN_SELECTOR, "WETH9 destination should be Mainnet");
|
||||
}
|
||||
if (mainnetWeth10Receiver != address(0)) {
|
||||
require(weth10Chains.length == 1, "WETH10 should have 1 destination");
|
||||
require(weth10Chains[0] == MAINNET_CHAIN_SELECTOR, "WETH10 destination should be Mainnet");
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("\n=== WETH Bridges Deployment Complete ===");
|
||||
console.log("Summary:");
|
||||
console.log(" WETH9 Bridge:", address(weth9Bridge));
|
||||
console.log(" WETH10 Bridge:", address(weth10Bridge));
|
||||
console.log(" Mainnet Chain Selector:", MAINNET_CHAIN_SELECTOR);
|
||||
console.log("\nNext Steps:");
|
||||
console.log(" 1. Fund bridges with LINK tokens for CCIP fees");
|
||||
console.log(" 2. Test bidirectional transfers");
|
||||
console.log(" 3. Monitor bridge activity");
|
||||
}
|
||||
}
|
||||
71
script/deploy/chains/DeployAllAdapters.s.sol
Normal file
71
script/deploy/chains/DeployAllAdapters.s.sol
Normal file
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../../../contracts/registry/ChainRegistry.sol";
|
||||
import "../../../contracts/bridge/adapters/evm/EVMAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/evm/XDCAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/evm/AlltraAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/non-evm/XRPLAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/non-evm/StellarAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/non-evm/TezosAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/hyperledger/FireflyAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/hyperledger/CactiAdapter.sol";
|
||||
import "../../../contracts/bridge/adapters/hyperledger/FabricAdapter.sol";
|
||||
|
||||
contract DeployAllAdapters is Script {
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address bridge = vm.envAddress("UNIVERSAL_BRIDGE_ADDRESS");
|
||||
address chainRegistry = vm.envAddress("CHAIN_REGISTRY_ADDRESS");
|
||||
|
||||
ChainRegistry registry = ChainRegistry(chainRegistry);
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
// Deploy EVM adapters
|
||||
EVMAdapter polygonAdapter = new EVMAdapter(deployer, bridge, 137, "Polygon");
|
||||
EVMAdapter arbitrumAdapter = new EVMAdapter(deployer, bridge, 42161, "Arbitrum");
|
||||
EVMAdapter optimismAdapter = new EVMAdapter(deployer, bridge, 10, "Optimism");
|
||||
EVMAdapter baseAdapter = new EVMAdapter(deployer, bridge, 8453, "Base");
|
||||
EVMAdapter avalancheAdapter = new EVMAdapter(deployer, bridge, 43114, "Avalanche");
|
||||
EVMAdapter bscAdapter = new EVMAdapter(deployer, bridge, 56, "BSC");
|
||||
EVMAdapter ethereumAdapter = new EVMAdapter(deployer, bridge, 1, "Ethereum Mainnet");
|
||||
EVMAdapter etherlinkAdapter = new EVMAdapter(deployer, bridge, 42793, "Etherlink Mainnet");
|
||||
XDCAdapter xdcAdapter = new XDCAdapter(deployer, bridge);
|
||||
AlltraAdapter alltraAdapter = new AlltraAdapter(deployer, bridge);
|
||||
|
||||
// Deploy non-EVM adapters
|
||||
XRPLAdapter xrplAdapter = new XRPLAdapter(deployer);
|
||||
StellarAdapter stellarAdapter = new StellarAdapter(deployer);
|
||||
TezosAdapter tezosAdapter = new TezosAdapter(deployer);
|
||||
|
||||
// Deploy Hyperledger adapters
|
||||
FireflyAdapter fireflyAdapter = new FireflyAdapter(deployer, "alltra-bridge");
|
||||
CactiAdapter cactiAdapter = new CactiAdapter(deployer, "http://192.168.11.177:4000/api/v1");
|
||||
FabricAdapter fabricAdapter = new FabricAdapter(deployer, "bridge-channel", "bridge");
|
||||
|
||||
// Register chains
|
||||
registry.registerEVMChain(137, address(polygonAdapter), "https://polygonscan.com", 12, 2, "");
|
||||
registry.registerEVMChain(42161, address(arbitrumAdapter), "https://arbiscan.io", 12, 1, "");
|
||||
registry.registerEVMChain(10, address(optimismAdapter), "https://optimistic.etherscan.io", 12, 2, "");
|
||||
registry.registerEVMChain(8453, address(baseAdapter), "https://basescan.org", 12, 2, "");
|
||||
registry.registerEVMChain(43114, address(avalancheAdapter), "https://snowtrace.io", 12, 1, "");
|
||||
registry.registerEVMChain(56, address(bscAdapter), "https://bscscan.com", 12, 3, "");
|
||||
registry.registerEVMChain(1, address(ethereumAdapter), "https://etherscan.io", 12, 12, "");
|
||||
registry.registerEVMChain(42793, address(etherlinkAdapter), "https://explorer.etherlink.com", 12, 2, "");
|
||||
registry.registerEVMChain(50, address(xdcAdapter), "https://explorer.xdc.network", 12, 2, "");
|
||||
|
||||
registry.registerNonEVMChain("XRPL-Mainnet", ChainRegistry.ChainType.XRPL, address(xrplAdapter), "https://xrpscan.com", 1, 4, true, "");
|
||||
registry.registerNonEVMChain("Stellar-Mainnet", ChainRegistry.ChainType.Stellar, address(stellarAdapter), "https://stellarchain.io", 1, 5, true, "");
|
||||
registry.registerNonEVMChain("Tezos-Mainnet", ChainRegistry.ChainType.Other, address(tezosAdapter), "https://tzkt.io", 1, 30, true, "");
|
||||
registry.registerNonEVMChain("Firefly-Orchestration", ChainRegistry.ChainType.Firefly, address(fireflyAdapter), "", 1, 1, true, "");
|
||||
registry.registerNonEVMChain("Cacti-Interoperability", ChainRegistry.ChainType.Cacti, address(cactiAdapter), "", 1, 1, true, "");
|
||||
registry.registerNonEVMChain("Fabric-bridge-channel", ChainRegistry.ChainType.Fabric, address(fabricAdapter), "", 1, 1, true, "");
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("All adapters deployed and registered!");
|
||||
}
|
||||
}
|
||||
226
script/deploy/iso4217w/DeployISO4217WSystem.s.sol
Normal file
226
script/deploy/iso4217w/DeployISO4217WSystem.s.sol
Normal file
@@ -0,0 +1,226 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../../../contracts/iso4217w/ComplianceGuard.sol";
|
||||
import "../../../contracts/iso4217w/oracle/ReserveOracle.sol";
|
||||
import "../../../contracts/iso4217w/controllers/MintController.sol";
|
||||
import "../../../contracts/iso4217w/controllers/BurnController.sol";
|
||||
import "../../../contracts/iso4217w/registry/TokenRegistry.sol";
|
||||
import "../../../contracts/iso4217w/TokenFactory.sol";
|
||||
import "../../../contracts/iso4217w/ISO4217WToken.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
|
||||
/**
|
||||
* @title DeployISO4217WSystem
|
||||
* @notice Deployment script for the complete ISO-4217W Token System
|
||||
* @dev Deploys all ISO-4217W system components and initializes W tokens
|
||||
*/
|
||||
contract DeployISO4217WSystem is Script {
|
||||
// Deployed contracts
|
||||
ComplianceGuard public complianceGuard;
|
||||
ReserveOracle public reserveOracle;
|
||||
MintController public mintController;
|
||||
BurnController public burnController;
|
||||
TokenRegistry public tokenRegistry;
|
||||
TokenFactory public tokenFactory;
|
||||
|
||||
// W Tokens
|
||||
ISO4217WToken public usdw;
|
||||
ISO4217WToken public eurw;
|
||||
ISO4217WToken public gbpw;
|
||||
ISO4217WToken public audw;
|
||||
ISO4217WToken public jpyw;
|
||||
ISO4217WToken public chfw;
|
||||
ISO4217WToken public cadw;
|
||||
|
||||
// Configuration
|
||||
address public admin;
|
||||
address public custodian;
|
||||
address public reserveManager;
|
||||
|
||||
// Reserve Oracle configuration
|
||||
address[] public reserveTransmitters;
|
||||
uint256 public constant QUORUM_THRESHOLD = 2; // Minimum 2 confirmations
|
||||
uint256 public constant STALENESS_THRESHOLD = 3600; // 1 hour
|
||||
|
||||
function run() external {
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
admin = vm.addr(deployerPrivateKey);
|
||||
custodian = vm.envOr("CUSTODIAN_ADDRESS", vm.addr(deployerPrivateKey));
|
||||
reserveManager = vm.envOr("RESERVE_MANAGER_ADDRESS", vm.addr(deployerPrivateKey));
|
||||
|
||||
// Reserve transmitters (oracle nodes)
|
||||
reserveTransmitters.push(vm.envOr("RESERVE_TRANSMITTER_1", vm.addr(deployerPrivateKey)));
|
||||
reserveTransmitters.push(vm.envOr("RESERVE_TRANSMITTER_2", vm.addr(deployerPrivateKey)));
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
console.log("=== Deploying ISO-4217W Token System ===");
|
||||
console.log("Admin:", admin);
|
||||
console.log("Custodian:", custodian);
|
||||
console.log("Reserve Manager:", reserveManager);
|
||||
|
||||
// Step 1: Deploy Compliance Guard
|
||||
console.log("\n1. Deploying Compliance Guard...");
|
||||
complianceGuard = new ComplianceGuard(admin);
|
||||
console.log("Compliance Guard:", address(complianceGuard));
|
||||
|
||||
// Step 2: Deploy Reserve Oracle
|
||||
console.log("\n2. Deploying Reserve Oracle...");
|
||||
reserveOracle = new ReserveOracle(admin, QUORUM_THRESHOLD, STALENESS_THRESHOLD);
|
||||
|
||||
// Add reserve oracles (transmitters)
|
||||
for (uint256 i = 0; i < reserveTransmitters.length; i++) {
|
||||
reserveOracle.addOracle(reserveTransmitters[i]);
|
||||
}
|
||||
console.log("Reserve Oracle:", address(reserveOracle));
|
||||
|
||||
// Step 3: Deploy Mint Controller
|
||||
console.log("\n3. Deploying Mint Controller...");
|
||||
mintController = new MintController(
|
||||
admin,
|
||||
address(complianceGuard),
|
||||
address(reserveOracle)
|
||||
);
|
||||
console.log("Mint Controller:", address(mintController));
|
||||
|
||||
// Step 4: Deploy Burn Controller (constructor: admin only)
|
||||
console.log("\n4. Deploying Burn Controller...");
|
||||
burnController = new BurnController(admin);
|
||||
console.log("Burn Controller:", address(burnController));
|
||||
|
||||
// Step 5: Deploy Token Registry
|
||||
console.log("\n5. Deploying Token Registry...");
|
||||
tokenRegistry = new TokenRegistry(admin);
|
||||
console.log("Token Registry:", address(tokenRegistry));
|
||||
|
||||
// Step 6: Deploy Token Factory (7 args: admin, implementation, registry, complianceGuard, reserveOracle, mintController, burnController)
|
||||
console.log("\n6. Deploying Token Factory...");
|
||||
ISO4217WToken tokenImplementation = new ISO4217WToken();
|
||||
tokenFactory = new TokenFactory(
|
||||
admin,
|
||||
address(tokenImplementation),
|
||||
address(tokenRegistry),
|
||||
address(complianceGuard),
|
||||
address(reserveOracle),
|
||||
address(mintController),
|
||||
address(burnController)
|
||||
);
|
||||
console.log("Token Factory:", address(tokenFactory));
|
||||
|
||||
// Grant factory role to register tokens
|
||||
tokenRegistry.grantRole(keccak256("REGISTRAR_ROLE"), address(tokenFactory));
|
||||
|
||||
// Step 7: Deploy W Tokens
|
||||
console.log("\n7. Deploying W Tokens...");
|
||||
|
||||
// Deploy USDW
|
||||
usdw = _deployWToken(
|
||||
"USDW Token",
|
||||
"USDW",
|
||||
"USD",
|
||||
2, // 2 decimals for USD
|
||||
custodian
|
||||
);
|
||||
console.log("USDW Token:", address(usdw));
|
||||
|
||||
// Deploy EURW
|
||||
eurw = _deployWToken(
|
||||
"EURW Token",
|
||||
"EURW",
|
||||
"EUR",
|
||||
2, // 2 decimals for EUR
|
||||
custodian
|
||||
);
|
||||
console.log("EURW Token:", address(eurw));
|
||||
|
||||
// Deploy GBPW
|
||||
gbpw = _deployWToken(
|
||||
"GBPW Token",
|
||||
"GBPW",
|
||||
"GBP",
|
||||
2, // 2 decimals for GBP
|
||||
custodian
|
||||
);
|
||||
console.log("GBPW Token:", address(gbpw));
|
||||
|
||||
audw = _deployWToken("AUDW Token", "AUDW", "AUD", 2, custodian);
|
||||
console.log("AUDW Token:", address(audw));
|
||||
jpyw = _deployWToken("JPYW Token", "JPYW", "JPY", 2, custodian);
|
||||
console.log("JPYW Token:", address(jpyw));
|
||||
chfw = _deployWToken("CHFW Token", "CHFW", "CHF", 2, custodian);
|
||||
console.log("CHFW Token:", address(chfw));
|
||||
cadw = _deployWToken("CADW Token", "CADW", "CAD", 2, custodian);
|
||||
console.log("CADW Token:", address(cadw));
|
||||
|
||||
// Step 8: Submit initial reserve reports (admin has ORACLE_ROLE)
|
||||
console.log("\n8. Submitting initial reserve reports...");
|
||||
reserveOracle.submitReserveReport("USD", 1000000e2, bytes32(0));
|
||||
reserveOracle.submitReserveReport("EUR", 500000e2, bytes32(0));
|
||||
reserveOracle.submitReserveReport("GBP", 500000e2, bytes32(0));
|
||||
reserveOracle.submitReserveReport("AUD", 500000e2, bytes32(0));
|
||||
reserveOracle.submitReserveReport("JPY", 50000000e2, bytes32(0));
|
||||
reserveOracle.submitReserveReport("CHF", 500000e2, bytes32(0));
|
||||
reserveOracle.submitReserveReport("CAD", 500000e2, bytes32(0));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("\n=== ISO-4217W Token System Deployment Complete ===");
|
||||
console.log("Summary:");
|
||||
console.log(" Compliance Guard:", address(complianceGuard));
|
||||
console.log(" Reserve Oracle:", address(reserveOracle));
|
||||
console.log(" Mint Controller:", address(mintController));
|
||||
console.log(" Burn Controller:", address(burnController));
|
||||
console.log(" Token Registry:", address(tokenRegistry));
|
||||
console.log(" Token Factory:", address(tokenFactory));
|
||||
console.log(" USDW Token:", address(usdw));
|
||||
console.log(" EURW Token:", address(eurw));
|
||||
console.log(" GBPW Token:", address(gbpw));
|
||||
console.log(" AUDW Token:", address(audw));
|
||||
console.log(" JPYW Token:", address(jpyw));
|
||||
console.log(" CHFW Token:", address(chfw));
|
||||
console.log(" CADW Token:", address(cadw));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Deploy a W token with proxy pattern
|
||||
*/
|
||||
function _deployWToken(
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
string memory currencyCode,
|
||||
uint8 decimals,
|
||||
address custodian_
|
||||
) internal returns (ISO4217WToken token) {
|
||||
// Deploy implementation
|
||||
ISO4217WToken implementation = new ISO4217WToken();
|
||||
|
||||
// Prepare initialization data
|
||||
bytes memory initData = abi.encodeWithSelector(
|
||||
ISO4217WToken.initialize.selector,
|
||||
name,
|
||||
symbol,
|
||||
currencyCode,
|
||||
decimals,
|
||||
custodian_,
|
||||
address(mintController),
|
||||
address(burnController),
|
||||
address(complianceGuard),
|
||||
admin
|
||||
);
|
||||
|
||||
// Deploy proxy
|
||||
ERC1967Proxy proxy = new ERC1967Proxy(address(implementation), initData);
|
||||
token = ISO4217WToken(address(proxy));
|
||||
|
||||
// Register token in registry (currencyCode, tokenAddress, tokenSymbol, decimals, custodian)
|
||||
tokenRegistry.registerToken(
|
||||
currencyCode,
|
||||
address(token),
|
||||
symbol,
|
||||
decimals,
|
||||
custodian_
|
||||
);
|
||||
}
|
||||
}
|
||||
79
script/deploy/vault/DeployAcVdcSdcVaults.s.sol
Normal file
79
script/deploy/vault/DeployAcVdcSdcVaults.s.sol
Normal file
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
|
||||
/**
|
||||
* @title DeployAcVdcSdcVaults
|
||||
* @notice Single script to create all ac* / vdc* / sdc* vaults via VaultFactory.createVaultWithDecimals.
|
||||
* @dev Run after DeployVaultSystem. Uses same owner/entity and base token addresses per chain for consistency.
|
||||
* See docs/runbooks/MULTI_CHAIN_EXECUTION_DETERMINISTIC_DEPLOYMENT.md (DepositToken/DebtToken).
|
||||
*
|
||||
* Env:
|
||||
* PRIVATE_KEY - Deployer (must have VAULT_DEPLOYER_ROLE on VaultFactory).
|
||||
* VAULT_FACTORY_ADDRESS - VaultFactory contract address.
|
||||
* OWNER - (optional) Vault owner; default deployer.
|
||||
* ENTITY - (optional) Regulated entity; default deployer.
|
||||
* CUSDC_ADDRESS_138 - (optional) Compliant USDC; if set, creates vault → acUSDC + vdcUSDC.
|
||||
* CUSDT_ADDRESS_138 - (optional) Compliant USDT; if set, creates vault → acUSDT + vdcUSDT.
|
||||
* COMPLIANT_USDC_ADDRESS, COMPLIANT_USDT_ADDRESS - Fallback env names if CUSDC/CUSDT_138 unset.
|
||||
*/
|
||||
contract DeployAcVdcSdcVaults is Script {
|
||||
uint8 constant DECIMALS = 6;
|
||||
bool constant DEBT_TRANSFERABLE = true;
|
||||
|
||||
function run() external {
|
||||
uint256 pk = vm.envUint("PRIVATE_KEY");
|
||||
address deployer = vm.addr(pk);
|
||||
address owner = vm.envOr("OWNER", deployer);
|
||||
address entity = vm.envOr("ENTITY", deployer);
|
||||
|
||||
address factoryAddr = vm.envAddress("VAULT_FACTORY_ADDRESS");
|
||||
require(factoryAddr != address(0), "VAULT_FACTORY_ADDRESS required");
|
||||
VaultFactory factory = VaultFactory(factoryAddr);
|
||||
|
||||
address cUsdc = _getToken("CUSDC_ADDRESS_138", "COMPLIANT_USDC_ADDRESS");
|
||||
address cUsdt = _getToken("CUSDT_ADDRESS_138", "COMPLIANT_USDT_ADDRESS");
|
||||
|
||||
vm.startBroadcast(pk);
|
||||
|
||||
if (cUsdc != address(0)) {
|
||||
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimals(
|
||||
owner,
|
||||
entity,
|
||||
cUsdc,
|
||||
cUsdc,
|
||||
DECIMALS,
|
||||
DECIMALS,
|
||||
DEBT_TRANSFERABLE
|
||||
);
|
||||
console.log("USDC vault:", vault);
|
||||
console.log("acUSDC (deposit):", depositToken);
|
||||
console.log("vdcUSDC (debt):", debtToken);
|
||||
}
|
||||
|
||||
if (cUsdt != address(0)) {
|
||||
(address vault, address depositToken, address debtToken) = factory.createVaultWithDecimals(
|
||||
owner,
|
||||
entity,
|
||||
cUsdt,
|
||||
cUsdt,
|
||||
DECIMALS,
|
||||
DECIMALS,
|
||||
DEBT_TRANSFERABLE
|
||||
);
|
||||
console.log("USDT vault:", vault);
|
||||
console.log("acUSDT (deposit):", depositToken);
|
||||
console.log("vdcUSDT (debt):", debtToken);
|
||||
}
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function _getToken(string memory primary, string memory altKey) internal view returns (address) {
|
||||
address a = vm.envOr(primary, address(0));
|
||||
if (a != address(0)) return a;
|
||||
return vm.envOr(altKey, address(0));
|
||||
}
|
||||
}
|
||||
164
script/deploy/vault/DeployVaultSystem.s.sol
Normal file
164
script/deploy/vault/DeployVaultSystem.s.sol
Normal file
@@ -0,0 +1,164 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {Script, console} from "forge-std/Script.sol";
|
||||
import {Ledger} from "../../../contracts/vault/Ledger.sol";
|
||||
import {RegulatedEntityRegistry} from "../../../contracts/vault/RegulatedEntityRegistry.sol";
|
||||
import {XAUOracle} from "../../../contracts/vault/XAUOracle.sol";
|
||||
import {RateAccrual} from "../../../contracts/vault/RateAccrual.sol";
|
||||
import {Liquidation} from "../../../contracts/vault/Liquidation.sol";
|
||||
import {CollateralAdapter} from "../../../contracts/vault/adapters/CollateralAdapter.sol";
|
||||
import {eMoneyJoin} from "../../../contracts/vault/adapters/eMoneyJoin.sol";
|
||||
import {Vault} from "../../../contracts/vault/Vault.sol";
|
||||
import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol";
|
||||
import {DepositToken} from "../../../contracts/vault/tokens/DepositToken.sol";
|
||||
import {DebtToken} from "../../../contracts/vault/tokens/DebtToken.sol";
|
||||
import {Aggregator} from "../../../contracts/oracle/Aggregator.sol";
|
||||
|
||||
/**
|
||||
* @title DeployVaultSystem
|
||||
* @notice Deployment script for the complete Vault System
|
||||
* @dev Deploys all vault system components in the correct order
|
||||
*/
|
||||
contract DeployVaultSystem is Script {
|
||||
// Deployed contracts
|
||||
RegulatedEntityRegistry public entityRegistry;
|
||||
Aggregator public ethPriceFeed;
|
||||
Aggregator public btcPriceFeed;
|
||||
XAUOracle public xauOracle;
|
||||
RateAccrual public rateAccrual;
|
||||
Ledger public ledger;
|
||||
Liquidation public liquidation;
|
||||
CollateralAdapter public collateralAdapter;
|
||||
eMoneyJoin public eMoneyJoinContract;
|
||||
VaultFactory public vaultFactory;
|
||||
|
||||
// Configuration
|
||||
address public admin;
|
||||
address public treasury; // Treasury address for liquidation proceeds
|
||||
address public ethAddress = address(0); // Native ETH
|
||||
address public btcAddress; // BTC token address (set in constructor or env)
|
||||
|
||||
// Risk parameters (basis points; Ledger requires liquidationRatio <= 10000)
|
||||
uint256 public constant DEFAULT_LIQUIDATION_RATIO = 10000; // 100%
|
||||
uint256 public constant DEFAULT_CREDIT_MULTIPLIER = 50000; // 5x
|
||||
uint256 public constant DEFAULT_DEBT_CEILING = 1000000e18; // 1M tokens
|
||||
|
||||
function run() external {
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
admin = vm.addr(deployerPrivateKey);
|
||||
treasury = vm.envOr("TREASURY_ADDRESS", vm.addr(deployerPrivateKey));
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
console.log("=== Deploying Vault System ===");
|
||||
console.log("Admin:", admin);
|
||||
console.log("Treasury:", treasury);
|
||||
|
||||
// Step 1: Deploy Regulated Entity Registry
|
||||
console.log("\n1. Deploying Regulated Entity Registry...");
|
||||
entityRegistry = new RegulatedEntityRegistry(admin);
|
||||
console.log("RegulatedEntityRegistry:", address(entityRegistry));
|
||||
|
||||
// Step 2: Deploy Price Feeds
|
||||
console.log("\n2. Deploying Price Feeds...");
|
||||
ethPriceFeed = new Aggregator("ETH/XAU", admin, 3600, 50);
|
||||
ethPriceFeed.addTransmitter(admin);
|
||||
ethPriceFeed.updateAnswer(0.05e18); // 1 ETH = 0.05 oz XAU (example)
|
||||
console.log("ETH Price Feed:", address(ethPriceFeed));
|
||||
|
||||
btcPriceFeed = new Aggregator("BTC/XAU", admin, 3600, 50);
|
||||
btcPriceFeed.addTransmitter(admin);
|
||||
btcPriceFeed.updateAnswer(0.5e18); // 1 BTC = 0.5 oz XAU (example)
|
||||
console.log("BTC Price Feed:", address(btcPriceFeed));
|
||||
|
||||
// Step 3: Deploy XAU Oracle
|
||||
console.log("\n3. Deploying XAU Oracle...");
|
||||
xauOracle = new XAUOracle(admin);
|
||||
xauOracle.addPriceFeed(address(ethPriceFeed), 10000); // 100% weight
|
||||
xauOracle.addPriceFeed(address(btcPriceFeed), 10000); // 100% weight
|
||||
xauOracle.updatePrice();
|
||||
console.log("XAU Oracle:", address(xauOracle));
|
||||
|
||||
// Step 4: Deploy Rate Accrual
|
||||
console.log("\n4. Deploying Rate Accrual...");
|
||||
rateAccrual = new RateAccrual(admin);
|
||||
rateAccrual.setInterestRate(address(0), 500); // 5% annual
|
||||
console.log("Rate Accrual:", address(rateAccrual));
|
||||
|
||||
// Step 5: Deploy Ledger
|
||||
console.log("\n5. Deploying Ledger...");
|
||||
ledger = new Ledger(admin, address(xauOracle), address(rateAccrual));
|
||||
console.log("Ledger:", address(ledger));
|
||||
|
||||
// Step 6: Deploy Liquidation Module
|
||||
console.log("\n6. Deploying Liquidation Module...");
|
||||
liquidation = new Liquidation(admin, address(ledger), address(xauOracle), treasury);
|
||||
console.log("Liquidation:", address(liquidation));
|
||||
|
||||
// Step 7: Deploy Collateral Adapter (constructor: admin, ledger)
|
||||
console.log("\n7. Deploying Collateral Adapter...");
|
||||
collateralAdapter = new CollateralAdapter(admin, address(ledger));
|
||||
console.log("Collateral Adapter:", address(collateralAdapter));
|
||||
|
||||
// Step 8: Deploy eMoney Join Adapter (constructor: admin only)
|
||||
console.log("\n8. Deploying eMoney Join Adapter...");
|
||||
eMoneyJoinContract = new eMoneyJoin(admin);
|
||||
console.log("eMoney Join:", address(eMoneyJoinContract));
|
||||
|
||||
// Step 9: Deploy Vault Factory (constructor: admin, vaultImpl, depositTokenImpl, debtTokenImpl, ledger, entityRegistry, collateralAdapter, eMoneyJoin)
|
||||
console.log("\n9. Deploying Vault Factory...");
|
||||
Vault vaultImpl = new Vault(admin, admin, address(ledger), address(entityRegistry), address(collateralAdapter), address(eMoneyJoinContract));
|
||||
DepositToken depositTokenImpl = new DepositToken();
|
||||
DebtToken debtTokenImpl = new DebtToken();
|
||||
vaultFactory = new VaultFactory(
|
||||
admin,
|
||||
address(vaultImpl),
|
||||
address(depositTokenImpl),
|
||||
address(debtTokenImpl),
|
||||
address(ledger),
|
||||
address(entityRegistry),
|
||||
address(collateralAdapter),
|
||||
address(eMoneyJoinContract)
|
||||
);
|
||||
console.log("Vault Factory:", address(vaultFactory));
|
||||
|
||||
// Step 10: Grant roles and configure
|
||||
console.log("\n10. Configuring roles and parameters...");
|
||||
|
||||
// Grant factory vault role
|
||||
ledger.grantVaultRole(address(vaultFactory));
|
||||
|
||||
// Set risk parameters (registers assets and sets params)
|
||||
ledger.setRiskParameters(
|
||||
ethAddress,
|
||||
DEFAULT_DEBT_CEILING,
|
||||
DEFAULT_LIQUIDATION_RATIO,
|
||||
DEFAULT_CREDIT_MULTIPLIER
|
||||
);
|
||||
if (btcAddress != address(0)) {
|
||||
ledger.setRiskParameters(
|
||||
btcAddress,
|
||||
DEFAULT_DEBT_CEILING,
|
||||
DEFAULT_LIQUIDATION_RATIO,
|
||||
DEFAULT_CREDIT_MULTIPLIER
|
||||
);
|
||||
}
|
||||
|
||||
// Grant factory role to create vaults
|
||||
entityRegistry.grantRole(keccak256("ENTITY_REGISTRAR_ROLE"), address(vaultFactory));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
||||
console.log("\n=== Vault System Deployment Complete ===");
|
||||
console.log("Summary:");
|
||||
console.log(" RegulatedEntityRegistry:", address(entityRegistry));
|
||||
console.log(" XAU Oracle:", address(xauOracle));
|
||||
console.log(" Rate Accrual:", address(rateAccrual));
|
||||
console.log(" Ledger:", address(ledger));
|
||||
console.log(" Liquidation:", address(liquidation));
|
||||
console.log(" Collateral Adapter:", address(collateralAdapter));
|
||||
console.log(" eMoney Join:", address(eMoneyJoinContract));
|
||||
console.log(" Vault Factory:", address(vaultFactory));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user