Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ccip/cct/foundry/deployments.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[avalanche-fuji]
endpoint_url = "${RPC_URL_FUJI}"

[arbitrum-sepolia]
endpoint_url = "${RPC_URL_ARBITRUM_SEPOLIA}"
2 changes: 1 addition & 1 deletion ccip/cct/foundry/lib/forge-std
Submodule forge-std updated 47 files
+1 −0 .github/CODEOWNERS
+6 −0 .github/dependabot.yml
+114 −100 .github/workflows/ci.yml
+6 −1 .github/workflows/sync.yml
+3 −3 README.md
+12 −0 RELEASE_CHECKLIST.md
+10 −4 foundry.toml
+1 −1 package.json
+22 −9 src/Base.sol
+60 −0 src/Config.sol
+477 −0 src/LibVariable.sol
+1 −0 src/Script.sol
+142 −47 src/StdAssertions.sol
+32 −3 src/StdChains.sol
+14 −2 src/StdCheats.sol
+612 −0 src/StdConfig.sol
+30 −0 src/StdConstants.sol
+4 −0 src/StdMath.sol
+2 −2 src/StdStorage.sol
+0 −18 src/StdUtils.sol
+1 −0 src/Test.sol
+464 −27 src/Vm.sol
+1 −1 src/interfaces/IERC1155.sol
+1 −1 src/interfaces/IERC4626.sol
+72 −0 src/interfaces/IERC6909.sol
+1 −1 src/interfaces/IERC721.sol
+150 −0 src/interfaces/IERC7540.sol
+241 −0 src/interfaces/IERC7575.sol
+0 −234 src/mocks/MockERC20.sol
+0 −231 src/mocks/MockERC721.sol
+44 −0 test/CommonBase.t.sol
+352 −0 test/Config.t.sol
+434 −0 test/LibVariable.t.sol
+0 −4 test/StdAssertions.t.sol
+8 −9 test/StdChains.t.sol
+45 −24 test/StdCheats.t.sol
+38 −0 test/StdConstants.t.sol
+2 −2 test/StdMath.t.sol
+20 −3 test/StdStorage.t.sol
+2 −2 test/Vm.t.sol
+1 −1 test/compilation/CompilationScript.sol
+1 −1 test/compilation/CompilationScriptBase.sol
+1 −1 test/compilation/CompilationTest.sol
+1 −1 test/compilation/CompilationTestBase.sol
+81 −0 test/fixtures/config.toml
+0 −441 test/mocks/MockERC20.t.sol
+0 −721 test/mocks/MockERC721.t.sol
48 changes: 39 additions & 9 deletions ccip/cct/foundry/script/AcceptAdminRole.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +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";

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

// Get the address of the signer (the account executing the 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);
Expand Down
83 changes: 65 additions & 18 deletions ccip/cct/foundry/script/ApplyChainUpdates.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,113 @@
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);
remotePoolAddresses[0] = remotePoolAddress;

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

// Instantiate the local TokenPool contract
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]);
}
Expand Down
75 changes: 55 additions & 20 deletions ccip/cct/foundry/script/ClaimAdmin.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,99 @@
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();
console.log("Current token admin:", tokenContractCCIPAdmin);

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

}
Loading