Skip to content

fix(x/forwarding)!: bind token identity to forwarding address derivation#6906

Merged
damiannolan merged 19 commits into
mainfrom
damian/add-token-id-to-forwardaddr-derivation
Mar 27, 2026
Merged

fix(x/forwarding)!: bind token identity to forwarding address derivation#6906
damiannolan merged 19 commits into
mainfrom
damian/add-token-id-to-forwardaddr-derivation

Conversation

@damiannolan

@damiannolan damiannolan commented Mar 23, 2026

Copy link
Copy Markdown
Collaborator

Overview

This PR adds the token identifier HexAddress to the forwarding address derivation.
This hoists the trust model off-chain, preventing linear scan of global permissionless warp tokens.

Below are the outcomes associated with that design decision that affect this PR.

Adding the token_id to the forwarding address derivation:

  • Trusted frontends provide token identifiers for forwarding address derivation
    • This means we can now only forward that token in a single MsgForward execution - as that is the token identifier committed to in the forwarding address
    • No send all denom balances in one go - Relayers can still submit a single tx with n MsgForward payloads
    • No partial failures  - This is actually a safer design decision, no need to worry about multiple token atomicity in execution path
  • There will exist a forwarding address for each unique denom
    • E.g. Address for TIA is different to address for USDC for forwarding to same recipient 0x...abcd on destination domain 1234

Previous issue re. poisoning account with IBC denoms is void, as the token id is provided in rpcs (less ambiguity)
If somebody sends random denom assets to a forwarding address those funds are irrecoverable by design (no poison pill, accepted user risk)

Please disregard the failing Protobuf break-check CI.


NOTE: This PR directly addresses two bug reports submitted by @loopghost. This includes CELESTIA-247 via HackenProof and another submitted privately via email.


Open with Devin

@damiannolan damiannolan self-assigned this Mar 23, 2026
Comment thread tools/spam_txclient/main.go

@damiannolan damiannolan left a comment

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.

Self review

Comment thread test/docker-e2e/e2e_hyperlane_test.go Outdated
Comment thread x/forwarding/client/cli/query.go Outdated
Comment thread x/forwarding/client/cli/query.go Outdated
Comment thread x/forwarding/client/cli/tx.go Outdated
Comment thread x/forwarding/keeper/query_server.go
Comment thread x/forwarding/types/address.go Outdated
@damiannolan damiannolan marked this pull request as ready for review March 23, 2026 16:04
@damiannolan damiannolan requested a review from a team as a code owner March 23, 2026 16:04
@damiannolan damiannolan requested review from ninabarbakadze and removed request for a team March 23, 2026 16:04

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review.

Tip: disable this comment in your organization's Code Review settings.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@rootulp rootulp requested review from evan-forbes and rach-id and removed request for ninabarbakadze March 23, 2026 21:28
@rootulp rootulp changed the title refactor(x/forwarding): add token identifier to address derivation refactor(x/forwarding)!: add token identifier to address derivation Mar 23, 2026
evan-forbes
evan-forbes previously approved these changes Mar 23, 2026
rach-id
rach-id previously approved these changes Mar 24, 2026
rach-id
rach-id previously approved these changes Mar 24, 2026
@loopghost

loopghost commented Mar 24, 2026

Copy link
Copy Markdown

Hi @damiannolan @rootulp @rach-id,

This PR directly addresses two distinct and independent security vulnerabilities I reported through Celestia's security program. Both were submitted with full end-to-end PoCs.

  • Report A (CELESTIA-247): submitted via HackenProof. @rootulp subscribed to it, moved it to triaged, then to in-review, and days later this PR was opened by the team.
  • Report B: submitted via email to Ismail.

These are two independent vulnerabilities with different root causes, different impacts, and different attack flows. Fixing one would not have fixed the other. Both are also distinct from CELESTIA-234, as both were identified and reported after PR #6877 was already merged.

The scope of this refactor directly corresponds to the attack vectors I disclosed, and I would appreciate acknowledgment of this. Specifically:

  1. Reframing the PR title from refactor! to fix!, consistent with how other security-prompted changes in this module have been labeled (e.g., PR fix!: filter unsupported denoms before truncating in Forward #6877 and PR fix!: x/forwarding atomic state token sends #6881 both use fix!). Suggested: fix!(x/forwarding): bind token identity to forwarding address derivation.

  2. Referencing CELESTIA-247 and my email submission in the PR description, consistent with how PR fix!: filter unsupported denoms before truncating in Forward #6877 references CELESTIA-234.

  3. Restoring CELESTIA-247 to triaged status on HackenProof. The usual workflow is to move a report to triaged before beginning work on a fix. I am confused as to why this was reverted given that a fix PR was then opened.

Thank you.

@damiannolan

Copy link
Copy Markdown
Collaborator Author

Hi @loopghost! Thank you for dropping a comment here. I will of course update the PR title and add acknowledgements within the description. Much appreciated for your reports, they have been invaluable! cc. @rootulp for HackenProof status updates

@damiannolan damiannolan changed the title refactor(x/forwarding)!: add token id to address derivation with explicit single token forwarding fix!(x/forwarding): bind token identity to forwarding address derivation Mar 24, 2026
claude[bot]

This comment was marked as resolved.

@damiannolan damiannolan changed the title fix!(x/forwarding): bind token identity to forwarding address derivation fix(x/forwarding)!: bind token identity to forwarding address derivation Mar 24, 2026
@loopghost

Copy link
Copy Markdown

Thank you so much @damiannolan, really appreciate the quick response and the kind words! Super happy to know my contributions have been valuable to the team. I'll definitely keep at it. Looking forward to the updates and to @rootulp's confirmation on the HackenProof side. Let me know if you need anything else from me.

@rootulp

rootulp commented Mar 24, 2026

Copy link
Copy Markdown
Collaborator

Moved CELESTIA-247 to triaged.

Comment thread test/docker-e2e/e2e_hyperlane_test.go
Comment thread x/forwarding/keeper/msg_server_test.go
Comment thread x/forwarding/CLAUDE.md
Comment thread x/forwarding/keeper/msg_server.go
Comment thread test/docker-e2e/e2e_hyperlane_test.go

@rootulp rootulp left a comment

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.

Thanks for the quick turnaround on the fix! 🙏 really appreciate it

Comment thread proto/celestia/forwarding/v1/event.proto
@ninabarbakadze ninabarbakadze added the backport:v8.x PR will be automatically backported to the v8.x branch after merging label Mar 27, 2026
@damiannolan damiannolan added this pull request to the merge queue Mar 27, 2026
Merged via the queue into main with commit 1c37708 Mar 27, 2026
29 of 30 checks passed
@damiannolan damiannolan deleted the damian/add-token-id-to-forwardaddr-derivation branch March 27, 2026 13:38
@damiannolan

Copy link
Copy Markdown
Collaborator Author

@Mergifyio refresh

@mergify

mergify Bot commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

refresh

✅ Pull request refreshed

mergify Bot pushed a commit that referenced this pull request Mar 27, 2026
…ion (#6906)

## Overview

This PR adds the token identifier `HexAddress` to the forwarding address
derivation.
This hoists the trust model off-chain, preventing linear scan of global
permissionless warp tokens.

Below are the outcomes associated with that design decision that affect
this PR.

**Adding the token_id to the forwarding address derivation:**

- Trusted frontends provide token identifiers for forwarding address
derivation
- This means we can now only forward that token in a single MsgForward
execution - as that is the token identifier committed to in the
forwarding address
- No send all denom balances in one go - Relayers can still submit a
single tx with n MsgForward payloads
- No partial failures  - This is actually a safer design decision, no
need to worry about multiple token atomicity in execution path
- There will exist a forwarding address for each unique denom
- E.g. Address for TIA is different to address for USDC for forwarding
to same recipient 0x...abcd on destination domain 1234

Previous issue re. poisoning account with IBC denoms is void, as the
token id is provided in rpcs (less ambiguity)
If somebody sends random denom assets to a forwarding address those
funds are irrecoverable by design (no poison pill, accepted user risk)

Please disregard the failing `Protobuf break-check` CI.

---

**NOTE**: This PR directly addresses two bug reports submitted by
@loopghost. This includes CELESTIA-247 via HackenProof and another
submitted privately via email.

<!-- devin-review-badge-begin -->

---

<a href="https://app.devin.ai/review/celestiaorg/celestia-app/pull/6906"
target="_blank">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open with Devin">
  </picture>
</a>
<!-- devin-review-badge-end -->

(cherry picked from commit 1c37708)

# Conflicts:
#	go.mod
#	test/docker-e2e/e2e_hyperlane_test.go
#	x/forwarding/keeper/msg_server.go
#	x/forwarding/keeper/msg_server_test.go
ninabarbakadze pushed a commit that referenced this pull request Mar 31, 2026
…ion (backport #6906) (#6920)

## Overview

This PR adds the token identifier `HexAddress` to the forwarding address
derivation.
This hoists the trust model off-chain, preventing linear scan of global
permissionless warp tokens.

Below are the outcomes associated with that design decision that affect
this PR.

**Adding the token_id to the forwarding address derivation:**

- Trusted frontends provide token identifiers for forwarding address
derivation
- This means we can now only forward that token in a single MsgForward
execution - as that is the token identifier committed to in the
forwarding address
- No send all denom balances in one go - Relayers can still submit a
single tx with n MsgForward payloads
- No partial failures  - This is actually a safer design decision, no
need to worry about multiple token atomicity in execution path
- There will exist a forwarding address for each unique denom
- E.g. Address for TIA is different to address for USDC for forwarding
to same recipient 0x...abcd on destination domain 1234

Previous issue re. poisoning account with IBC denoms is void, as the
token id is provided in rpcs (less ambiguity)
If somebody sends random denom assets to a forwarding address those
funds are irrecoverable by design (no poison pill, accepted user risk)

Please disregard the failing `Protobuf break-check` CI.

--- 

**NOTE**: This PR directly addresses two bug reports submitted by
@loopghost. This includes CELESTIA-247 via HackenProof and another
submitted privately via email.



---

<a href="https://app.devin.ai/review/celestiaorg/celestia-app/pull/6906"
target="_blank">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open with Devin">
  </picture>
</a>

<hr>This is an automatic backport of pull request #6906 done by
[Mergify](https://mergify.com).
<!-- devin-review-badge-begin -->

---

<a href="https://app.devin.ai/review/celestiaorg/celestia-app/pull/6920"
target="_blank">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open with Devin">
  </picture>
</a>
<!-- devin-review-badge-end -->

---------

Co-authored-by: Damian Nolan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:v8.x PR will be automatically backported to the v8.x branch after merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants