Skip to content

MF3-L13: document asset-symbol equivalence operator invariant#818

Merged
philanton merged 3 commits into
fix/audit-findings-finalx3from
fix/mf3-l13
Jun 8, 2026
Merged

MF3-L13: document asset-symbol equivalence operator invariant#818
philanton merged 3 commits into
fix/audit-findings-finalx3from
fix/mf3-l13

Conversation

@philanton

Copy link
Copy Markdown
Contributor

Audit finding MF3-L13

The state validator lets off-chain credit with no HomeChannelID bind to any chain/token the user proposes at first channel creation, enforcing only that the asset symbol matches (pkg/core/state_advancer.go:34-55). Consequently credit can be redeemed from any configured token inventory sharing that symbol, independent of which inventory originally backed it.

Assessment

This is intended behaviour of the unified asset model — a unified asset is identified solely by its symbol, and all chain-specific tokens configured under that symbol are fungible 1:1 representations. Leaving the chain/token open until the user binds it is exactly what enables cross-chain redemption. Binding credit to its origin token would remove that feature.

The harmful scenario requires the node operator to map economically non-equivalent tokens (e.g. a test token and production USDC) under a single symbol. In that case the operator drains their own inventory through their own misconfiguration — no external trust boundary is crossed. Token equivalence cannot be verified programmatically.

Severity: informational / config hardening. No validation or provenance change.

Change

Make the operator obligation explicit:

  • docs/protocol/security-and-limitations.md — new Asset-symbol equivalence trust assumption.
  • nitronode/store/memory/asset_config.go — equivalence warning on the AssetConfig doc comment, cross-referencing the protocol doc.

🤖 Generated with Claude Code

MF3-L13: the unified asset model treats all chain-specific tokens
configured under one symbol as fully fungible 1:1 representations. Off-chain
credit can therefore be redeemed from any token inventory sharing the asset
symbol, independent of which inventory originally backed it. This is intended
behaviour enabling cross-chain redemption; the only harmful case is an operator
mapping economically non-equivalent tokens (e.g. a test token and production
USDC) under one symbol. Equivalence cannot be verified programmatically.

Make the operator obligation explicit in the security/limitations trust
assumptions and on the AssetConfig struct doc. No validation change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64fbea87-f5c2-45bd-bd39-130c65070e4f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mf3-l13

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@philanton philanton changed the base branch from main to fix/audit-findings-finalx3 June 5, 2026 11:09

@ihsraham ihsraham 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.

Directionally this is the right framing if L-13 is being handled as an accepted operator-configuration risk. I left one closure note: since the mitigation is documentation-only, the invariant should also be visible in the asset configuration path before we call this closed.

- **Cross-chain relay** — nodes relay cross-chain state updates; trustless cross-chain enforcement is not yet implemented
- **Timely enforcement** — nodes are expected to submit checkpoints when requested; delayed enforcement may affect user experience but does not compromise single-chain asset safety
- **Off-chain transfer routing** — when a user sends funds off-chain to another party, the node must countersign both the sender's state (decreasing their allocation) and the receiver's credit state (increasing theirs); the on-chain contract cannot enforce atomicity between two independent channel updates. A malicious node could apply the sender's state while withholding the receiver's credit, capturing the transferred funds. Users must trust the node to faithfully execute both legs of every off-chain transfer.
- **Asset-symbol equivalence** — the node operator controls which chain-specific tokens are configured under a single unified asset symbol. The protocol treats all tokens sharing a symbol as fully fungible 1:1 representations of the same asset, so off-chain credit denominated in that asset can be redeemed from any of those token inventories regardless of which one originally backed it (the validator binds unchanneled credit to the chain/token chosen at first channel creation, enforcing only that the asset symbol matches). This is intended behaviour that enables cross-chain redemption. Operators MUST therefore configure only economically equivalent (1:1 redeemable) tokens under one symbol; grouping non-equivalent tokens (e.g. a test token and production USDC) under the same symbol would let credit sourced from the cheap inventory be redeemed against the valuable one. Token equivalence cannot be verified programmatically and is an operator configuration responsibility.

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.

Good call documenting the unified-asset assumption here. This explains why binding detached credit to an origin token would conflict with intended cross-chain redemption.

Missing piece for L-13 closure: the same warning is not present where operators actually configure this risk, such as the nitronode/README.md config/assets.yaml example and the Helm assets.yaml path. Since the mitigation is docs-only, could we also put the 1:1 equivalence requirement on those asset-config surfaces, or explicitly mark the audit item as accepted/documented operator risk?

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.

Yeah, good catch — the warning was only in the protocol doc and the AssetConfig godoc, neither of which an operator editing YAML actually sees.

Added the 1:1 equivalence warning to the config surfaces in 17af52e: the config/assets.yaml example in nitronode/README.md and the Helm prod/stress/sandbox assets.yaml files, each linking back to security-and-limitations. So L-13 stays a documented operator-config risk, just now visible at the point of configuration.

The asset-symbol 1:1 equivalence invariant was documented only in the
protocol security doc and the AssetConfig struct godoc. Operators editing
asset YAML never saw it. Add the warning to the README config/assets.yaml
example and the Helm prod/stress/sandbox assets.yaml files, each linking
back to the security-and-limitations doc. Closes the L-13 docs-only
mitigation gap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@ihsraham ihsraham 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.

Approving for L-13. Treating this as a documented operator-config risk, the warning is now in the protocol security doc, the config/assets.yaml README example, and the Helm asset config surfaces, so operators see the 1:1 equivalence requirement at configuration time.

No runtime enforcement was added, but that matches the docs-only mitigation path here. No blockers from me.

@nksazonov nksazonov left a comment

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.

Please, add the same information in more detailed and shortened version to contracts/SECURITY.md and protocol-description.md respectively.

…protocol-description

MF3-L13: extend the asset-symbol equivalence operator invariant to the two
remaining security surfaces. contracts/SECURITY.md gets a detailed
"Asset-symbol equivalence" trust assumption; protocol-description.md gets a
shortened bullet in the security model summary. No validation change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@philanton

Copy link
Copy Markdown
Contributor Author

@nksazonov done in 81c134e. Added the detailed version as an Asset-symbol equivalence trust assumption in contracts/SECURITY.md, and a shortened bullet in the security model summary of protocol-description.md. Both link back / align with the full statement in security-and-limitations.md.

@nksazonov nksazonov left a comment

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.

Well done!

@philanton philanton merged commit 8eea566 into fix/audit-findings-finalx3 Jun 8, 2026
7 checks passed
@philanton philanton deleted the fix/mf3-l13 branch June 8, 2026 12:32
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