// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Script, console} from "forge-std/Script.sol"; import {CompliantCWUSDCTokenV2} from "../../contracts/tokens/CompliantCWUSDCTokenV2.sol"; import {CompliantCWUSDTTokenV2} from "../../contracts/tokens/CompliantCWUSDTTokenV2.sol"; import {CompliantFiatTokenV2} from "../../contracts/tokens/CompliantFiatTokenV2.sol"; /** * @title DeployCWTransportFiatTokensV2ForChain * @notice Deploy ERC-3009-capable cWUSDC / cWUSDT transport on a public EVM chain (Base, Polygon, …). * * Env: * PRIVATE_KEY (required) * CW_BRIDGE_ADDRESS (required) — L2 bridge receiver with MINTER/BURNER * INITIAL_OPERATOR (optional; default deployer) * ADMIN / OWNER (optional; default deployer) * INITIAL_SUPPLY (optional; default 0 — bridge mints) * FORWARD_CANONICAL (optional; default false for transport) * CW_TRANSPORT_STRICT_MODE (optional; default 1 — revoke deployer mint/burn after bridge grant) * DEPLOY_CWUSDT_V2=1 / DEPLOY_CWUSDC_V2=1 (default both 1) */ contract DeployCWTransportFiatTokensV2ForChain is Script { function run() external { uint256 pk = vm.envUint("PRIVATE_KEY"); address deployer = vm.addr(pk); address bridge = vm.envAddress("CW_BRIDGE_ADDRESS"); address initialOperator = vm.envOr("INITIAL_OPERATOR", deployer); address ownerAlias = vm.envOr("OWNER", deployer); address admin = vm.envOr("ADMIN", ownerAlias); uint256 initialSupply = vm.envOr("INITIAL_SUPPLY", uint256(0)); bool forwardCanonical = vm.envOr("FORWARD_CANONICAL", false); bool strictMode = vm.envOr("CW_TRANSPORT_STRICT_MODE", uint256(1)) != 0; require(bridge != address(0), "CW_BRIDGE_ADDRESS required"); vm.startBroadcast(pk); if (vm.envOr("DEPLOY_CWUSDT_V2", uint256(1)) != 0) { CompliantCWUSDTTokenV2 token = new CompliantCWUSDTTokenV2(initialOperator, admin, initialSupply, forwardCanonical); _wireBridge(address(token), bridge, admin, strictMode); console.log("cWUSDT_V2", address(token)); console.log("cWUSDT_V2_bridge", bridge); } if (vm.envOr("DEPLOY_CWUSDC_V2", uint256(1)) != 0) { CompliantCWUSDCTokenV2 token = new CompliantCWUSDCTokenV2(initialOperator, admin, initialSupply, forwardCanonical); _wireBridge(address(token), bridge, admin, strictMode); console.log("cWUSDC_V2", address(token)); console.log("cWUSDC_V2_bridge", bridge); } vm.stopBroadcast(); } function _wireBridge(address token, address bridge, address admin, bool strictMode) internal { CompliantFiatTokenV2 t = CompliantFiatTokenV2(token); t.grantRole(t.MINTER_ROLE(), bridge); t.grantRole(t.BURNER_ROLE(), bridge); if (strictMode) { t.revokeRole(t.MINTER_ROLE(), admin); t.revokeRole(t.BURNER_ROLE(), admin); } } }