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