From 893b98842c0a2faf3d26f77b16844d76c3e830ec Mon Sep 17 00:00:00 2001 From: typicalHuman Date: Wed, 15 Oct 2025 17:27:47 +0500 Subject: [PATCH] Refactor Foundry scripts: unify multichain CCIP bridging into single script call Updated Foundry scripts for the CCIP bridging infrastructure to execute multichain logic within a single script call, instead of invoking one script per chain. This improves efficiency, simplifies orchestration, and reduces redundant code paths between chain deployments. --- ccip/cct/foundry/deployments.toml | 5 ++ ccip/cct/foundry/lib/forge-std | 2 +- ccip/cct/foundry/script/AcceptAdminRole.s.sol | 48 +++++++++-- .../foundry/script/ApplyChainUpdates.s.sol | 83 +++++++++++++++---- ccip/cct/foundry/script/ClaimAdmin.s.sol | 75 ++++++++++++----- .../script/DeployBurnMintTokenPool.s.sol | 62 +++++++++++--- .../script/DeployLockReleaseTokenPool.s.sol | 65 ++++++++++++--- ccip/cct/foundry/script/DeployToken.s.sol | 70 +++++++++++++--- ccip/cct/foundry/script/SetPool.s.sol | 57 ++++++++++--- 9 files changed, 372 insertions(+), 95 deletions(-) create mode 100644 ccip/cct/foundry/deployments.toml diff --git a/ccip/cct/foundry/deployments.toml b/ccip/cct/foundry/deployments.toml new file mode 100644 index 00000000..0f45a2c8 --- /dev/null +++ b/ccip/cct/foundry/deployments.toml @@ -0,0 +1,5 @@ +[avalanche-fuji] +endpoint_url = "${RPC_URL_FUJI}" + +[arbitrum-sepolia] +endpoint_url = "${RPC_URL_ARBITRUM_SEPOLIA}" \ No newline at end of file diff --git a/ccip/cct/foundry/lib/forge-std b/ccip/cct/foundry/lib/forge-std index 1eea5bae..b8f065fd 160000 --- a/ccip/cct/foundry/lib/forge-std +++ b/ccip/cct/foundry/lib/forge-std @@ -1 +1 @@ -Subproject commit 1eea5bae12ae557d589f9f0f0edae2faa47cb262 +Subproject commit b8f065fda83b8cd94a6b2fec8fcd911dc3b444fd diff --git a/ccip/cct/foundry/script/AcceptAdminRole.s.sol b/ccip/cct/foundry/script/AcceptAdminRole.s.sol index 22b125d2..3ee5d20a 100644 --- a/ccip/cct/foundry/script/AcceptAdminRole.s.sol +++ b/ccip/cct/foundry/script/AcceptAdminRole.s.sol @@ -2,30 +2,52 @@ pragma solidity 0.8.24; import {Script, console} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; import {HelperUtils} from "./utils/HelperUtils.s.sol"; // Utility functions for JSON parsing and chain info import {HelperConfig} from "./HelperConfig.s.sol"; // Network configuration helper import {TokenAdminRegistry} from "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/TokenAdminRegistry.sol"; -contract AcceptAdminRole is Script { +contract AcceptAdminRole is Script, Config { function run() external { + _loadConfigAndForks("./deployments.toml", true); + for (uint256 i = 0; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + deployToChain(chainId); + } + } + + function deployToChain(uint256 chainId) internal { + vm.selectFork(forkOf[chainId]); // Get the chain name based on the current chain ID string memory chainName = HelperUtils.getChainName(block.chainid); // Construct the path to the deployed token JSON file string memory root = vm.projectRoot(); - string memory deployedTokenPath = string.concat(root, "/script/output/deployedToken_", chainName, ".json"); + string memory deployedTokenPath = string.concat( + root, + "/script/output/deployedToken_", + chainName, + ".json" + ); // Extract the deployed token address from the JSON file - address tokenAddress = - HelperUtils.getAddressFromJson(vm, deployedTokenPath, string.concat(".deployedToken_", chainName)); + address tokenAddress = HelperUtils.getAddressFromJson( + vm, + deployedTokenPath, + string.concat(".deployedToken_", chainName) + ); // Fetch the network configuration to get the TokenAdminRegistry address HelperConfig helperConfig = new HelperConfig(); - (,,, address tokenAdminRegistry,,,,) = helperConfig.activeNetworkConfig(); + (, , , address tokenAdminRegistry, , , , ) = helperConfig + .activeNetworkConfig(); // Ensure the token address and TokenAdminRegistry address are valid require(tokenAddress != address(0), "Invalid token address"); - require(tokenAdminRegistry != address(0), "TokenAdminRegistry is not defined for this network"); + require( + tokenAdminRegistry != address(0), + "TokenAdminRegistry is not defined for this network" + ); vm.startBroadcast(); @@ -33,16 +55,24 @@ contract AcceptAdminRole is Script { address signer = msg.sender; // Instantiate the TokenAdminRegistry contract - TokenAdminRegistry tokenAdminRegistryContract = TokenAdminRegistry(tokenAdminRegistry); + TokenAdminRegistry tokenAdminRegistryContract = TokenAdminRegistry( + tokenAdminRegistry + ); // Fetch the token configuration for the given token address - TokenAdminRegistry.TokenConfig memory tokenConfig = tokenAdminRegistryContract.getTokenConfig(tokenAddress); + TokenAdminRegistry.TokenConfig + memory tokenConfig = tokenAdminRegistryContract.getTokenConfig( + tokenAddress + ); // Get the pending administrator for the token address pendingAdministrator = tokenConfig.pendingAdministrator; // Ensure the signer is the pending administrator - require(pendingAdministrator == signer, "Only the pending administrator can accept the admin role"); + require( + pendingAdministrator == signer, + "Only the pending administrator can accept the admin role" + ); // Accept the admin role for the token tokenAdminRegistryContract.acceptAdminRole(tokenAddress); diff --git a/ccip/cct/foundry/script/ApplyChainUpdates.s.sol b/ccip/cct/foundry/script/ApplyChainUpdates.s.sol index 8769e8ff..12c093a7 100644 --- a/ccip/cct/foundry/script/ApplyChainUpdates.s.sol +++ b/ccip/cct/foundry/script/ApplyChainUpdates.s.sol @@ -2,39 +2,77 @@ pragma solidity 0.8.24; import {Script, console} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; import {HelperUtils} from "./utils/HelperUtils.s.sol"; // Utility functions for JSON parsing and chain info import {HelperConfig} from "./HelperConfig.s.sol"; // Network configuration helper import {TokenPool} from "@chainlink/contracts-ccip/contracts/pools/TokenPool.sol"; import {RateLimiter} from "@chainlink/contracts-ccip/contracts/libraries/RateLimiter.sol"; -contract ApplyChainUpdates is Script { +contract ApplyChainUpdates is Script, Config { function run() external { + _loadConfigAndForks("./deployments.toml", true); + for (uint256 i = 0; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + deployToChain(chainId); + } + } + + function deployToChain(uint256 chainId) internal { + vm.selectFork(forkOf[chainId]); // Get the current chain name based on the chain ID string memory chainName = HelperUtils.getChainName(block.chainid); // Construct paths to the configuration and local pool JSON files string memory root = vm.projectRoot(); string memory configPath = string.concat(root, "/script/config.json"); - string memory localPoolPath = string.concat(root, "/script/output/deployedTokenPool_", chainName, ".json"); + string memory localPoolPath = string.concat( + root, + "/script/output/deployedTokenPool_", + chainName, + ".json" + ); // Read the remoteChainId from config.json based on the current chain ID uint256 remoteChainId = HelperUtils.getUintFromJson( - vm, configPath, string.concat(".remoteChains.", HelperUtils.uintToStr(block.chainid)) + vm, + configPath, + string.concat( + ".remoteChains.", + HelperUtils.uintToStr(block.chainid) + ) ); // Get the remote chain name based on the remoteChainId string memory remoteChainName = HelperUtils.getChainName(remoteChainId); - string memory remotePoolPath = - string.concat(root, "/script/output/deployedTokenPool_", remoteChainName, ".json"); - string memory remoteTokenPath = string.concat(root, "/script/output/deployedToken_", remoteChainName, ".json"); + string memory remotePoolPath = string.concat( + root, + "/script/output/deployedTokenPool_", + remoteChainName, + ".json" + ); + string memory remoteTokenPath = string.concat( + root, + "/script/output/deployedToken_", + remoteChainName, + ".json" + ); // Extract addresses from the JSON files - address poolAddress = - HelperUtils.getAddressFromJson(vm, localPoolPath, string.concat(".deployedTokenPool_", chainName)); - address remotePoolAddress = - HelperUtils.getAddressFromJson(vm, remotePoolPath, string.concat(".deployedTokenPool_", remoteChainName)); - address remoteTokenAddress = - HelperUtils.getAddressFromJson(vm, remoteTokenPath, string.concat(".deployedToken_", remoteChainName)); + address poolAddress = HelperUtils.getAddressFromJson( + vm, + localPoolPath, + string.concat(".deployedTokenPool_", chainName) + ); + address remotePoolAddress = HelperUtils.getAddressFromJson( + vm, + remotePoolPath, + string.concat(".deployedTokenPool_", remoteChainName) + ); + address remoteTokenAddress = HelperUtils.getAddressFromJson( + vm, + remoteTokenPath, + string.concat(".deployedToken_", remoteChainName) + ); // For remotePoolAddresses, create an array with the remotePoolAddress address[] memory remotePoolAddresses = new address[](1); @@ -42,15 +80,21 @@ contract ApplyChainUpdates is Script { // Fetch the remote network configuration to get the chain selector HelperConfig helperConfig = new HelperConfig(); - HelperConfig.NetworkConfig memory remoteNetworkConfig = - HelperUtils.getNetworkConfig(helperConfig, remoteChainId); + HelperConfig.NetworkConfig memory remoteNetworkConfig = HelperUtils + .getNetworkConfig(helperConfig, remoteChainId); uint64 remoteChainSelector = remoteNetworkConfig.chainSelector; require(poolAddress != address(0), "Invalid pool address"); require(remotePoolAddress != address(0), "Invalid remote pool address"); - require(remoteTokenAddress != address(0), "Invalid remote token address"); - require(remoteChainSelector != 0, "chainSelector is not defined for the remote chain"); + require( + remoteTokenAddress != address(0), + "Invalid remote token address" + ); + require( + remoteChainSelector != 0, + "chainSelector is not defined for the remote chain" + ); vm.startBroadcast(); @@ -58,10 +102,13 @@ contract ApplyChainUpdates is Script { TokenPool poolContract = TokenPool(poolAddress); // Prepare chain update data for configuring cross-chain transfers - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + TokenPool.ChainUpdate[] + memory chainUpdates = new TokenPool.ChainUpdate[](1); // Encode remote pool addresses - bytes[] memory remotePoolAddressesEncoded = new bytes[](remotePoolAddresses.length); + bytes[] memory remotePoolAddressesEncoded = new bytes[]( + remotePoolAddresses.length + ); for (uint256 i = 0; i < remotePoolAddresses.length; i++) { remotePoolAddressesEncoded[i] = abi.encode(remotePoolAddresses[i]); } diff --git a/ccip/cct/foundry/script/ClaimAdmin.s.sol b/ccip/cct/foundry/script/ClaimAdmin.s.sol index f8e7a3da..b26776ca 100644 --- a/ccip/cct/foundry/script/ClaimAdmin.s.sol +++ b/ccip/cct/foundry/script/ClaimAdmin.s.sol @@ -2,50 +2,82 @@ pragma solidity 0.8.24; import {Script, console} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; import {HelperUtils} from "./utils/HelperUtils.s.sol"; // Utility functions for JSON parsing and chain info import {HelperConfig} from "./HelperConfig.s.sol"; // Network configuration helper -import {RegistryModuleOwnerCustom} from - "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/RegistryModuleOwnerCustom.sol"; +import {RegistryModuleOwnerCustom} from "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/RegistryModuleOwnerCustom.sol"; import {BurnMintERC20} from "@chainlink/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol"; - -contract ClaimAdmin is Script { +contract ClaimAdmin is Script, Config { function run() external { + _loadConfigAndForks("./deployments.toml", true); + for (uint256 i = 0; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + deployToChain(chainId); + } + } + + function deployToChain(uint256 chainId) internal { + vm.selectFork(forkOf[chainId]); // Get the chain name based on the current chain ID string memory chainName = HelperUtils.getChainName(block.chainid); // Define paths to the necessary JSON files string memory root = vm.projectRoot(); - string memory deployedTokenPath = string.concat(root, "/script/output/deployedToken_", chainName, ".json"); + string memory deployedTokenPath = string.concat( + root, + "/script/output/deployedToken_", + chainName, + ".json" + ); string memory configPath = string.concat(root, "/script/config.json"); // Extract values from the JSON files - address tokenAddress = - HelperUtils.getAddressFromJson(vm, deployedTokenPath, string.concat(".deployedToken_", chainName)); - address tokenAdmin = HelperUtils.getAddressFromJson(vm, configPath, ".BnMToken.ccipAdminAddress"); + address tokenAddress = HelperUtils.getAddressFromJson( + vm, + deployedTokenPath, + string.concat(".deployedToken_", chainName) + ); + address tokenAdmin = HelperUtils.getAddressFromJson( + vm, + configPath, + ".BnMToken.ccipAdminAddress" + ); // Fetch the network configuration HelperConfig helperConfig = new HelperConfig(); - (,,,, address registryModuleOwnerCustom,,,) = helperConfig.activeNetworkConfig(); + (, , , , address registryModuleOwnerCustom, , , ) = helperConfig + .activeNetworkConfig(); require(tokenAddress != address(0), "Invalid token address"); - require(registryModuleOwnerCustom != address(0), "Registry module owner custom is not defined for this network"); + require( + registryModuleOwnerCustom != address(0), + "Registry module owner custom is not defined for this network" + ); vm.startBroadcast(); - - claimAdminWithCCIPAdmin(tokenAddress, tokenAdmin, registryModuleOwnerCustom); - + + claimAdminWithCCIPAdmin( + tokenAddress, + tokenAdmin, + registryModuleOwnerCustom + ); + vm.stopBroadcast(); } // Claim admin role using the token's CCIP admin - function claimAdminWithCCIPAdmin(address tokenAddress, address tokenAdmin, address registryModuleOwnerCustom) - internal - { + function claimAdminWithCCIPAdmin( + address tokenAddress, + address tokenAdmin, + address registryModuleOwnerCustom + ) internal { // Instantiate the token contract with CCIP admin functionality BurnMintERC20 tokenContract = BurnMintERC20(tokenAddress); // Instantiate the registry contract - RegistryModuleOwnerCustom registryContract = RegistryModuleOwnerCustom(registryModuleOwnerCustom); + RegistryModuleOwnerCustom registryContract = RegistryModuleOwnerCustom( + registryModuleOwnerCustom + ); // Get the current CCIP admin of the token address tokenContractCCIPAdmin = tokenContract.getCCIPAdmin(); @@ -53,13 +85,16 @@ contract ClaimAdmin is Script { // Ensure the CCIP admin matches the expected token admin address require( - tokenContractCCIPAdmin == tokenAdmin, "CCIP admin of token doesn't match the token admin address." + tokenContractCCIPAdmin == tokenAdmin, + "CCIP admin of token doesn't match the token admin address." ); // Register the admin via getCCIPAdmin() function - console.log("Claiming admin of the token via getCCIPAdmin() for CCIP admin:", tokenAdmin); + console.log( + "Claiming admin of the token via getCCIPAdmin() for CCIP admin:", + tokenAdmin + ); registryContract.registerAdminViaGetCCIPAdmin(tokenAddress); console.log("Admin claimed successfully for token:", tokenAddress); } - } diff --git a/ccip/cct/foundry/script/DeployBurnMintTokenPool.s.sol b/ccip/cct/foundry/script/DeployBurnMintTokenPool.s.sol index 53e232d5..30550228 100644 --- a/ccip/cct/foundry/script/DeployBurnMintTokenPool.s.sol +++ b/ccip/cct/foundry/script/DeployBurnMintTokenPool.s.sol @@ -2,32 +2,54 @@ pragma solidity 0.8.24; import {Script, console} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; import {HelperUtils} from "./utils/HelperUtils.s.sol"; // Utility functions for JSON parsing and chain info import {HelperConfig} from "./HelperConfig.s.sol"; // Network configuration helper import {BurnMintTokenPool} from "@chainlink/contracts-ccip/contracts/pools/BurnMintTokenPool.sol"; import {BurnMintERC20} from "@chainlink/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol"; import {IBurnMintERC20} from "@chainlink/contracts/src/v0.8/shared/token/ERC20/IBurnMintERC20.sol"; -contract DeployBurnMintTokenPool is Script { +contract DeployBurnMintTokenPool is Script, Config { function run() external { + _loadConfigAndForks("./deployments.toml", true); + for (uint256 i = 0; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + deployToChain(chainId); + } + } + + function deployToChain(uint256 chainId) internal { + vm.selectFork(forkOf[chainId]); // Get the chain name based on the current chain ID string memory chainName = HelperUtils.getChainName(block.chainid); // Construct the path to the deployed token JSON file string memory root = vm.projectRoot(); - string memory deployedTokenPath = string.concat(root, "/script/output/deployedToken_", chainName, ".json"); + string memory deployedTokenPath = string.concat( + root, + "/script/output/deployedToken_", + chainName, + ".json" + ); // Extract the deployed token address from the JSON file - address tokenAddress = - HelperUtils.getAddressFromJson(vm, deployedTokenPath, string.concat(".deployedToken_", chainName)); + address tokenAddress = HelperUtils.getAddressFromJson( + vm, + deployedTokenPath, + string.concat(".deployedToken_", chainName) + ); // Fetch network configuration (router and RMN proxy addresses) HelperConfig helperConfig = new HelperConfig(); - (, address router, address rmnProxy,,,,,) = helperConfig.activeNetworkConfig(); + (, address router, address rmnProxy, , , , , ) = helperConfig + .activeNetworkConfig(); // Ensure that the token address, router, and RMN proxy are valid require(tokenAddress != address(0), "Invalid token address"); - require(router != address(0) && rmnProxy != address(0), "Router or RMN Proxy not defined for this network"); + require( + router != address(0) && rmnProxy != address(0), + "Router or RMN Proxy not defined for this network" + ); // Cast the token address to the IBurnMintERC20 interface IBurnMintERC20 token = IBurnMintERC20(tokenAddress); @@ -47,17 +69,35 @@ contract DeployBurnMintTokenPool is Script { // Grant mint and burn roles to the token pool on the token contract BurnMintERC20(tokenAddress).grantMintAndBurnRoles(address(tokenPool)); - console.log("Granted mint and burn roles to token pool:", address(tokenPool)); + console.log( + "Granted mint and burn roles to token pool:", + address(tokenPool) + ); vm.stopBroadcast(); // Serialize and write the token pool address to a new JSON file string memory jsonObj = "internal_key"; - string memory key = string(abi.encodePacked("deployedTokenPool_", chainName)); - string memory finalJson = vm.serializeAddress(jsonObj, key, address(tokenPool)); + string memory key = string( + abi.encodePacked("deployedTokenPool_", chainName) + ); + string memory finalJson = vm.serializeAddress( + jsonObj, + key, + address(tokenPool) + ); - string memory poolFileName = string(abi.encodePacked("./script/output/deployedTokenPool_", chainName, ".json")); - console.log("Writing deployed token pool address to file:", poolFileName); + string memory poolFileName = string( + abi.encodePacked( + "./script/output/deployedTokenPool_", + chainName, + ".json" + ) + ); + console.log( + "Writing deployed token pool address to file:", + poolFileName + ); vm.writeJson(finalJson, poolFileName); } } diff --git a/ccip/cct/foundry/script/DeployLockReleaseTokenPool.s.sol b/ccip/cct/foundry/script/DeployLockReleaseTokenPool.s.sol index c118b7cb..2ee2dad2 100644 --- a/ccip/cct/foundry/script/DeployLockReleaseTokenPool.s.sol +++ b/ccip/cct/foundry/script/DeployLockReleaseTokenPool.s.sol @@ -2,32 +2,53 @@ pragma solidity 0.8.24; import {Script, console} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; import {HelperUtils} from "./utils/HelperUtils.s.sol"; // Utility functions for JSON parsing and chain info import {HelperConfig} from "./HelperConfig.s.sol"; // Network configuration helper import {LockReleaseTokenPool} from "@chainlink/contracts-ccip/contracts/pools/LockReleaseTokenPool.sol"; -import {IERC20} from - "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; +import {IERC20} from "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; -contract DeployLockReleaseTokenPool is Script { +contract DeployLockReleaseTokenPool is Script, Config { function run() external { + _loadConfigAndForks("./deployments.toml", true); + for (uint256 i = 0; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + deployToChain(chainId); + } + } + + function deployToChain(uint256 chainId) internal { + vm.selectFork(forkOf[chainId]); // Get the chain name based on the current chain ID string memory chainName = HelperUtils.getChainName(block.chainid); // Construct the path to the deployed token JSON file string memory root = vm.projectRoot(); - string memory deployedTokenPath = string.concat(root, "/script/output/deployedToken_", chainName, ".json"); + string memory deployedTokenPath = string.concat( + root, + "/script/output/deployedToken_", + chainName, + ".json" + ); // Extract the deployed token address from the JSON file - address tokenAddress = - HelperUtils.getAddressFromJson(vm, deployedTokenPath, string.concat(".deployedToken_", chainName)); + address tokenAddress = HelperUtils.getAddressFromJson( + vm, + deployedTokenPath, + string.concat(".deployedToken_", chainName) + ); // Fetch network configuration (router and RMN proxy addresses) HelperConfig helperConfig = new HelperConfig(); - (, address router, address rmnProxy,,,,,) = helperConfig.activeNetworkConfig(); + (, address router, address rmnProxy, , , , , ) = helperConfig + .activeNetworkConfig(); // Ensure that the token address, router, and RMN proxy are valid require(tokenAddress != address(0), "Invalid token address"); - require(router != address(0) && rmnProxy != address(0), "Router or RMN Proxy not defined for this network"); + require( + router != address(0) && rmnProxy != address(0), + "Router or RMN Proxy not defined for this network" + ); vm.startBroadcast(); @@ -40,17 +61,35 @@ contract DeployLockReleaseTokenPool is Script { router ); - console.log("Lock & Release token pool deployed to:", address(tokenPool)); + console.log( + "Lock & Release token pool deployed to:", + address(tokenPool) + ); vm.stopBroadcast(); // Serialize and write the token pool address to a new JSON file string memory jsonObj = "internal_key"; - string memory key = string(abi.encodePacked("deployedTokenPool_", chainName)); - string memory finalJson = vm.serializeAddress(jsonObj, key, address(tokenPool)); + string memory key = string( + abi.encodePacked("deployedTokenPool_", chainName) + ); + string memory finalJson = vm.serializeAddress( + jsonObj, + key, + address(tokenPool) + ); - string memory poolFileName = string(abi.encodePacked("./script/output/deployedTokenPool_", chainName, ".json")); - console.log("Writing deployed token pool address to file:", poolFileName); + string memory poolFileName = string( + abi.encodePacked( + "./script/output/deployedTokenPool_", + chainName, + ".json" + ) + ); + console.log( + "Writing deployed token pool address to file:", + poolFileName + ); vm.writeJson(finalJson, poolFileName); } } diff --git a/ccip/cct/foundry/script/DeployToken.s.sol b/ccip/cct/foundry/script/DeployToken.s.sol index 97ab4054..e31c0383 100644 --- a/ccip/cct/foundry/script/DeployToken.s.sol +++ b/ccip/cct/foundry/script/DeployToken.s.sol @@ -2,11 +2,22 @@ pragma solidity 0.8.24; import {Script, console} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; import {HelperUtils} from "./utils/HelperUtils.s.sol"; // Utility functions for JSON parsing and chain info import {BurnMintERC20} from "@chainlink/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol"; -contract DeployToken is Script { +contract DeployToken is Script, Config { function run() external { + _loadConfigAndForks("./deployments.toml", true); + for (uint256 i = 0; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + deployToChain(chainId); + } + } + + function deployToChain(uint256 chainId) internal { + vm.selectFork(forkOf[chainId]); + // Get the chain name based on the current chain ID string memory chainName = HelperUtils.getChainName(block.chainid); @@ -15,22 +26,45 @@ contract DeployToken is Script { string memory configPath = string.concat(root, "/script/config.json"); // Extract token parameters from the config.json file - string memory name = HelperUtils.getStringFromJson(vm, configPath, ".BnMToken.name"); - string memory symbol = HelperUtils.getStringFromJson(vm, configPath, ".BnMToken.symbol"); - uint8 decimals = uint8(HelperUtils.getUintFromJson(vm, configPath, ".BnMToken.decimals")); - uint256 maxSupply = HelperUtils.getUintFromJson(vm, configPath, ".BnMToken.maxSupply"); - uint256 preMint = HelperUtils.getUintFromJson(vm, configPath, ".BnMToken.preMint"); + string memory name = HelperUtils.getStringFromJson( + vm, + configPath, + ".BnMToken.name" + ); + string memory symbol = HelperUtils.getStringFromJson( + vm, + configPath, + ".BnMToken.symbol" + ); + uint8 decimals = uint8( + HelperUtils.getUintFromJson(vm, configPath, ".BnMToken.decimals") + ); + uint256 maxSupply = HelperUtils.getUintFromJson( + vm, + configPath, + ".BnMToken.maxSupply" + ); + uint256 preMint = HelperUtils.getUintFromJson( + vm, + configPath, + ".BnMToken.preMint" + ); vm.startBroadcast(); address deployer = msg.sender; address tokenAddress; - - BurnMintERC20 token = new BurnMintERC20(name, symbol, decimals, maxSupply, preMint); + BurnMintERC20 token = new BurnMintERC20( + name, + symbol, + decimals, + maxSupply, + preMint + ); tokenAddress = address(token); console.log("Deployed BurnMintERC20 at:", tokenAddress); - + // Grant mint and burn roles to the deployer address BurnMintERC20(tokenAddress).grantMintAndBurnRoles(deployer); console.log("Granted mint and burn roles to:", deployer); @@ -39,11 +73,23 @@ contract DeployToken is Script { // Prepare to write the deployed token address to a JSON file string memory jsonObj = "internal_key"; - string memory key = string(abi.encodePacked("deployedToken_", chainName)); - string memory finalJson = vm.serializeAddress(jsonObj, key, tokenAddress); + string memory key = string( + abi.encodePacked("deployedToken_", chainName) + ); + string memory finalJson = vm.serializeAddress( + jsonObj, + key, + tokenAddress + ); // Define the output file path for the deployed token address - string memory fileName = string(abi.encodePacked("./script/output/deployedToken_", chainName, ".json")); + string memory fileName = string( + abi.encodePacked( + "./script/output/deployedToken_", + chainName, + ".json" + ) + ); console.log("Writing deployed token address to file:", fileName); // Write the JSON file containing the deployed token address diff --git a/ccip/cct/foundry/script/SetPool.s.sol b/ccip/cct/foundry/script/SetPool.s.sol index d8ab13da..30d3e207 100644 --- a/ccip/cct/foundry/script/SetPool.s.sol +++ b/ccip/cct/foundry/script/SetPool.s.sol @@ -2,42 +2,77 @@ pragma solidity 0.8.24; import {Script, console} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; import {HelperUtils} from "./utils/HelperUtils.s.sol"; // Utility functions for JSON parsing and chain info import {HelperConfig} from "./HelperConfig.s.sol"; // Network configuration helper import {TokenAdminRegistry} from "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/TokenAdminRegistry.sol"; // Script contract to set the token pool in the TokenAdminRegistry -contract SetPool is Script { +contract SetPool is Script, Config { function run() external { + _loadConfigAndForks("./deployments.toml", true); + for (uint256 i = 0; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + deployToChain(chainId); + } + } + + function deployToChain(uint256 chainId) internal { + vm.selectFork(forkOf[chainId]); // Get the chain name based on the current chain ID string memory chainName = HelperUtils.getChainName(block.chainid); // Construct paths to the JSON files containing deployed token and pool addresses string memory root = vm.projectRoot(); - string memory deployedTokenPath = string.concat(root, "/script/output/deployedToken_", chainName, ".json"); - string memory deployedPoolPath = string.concat(root, "/script/output/deployedTokenPool_", chainName, ".json"); + string memory deployedTokenPath = string.concat( + root, + "/script/output/deployedToken_", + chainName, + ".json" + ); + string memory deployedPoolPath = string.concat( + root, + "/script/output/deployedTokenPool_", + chainName, + ".json" + ); // Extract the deployed token and pool addresses from the JSON files - address tokenAddress = - HelperUtils.getAddressFromJson(vm, deployedTokenPath, string.concat(".deployedToken_", chainName)); - address poolAddress = - HelperUtils.getAddressFromJson(vm, deployedPoolPath, string.concat(".deployedTokenPool_", chainName)); + address tokenAddress = HelperUtils.getAddressFromJson( + vm, + deployedTokenPath, + string.concat(".deployedToken_", chainName) + ); + address poolAddress = HelperUtils.getAddressFromJson( + vm, + deployedPoolPath, + string.concat(".deployedTokenPool_", chainName) + ); // Fetch the network configuration to get the TokenAdminRegistry address HelperConfig helperConfig = new HelperConfig(); - (,,, address tokenAdminRegistry,,,,) = helperConfig.activeNetworkConfig(); + (, , , address tokenAdminRegistry, , , , ) = helperConfig + .activeNetworkConfig(); require(tokenAddress != address(0), "Invalid token address"); require(poolAddress != address(0), "Invalid pool address"); - require(tokenAdminRegistry != address(0), "TokenAdminRegistry is not defined for this network"); + require( + tokenAdminRegistry != address(0), + "TokenAdminRegistry is not defined for this network" + ); vm.startBroadcast(); // Instantiate the TokenAdminRegistry contract - TokenAdminRegistry tokenAdminRegistryContract = TokenAdminRegistry(tokenAdminRegistry); + TokenAdminRegistry tokenAdminRegistryContract = TokenAdminRegistry( + tokenAdminRegistry + ); // Fetch the token configuration to get the administrator's address - TokenAdminRegistry.TokenConfig memory config = tokenAdminRegistryContract.getTokenConfig(tokenAddress); + TokenAdminRegistry.TokenConfig + memory config = tokenAdminRegistryContract.getTokenConfig( + tokenAddress + ); address tokenAdministratorAddress = config.administrator; console.log("Setting pool for token:", tokenAddress);