Skip to content

Add remote token address check#482

Merged
friedemannf merged 9 commits into
mainfrom
token-check
Jun 4, 2026
Merged

Add remote token address check#482
friedemannf merged 9 commits into
mainfrom
token-check

Conversation

@JohnChangUK
Copy link
Copy Markdown
Contributor

No description provided.

@JohnChangUK JohnChangUK requested a review from a team as a code owner May 10, 2026 19:24
@github-actions
Copy link
Copy Markdown

👋 JohnChangUK, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

remoteTokenAddressMatches sourceTokenAddress configuredRemoteTokenAddress =
sourceTokenAddress == configuredRemoteTokenAddress
|| (byteCount sourceTokenAddress == 32
&& byteCount configuredRemoteTokenAddress == 20
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

how is this handled on EVM? is there this exceptional clause for EVM addresses?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  1. EVM doesn't have this check as sourceTokenAddress field doesn't exist there. The token pool address has the token bound do it as a field during creation.
  2. EVM uses abi.encode to encode the address into the message. This pads the address to 32 bytes. https://github.com/smartcontractkit/chainlink-ccip/blob/main/chains/evm/contracts/onRamp/OnRamp.sol#L777

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

EVM doesn't have this check as sourceTokenAddress field doesn't exist there. The token pool address has the token bound do it as a field during creation.

it's right here? https://github.com/smartcontractkit/chainlink-ccip/blob/22e2d05695cd4fea667a9037d47cffb33acb12db/chains/evm/contracts/libraries/MessageV1Codec.sol#L165

from the comments at that line:

// Address of destination token, NOT abi encoded but raw bytes matching destination chains address byte length.

which means that this should always match the source chain's address length? and we should be decoding it correctly here?

sourceTokenLen <- decodeUint8 sourceTokenLenHex

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

// Address of destination token, NOT abi encoded but raw bytes matching destination chains address byte length.

This comment above is for destTokenAddress though, not on sourceTokenAddress.

bytes sourceTokenAddress; // Address of source token, abi encoded for EVM chains.

cfal
cfal previously requested changes May 14, 2026
-- - In the incoming directions, the pools will validate that sourcePoolAddress === the stored remote pool address
-- - In the outgoing direction (to EVM), the pools will add this stored address to the message in destTokenAddress
-- - In the outgoing direction, EVM expects the incoming destTokenAddress the be unpadded 20 bytes, so we must strip the padding before sending the outgoing message
validateDestChainAddress : BytesHex -> Int -> BytesHex
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Comment on lines +281 to +286
ensure
isValidHex receiver && byteCount receiver == destAddressBytesLength
&& (tokenReceiver == "" || (isValidHex tokenReceiver && byteCount tokenReceiver == destAddressBytesLength))
&& (case tokenSendData of
None -> True
Some tsd -> isValidHex tsd.destTokenAddress && byteCount tsd.destTokenAddress == destAddressBytesLength)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Adding an ensure clause here, the actual validation is supposed to happen via validateDestChainAddress

let tsd = TokenSendData with
poolInstanceId, poolOwner, instrumentId, amount
destTokenAddress, extraData
destTokenAddress = validateDestChainAddress destTokenAddress destAddressBytesLength
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This has to happen here instead of in the OnRamp, since the OnRamp cannot modify the value

@friedemannf friedemannf dismissed cfal’s stale review June 4, 2026 23:56

Clarified EVM behavior

@friedemannf friedemannf merged commit 11cc6f6 into main Jun 4, 2026
39 checks passed
@friedemannf friedemannf deleted the token-check branch June 4, 2026 23:56
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.

3 participants