Skip to content

Cross chain pool & token#1883

Merged
RensR merged 52 commits intomainfrom
CrossChainPool-&-Token
Apr 6, 2026
Merged

Cross chain pool & token#1883
RensR merged 52 commits intomainfrom
CrossChainPool-&-Token

Conversation

@RensR
Copy link
Copy Markdown
Collaborator

@RensR RensR commented Mar 20, 2026

This PR introduces new tokens and a new pool

Tokens

The BaseERC20 is a basic mint-once LockRelease token. It serves as the base implementation of the new CrossChainToken and the CrossChainPoolToken.

The CrossChainToken (CCT) is the new primary CCIP token. It supports everything needed to fully support CCIP integration: ccipAdmin, burning/minting and safe ownership roles.

Pool

The new pool is a pool/token combo. This makes management and deployment easier: there's nothing to configure. The token exposes it burn/mint functions through the fully CCIP compatible TokenPool interface (ready for CCIPv2) and no token related config/permissions have to be set post deployment.

Factory

The token pool factory is updated to work with the new CrossChainToken. It should not support significantly more flexible ownership/premint/permission options, and has better security guards against dangling permissions or tokens being locked in the factory contact.

RensR added 30 commits March 10, 2026 10:48
# Conflicts:
#	ccv/chains/evm/deployment/latest/operations/lombard_token_pool/lombard_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/burn_from_mint_token_pool/burn_from_mint_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/burn_mint_token_pool/burn_mint_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/burn_mint_with_lock_release_flag_token_pool/burn_mint_with_lock_release_flag_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/burn_to_address_mint_token_pool/burn_to_address_mint_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/cctp_through_ccv_token_pool/cctp_through_ccv_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/lock_release_token_pool/lock_release_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/siloed_lock_release_token_pool/siloed_lock_release_token_pool.go
#	ccv/chains/evm/deployment/v2_0_0/operations/siloed_usdc_token_pool/siloed_usdc_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/burn_from_mint_token_pool/burn_from_mint_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/burn_mint_token_pool/burn_mint_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/burn_mint_with_lock_release_flag_token_pool/burn_mint_with_lock_release_flag_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/burn_to_address_mint_token_pool/burn_to_address_mint_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/cctp_through_ccv_token_pool/cctp_through_ccv_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/lock_release_token_pool/lock_release_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/lombard_token_pool/lombard_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/siloed_lock_release_token_pool/siloed_lock_release_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/siloed_usdc_token_pool/siloed_usdc_token_pool.go
#	ccv/chains/evm/gobindings/generated/latest/token_pool_factory/token_pool_factory.go
#	chains/evm/.gas-snapshot
#	chains/evm/gobindings/generation/generated-wrapper-dependency-versions-do-not-edit.txt
Also adds (IERC20Metadata).interfaceId
RensR and others added 11 commits March 26, 2026 11:09
…ry-to-futureOwner

send tokens from factory to futureOwner
…en-fixes

# Conflicts:
#	chains/evm/contracts/tokens/BaseERC20.sol
…-token-fixes

Minor cross chain pool token fixes
# Conflicts:
#	chains/evm/contracts/tokens/BaseERC20.sol
# Conflicts:
#	ccv/chains/evm/gobindings/generated/latest/mock_lbtc_token_pool/mock_lbtc_token_pool.go
#	chains/evm/.gas-snapshot
#	chains/evm/contracts/pools/TokenPool.sol
@RensR RensR marked this pull request as ready for review March 26, 2026 11:14
@RensR RensR requested a review from a team as a code owner March 26, 2026 11:14
Copilot AI review requested due to automatic review settings March 26, 2026 11:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces new cross-chain-friendly token and “pool-is-token” primitives, migrates the factory deployment flow to those primitives (including a new futureOwner handoff parameter), and updates compilation, bindings, and tests to remove the legacy factory-minted ERC20.

Changes:

  • Add BaseERC20/CrossChainToken (role-based burn/mint + CCIP admin) and CrossChainPoolToken (token pool that is also the ERC20).
  • Refactor TokenPoolFactory to deploy/configure CrossChainToken-based deployments, add futureOwner, and forward any factory-held premint to that owner.
  • Update build scripts, Go bindings generation inputs, and tests/mocks to use CrossChainToken instead of BurnMintERC20/FactoryBurnMintERC20, plus add new unit + e2e coverage.

Reviewed changes

Copilot reviewed 93 out of 96 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
chains/evm/scripts/compile_all Add compilation targets/optimizer override for new CrossChain pool/token artifacts; switch factory compile target.
chains/evm/gobindings/go_generate.go Update go:generate wrappers: remove FactoryBurnMintERC20, add CrossChainPoolToken and CrossChainToken.
chains/evm/gobindings/generation/generated-wrapper-dependency-versions-do-not-edit.txt Add new wrapper dependencies and update factory wrapper hash.
chains/evm/contracts/tokens/CrossChainToken.sol New role-based burn/mint token built on BaseERC20 + OZ AccessControl default admin rules.
chains/evm/contracts/tokens/BaseERC20.sol New ERC20 base with max-supply guardrails and explicit CCIP admin role management.
chains/evm/contracts/tokenAdminRegistry/TokenPoolFactory/FactoryBurnMintERC20.sol Remove legacy factory-deployed burn/mint token implementation.
chains/evm/contracts/test/tokens/CrossChainToken/CrossChainTokenSetup.t.sol Add CrossChainToken test setup fixture.
chains/evm/contracts/test/tokens/CrossChainToken/CrossChainToken.setCCIPAdmin.t.sol Add setCCIPAdmin behavior + access control tests.
chains/evm/contracts/test/tokens/CrossChainToken/CrossChainToken.mint.t.sol Add mint behavior tests incl maxSupply + invalid receiver + role checks.
chains/evm/contracts/test/tokens/CrossChainToken/CrossChainToken.grantMintAndBurnRoles.t.sol Add helper role-granting test.
chains/evm/contracts/test/tokens/CrossChainToken/CrossChainToken.constructor.t.sol Add constructor invariants + supportsInterface + typeAndVersion tests.
chains/evm/contracts/test/tokens/CrossChainToken/CrossChainToken.burn.t.sol Add burn/burnFrom tests and role-gating coverage.
chains/evm/contracts/test/tokens/BaseERC20/BaseERC20Setup.t.sol Add BaseERC20 test setup fixture.
chains/evm/contracts/test/tokens/BaseERC20/BaseERC20.transfer.t.sol Add transfer/approve-to-self revert tests for BaseERC20.
chains/evm/contracts/test/tokens/BaseERC20/BaseERC20.setCCIPAdmin.t.sol Add CCIP admin transfer behavior + revert coverage for BaseERC20.
chains/evm/contracts/test/tokens/BaseERC20/BaseERC20.constructor.t.sol Add BaseERC20 constructor invariants + revert coverage.
chains/evm/contracts/test/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactorySetup.t.sol Remove legacy setup that depended on FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/RegistryModuleOwnerCustom/RegistryModuleOwnerCustomSetup.t.sol Update registry module tests to use CrossChainToken instead of BurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.transfer.t.sol Remove legacy FactoryBurnMintERC20 transfer tests.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.supportsInterface.t.sol Remove legacy FactoryBurnMintERC20 supportsInterface tests.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.mint.t.sol Remove legacy FactoryBurnMintERC20 mint tests.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.increaseApproval.t.sol Remove legacy approval-increase test for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.grantRole.t.sol Remove legacy role grant/revoke tests for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.grantMintAndBurnRoles.t.sol Remove legacy grantMintAndBurnRoles test for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.getCCIPAdmin.t.sol Remove legacy CCIP admin tests for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.decreaseApproval.t.sol Remove legacy approval-decrease test for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.constructor.t.sol Remove legacy constructor tests for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.burnFromAlias.t.sol Remove legacy burn alias test for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.burnFrom.t.sol Remove legacy burnFrom test for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.burn.t.sol Remove legacy burn tests for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/FactoryBurnMintERC20.approve.t.sol Remove legacy approve tests for FactoryBurnMintERC20.
chains/evm/contracts/test/tokenAdminRegistry/FactoryBurnMintERC20/BurnMintERC20Setup.t.sol Remove legacy FactoryBurnMintERC20 test fixture.
chains/evm/contracts/test/pools/USDC/USDCTokenPoolProxy/USDCTokenPoolProxy.withdrawFeeTokens.t.sol Update fee token test wiring to use CrossChainToken.
chains/evm/contracts/test/pools/USDC/USDCSetup.t.sol Use CrossChainToken as the USDC test token.
chains/evm/contracts/test/pools/USDC/SiloedUSDCTokenPool/SiloedUSDCTokenPoolSetup.sol Update role granting callsites to CrossChainToken.
chains/evm/contracts/test/pools/TokenPool/TokenPoolSetup.t.sol Use CrossChainToken for test token creation.
chains/evm/contracts/test/pools/TokenPool/TokenPool.withdrawFee.t.sol Use CrossChainToken for additional fee token in tests.
chains/evm/contracts/test/pools/TokenPool/TokenPool.applyChainUpdates.t.sol Use CrossChainToken in pool chain-update tests.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPoolSetup.t.sol Use CrossChainToken for pool/lockbox tests.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPool.getAllLockBoxConfigs.t.sol Use CrossChainToken for lockbox config enumeration test.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPool.constructor.t.sol Use CrossChainToken in constructor test.
chains/evm/contracts/test/pools/SiloedLockReleaseTokenPool/SiloedLockReleaseTokenPool.configureLockBoxes.t.sol Use CrossChainToken for lockbox configuration tests.
chains/evm/contracts/test/pools/LombardTokenPool/LombardTokenPool.constructor.t.sol Switch Lombard token tests to CrossChainToken and BaseTest.
chains/evm/contracts/test/pools/LombardTokenPool/LombardTokenPool._getTokenDecimals.t.sol Use CrossChainToken in token decimals helper test.
chains/evm/contracts/test/pools/LockReleaseTokenPool/LockReleaseTokenPoolSetup.t.sol Use CrossChainToken for lock/release pool setup.
chains/evm/contracts/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.constructor.t.sol Use CrossChainToken in constructor and invalid token tests.
chains/evm/contracts/test/pools/ERC20LockBox/ERC20LockBoxSetup.t.sol Use CrossChainToken for lockbox setup.
chains/evm/contracts/test/pools/ERC20LockBox/ERC20LockBox.deposit.t.sol Update unsupported-token test to use CrossChainToken.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolTokenSetup.t.sol Add setup fixture for the new pool-is-token contract.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.setCCIPAdmin.t.sol Add CCIP admin setter tests for CrossChainPoolToken.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.sendReceive.t.sol Add full lifecycle send/receive simulation tests for pool-is-token flows.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.releaseOrMint.t.sol Add releaseOrMint tests for CrossChainPoolToken incl maxSupply/curse/chain gating.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.lockOrBurn.t.sol Add lockOrBurn burn-from-self tests + RMN/chain gating coverage.
chains/evm/contracts/test/pools/CrossChainPoolToken/CrossChainPoolToken.constructor.t.sol Add constructor invariants for CrossChainPoolToken.
chains/evm/contracts/test/pools/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.lockOrBurn.t.sol Update role granting to CrossChainToken.
chains/evm/contracts/test/pools/BurnToAddressMintTokenPool/BurnToAddressMintTokenPoolSetup.t.sol Update role granting to CrossChainToken.
chains/evm/contracts/test/pools/BurnMintWithLockReleaseFlagTokenPool/BurnMintWithLockReleaseFlagTokenPoolSetup.t.sol Use CrossChainToken and update role granting in USDC-like setup.
chains/evm/contracts/test/pools/BurnMintTokenPool/BurnMintTokenPool.releaseOrMint.t.sol Update role granting to CrossChainToken.
chains/evm/contracts/test/pools/BurnMintTokenPool/BurnMintTokenPool.lockOrBurn.t.sol Update role granting to CrossChainToken.
chains/evm/contracts/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPoolSetup.t.sol Update role granting to CrossChainToken.
chains/evm/contracts/test/pools/AdvancedPoolHooks/AdvancedPoolHooksSetup.t.sol Use CrossChainToken for token setup.
chains/evm/contracts/test/onRamp/OnRamp/OnRamp.withdrawFeeTokens.t.sol Use CrossChainToken for fee token tests.
chains/evm/contracts/test/offRamp/OffRamp/OffRamp.releaseOrMintSingleToken.t.sol Update role granting to CrossChainToken.
chains/evm/contracts/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol Use CrossChainToken as destination token in offRamp execution tests.
chains/evm/contracts/test/mocks/test/MockRouterTest.t.sol Loosened revert expectation for allowance error (needs tightening).
chains/evm/contracts/test/mocks/MockE2EUSDCTransmitterCCTPV2.sol Update mock transmitter token type to CrossChainToken.
chains/evm/contracts/test/mocks/MockE2EUSDCTransmitter.sol Update mock transmitter token type to CrossChainToken.
chains/evm/contracts/test/libraries/FeeTokenHandler/FeeTokenHandler.withdrawFeeTokens.t.sol Use CrossChainToken for fee token in handler tests.
chains/evm/contracts/test/feeQuoter/FeeQuoterSetup.t.sol Adjust FeeQuoter test constants to accommodate updated limits/overheads.
chains/evm/contracts/test/executor/Executor/ExecutorSetup.t.sol Use CrossChainToken as fee token in executor tests.
chains/evm/contracts/test/executor/Executor/Executor.withdrawFeeTokens.t.sol Use CrossChainToken as secondary fee token in executor tests.
chains/evm/contracts/test/e2e/e2e.feeWithdraw.t.sol Use CrossChainToken as test token in e2e fee-withdraw flow.
chains/evm/contracts/test/e2e/e2e.factoryDeployedPool.t.sol Add e2e coverage for factory-deployed token+pool and remote deployment via CCIP.
chains/evm/contracts/test/e2e/e2e.cctp.t.sol Use CrossChainToken for USDC token in CCTP e2e tests and role granting.
chains/evm/contracts/test/ccvs/components/BaseVerifier/BaseVerifierSetup.t.sol Use CrossChainToken as source fee token in verifier setup.
chains/evm/contracts/test/ccvs/VersionedVerifierResolver/VersionedVerifierResolver.withdrawFeeTokens.t.sol Use CrossChainToken for fee token tests.
chains/evm/contracts/test/ccvs/LombardVerifier/LombardVerifierSetup.t.sol Use CrossChainToken for supported token setup.
chains/evm/contracts/test/ccvs/LombardVerifier/LombardVerifier.updateSupportedTokens.t.sol Use CrossChainToken in supported token update tests and allowance checks.
chains/evm/contracts/test/ccvs/LombardVerifier/LombardVerifier.forwardToVerifier.t.sol Use CrossChainToken in adapter forwarding tests.
chains/evm/contracts/test/ccvs/CommitteeVerifier/CommitteeVerifier.withdrawFeeTokens.t.sol Use CrossChainToken for fee token tests.
chains/evm/contracts/test/ccvs/CCTPVerifier/CCTPVerifierSetup.t.sol Use CrossChainToken as USDC token and update role granting.
chains/evm/contracts/test/ccvs/CCTPVerifier/CCTPVerifier.withdrawFeeTokens.t.sol Use CrossChainToken for fee token tests.
chains/evm/contracts/test/applications/EtherSenderReceiver/EtherSenderReceiverTestSetup.t.sol Use CrossChainToken as LINK fee token in app tests.
chains/evm/contracts/test/applications/EtherSenderReceiver/EtherSenderReceiverTest.ccipSend.t.sol Loosened revert expectation for allowance error (needs tightening).
chains/evm/contracts/test/TokenSetup.t.sol Add helper to deploy CrossChainToken and migrate shared token setup to it.
chains/evm/contracts/test/TokenPoolFactory/TokenPoolFactorySetup.t.sol Add new TokenPoolFactory test setup aligned with new contract location + CrossChainToken init code.
chains/evm/contracts/test/TokenPoolFactory/TokenPoolFactory.deployTokenAndTokenPool.t.sol Update factory tests for new API (futureOwner), CrossChainToken roles, and expanded ownership/permission assertions.
chains/evm/contracts/test/TokenPoolFactory/TokenPoolFactory.constructor.t.sol Update imports and constructor test inputs for new factory location.
chains/evm/contracts/test/Router/Router.ccipSend.t.sol Loosened revert expectation for allowance error (needs tightening).
chains/evm/contracts/test/Proxy/Proxy.withdrawFeeTokens.t.sol Use CrossChainToken for fee token tests.
chains/evm/contracts/pools/CrossChainPoolToken.sol New pool contract that is also the ERC20 token (burn/mint via internal ERC20 ops).
chains/evm/contracts/TokenPoolFactory.sol Refactor factory for CrossChainToken-based deployments, add futureOwner, register via CCIP admin, and forward premint balance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread chains/evm/contracts/test/mocks/test/MockRouterTest.t.sol
Comment thread chains/evm/contracts/test/Router/Router.ccipSend.t.sol
@github-actions
Copy link
Copy Markdown

Metric CrossChainPool-&-Token main
Coverage 70.1% 69.8%

Comment thread chains/evm/contracts/pools/CrossChainPoolToken.sol
Comment thread chains/evm/contracts/pools/CrossChainPoolToken.sol
function burn(
address account,
uint256 amount
) public virtual override {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a huge fan of delegating the validation to burnFrom. Like this is secure, but if a future dev were to override this function and use some custom logic that doesn't call burnFrom it could be a trivial thing to miss.

Given that this contracts size is only 6.3kB, and burnFrom already heavily uses internal logic, we could just do this.

  function burn(
    address account,
    uint256 amount
  ) public virtual override onlyRole(BURNER_ROLE) {
    _spendAllowance(account, _msgSender(), amount);
    _burn(account, amount);
  }

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they override, wouldn't they override with some equally secure implementation? This way we reduce code dup and ensure consistency between calls. This burn with an account is just a "wrong" burnFrom with the name burn. We purely add this to allow for compatibility, and it should be exactly equal to BurnFrom (the more correct name). I think given that, it makes sense that this calls into BurnFrom.

/// @param burnAndMinter The address to be granted both the MINTER_ROLE and BURNER_ROLE.
/// @dev calls public functions so this function does not require
/// access controls. This is handled in the inner functions.
function grantMintAndBurnRoles(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same nit as above, just add the validation and then make grantRole into _grantRole

Comment thread chains/evm/contracts/tokens/CrossChainToken.sol
address token = Create2.deploy(0, salt, tokenInitCode);

LocalPoolConfig memory localConfig = LocalPoolConfig({
token: token, localTokenDecimals: localTokenDecimals, localPoolType: localPoolType, lockBox: lockBox, salt: salt
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit add validation that localTokenDecimals actually matches token.decimals() to prevent silent misconfigure.

@RensR RensR enabled auto-merge April 6, 2026 10:58
@RensR RensR added this pull request to the merge queue Apr 6, 2026
Merged via the queue into main with commit 4bde290 Apr 6, 2026
61 checks passed
@RensR RensR deleted the CrossChainPool-&-Token branch April 6, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants