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