chore: sync submodule state (parent ref update)

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-02 12:14:09 -08:00
parent 50ab378da9
commit 5efe36b1e0
1100 changed files with 155024 additions and 8674 deletions

View File

@@ -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));

View File

@@ -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);
}
}

View 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();
}
}

View 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));
}
}

View 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);
}
}

View 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);
}
}

View 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));
}
}

View 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
);
}
}

View 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));
}
}

View 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();
}
}

View 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));
}
}

View 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");
}
}

View 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!");
}
}

View 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_
);
}
}

View 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));
}
}

View 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));
}
}