-
Notifications
You must be signed in to change notification settings - Fork 39
Description
Description
In the CCIPLocalSimulatorFork._routeCapturedMessages function, when processing CCIPMessageSent events (for CCIP v1.6+), the simulator incorrectly truncates 32-byte ABI-encoded addresses (both receiver and destTokenAddress) to 20 bytes by using address(uint160(bytes20(...))) instead of the correct abi.decode(..., (address)).
This causes addresses to be truncated (e.g., 0x0000...Cef9...) when the message arrives at the destination chain, leading to failures such as getPool returning zero address or InvalidSourcePoolAddress errors.
Environment
Package: chainlink-local
Version: [e.g., v0.2.7, main branch commit hash]
Solidity Version: 0.8.19+
Foundry Version: [e.g., forge 0.2.0]
Steps to Reproduce
cross from sepolia to base sepolia
In a Foundry test, send a CCIP v1.6+ message using the simulator (e.g., from Sepolia to Base Sepolia).
Construct the source message correctly:
receiver = abi.encode(user) (32-byte ABI encoding)
In lockOrBurn, return destTokenAddress = abi.encode(remoteToken) (32-byte ABI encoding)
Call ccipLocalSimulatorFork.switchChainAndRouteMessage(remoteForkId).
On the destination fork, executeSingleMessage receives truncated addresses, causing failures.
Relevant Code
File: src/ccip/CCIPLocalSimulatorFork.sol
Function: _routeCapturedMessages
Line numbers (approximate):
solidity
// Lines ~214-219: tokenAmounts construction
destTokenAddress: address(
uint160(bytes20(message.tokenAmounts[l].destTokenAddress))
),
// Line ~226: receiver construction
receiver: address(uint160(bytes20(message.receiver))),
Expected Behavior
The simulator should correctly decode 32-byte ABI-encoded addresses using:
solidity
destTokenAddress: abi.decode(message.tokenAmounts[l].destTokenAddress, (address)),
receiver: abi.decode(message.receiver, (address)),
Actual Behavior
Addresses are truncated to the first 20 bytes of the 32-byte encoding, resulting in invalid addresses on the destination chain.
Impact
All CCIP v1.6+ cross-chain tests using chainlink-local may fail due to address truncation, making it impossible to properly test token transfers and message execution.
Proposed Fix
Replace the two lines above with:
solidity
destTokenAddress: abi.decode(message.tokenAmounts[l].destTokenAddress, (address)),
receiver: abi.decode(message.receiver, (address)),
Note: sourcePoolAddress encoding should remain as abi.encodePacked (20 bytes raw address) as it is correctly handled elsewhere.
Workaround
Until the fix is released, manually patch CCIPLocalSimulatorFork.sol in your local lib/chainlink-local directory with the changes above, or override validation functions in your own pool contracts to handle 32-byte encodings.
Additional Context
This issue only affects CCIP v1.6+ messages (CCIPMessageSent events). The pre-v1.6 handling (CCIPSendRequested) appears to be correct.