Skip to content

fix(cluster-tool): stop passing a reserve code on collateral deposits (SOL-432) - #96

Open
valthon wants to merge 1 commit into
masterfrom
fix/SOL-432-drop-deposit-reserve-code
Open

fix(cluster-tool): stop passing a reserve code on collateral deposits (SOL-432)#96
valthon wants to merge 1 commit into
masterfrom
fix/SOL-432-drop-deposit-reserve-code

Conversation

@valthon

@valthon valthon commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Coordinated change — SOL-432. Three identically-named branches
(fix/SOL-432-drop-deposit-reserve-code) across wire-solana, wire-ethereum
and wire-tools-ts. The deposit action's reserve_code field is caller-supplied
and unused; all three sides must land together for the e2e flow-test workflow
to be able to verify them.

Paired with: Wire-Network/wire-solana#515, Wire-Network/wire-ethereum#197

The harness threaded WireUnderwriterTool.PrimaryReserveCode into both
non-native collateral deposit steps -- SVM opp-outpost::deposit_non_native and
EVM OperatorRegistry.depositNonNative. SOL-432 (CertiK WNS-165) removes that
parameter from both outposts, so the harness stops supplying it.

The depot is the evidence that 0 is the normative value, and that a reserve code
never belonged on a deposit at all:

  • wire-sysio/libraries/opp/proto/sysio/opp/attestations/attestations.proto
    declares OperatorAction.reserve_code (field 9) "SLASH-only ... Empty (0)
    for non-SLASH action types."
  • wire-sysio/contracts/sysio.msgch/src/sysio.msgch.cpp dispatch_operator_action
    forwards ACTION_TYPE_DEPOSIT_REQUEST to opreg::depositinle as
    (account, chain_code, token_code, amount, op_address.kind,
    op_address.address, original_message_id) -- oa.reserve_code is not read.
  • The depot's own sysio.opreg.cpp build_deposit_action leaves it
    default-initialized (0); only build_slash_action populates it.

Removal beats validation on the outposts: validating the code would require
resolving a Reserve on the collateral path, coupling the collateral custody
surface to the reserves surface. .claude/rules/outpost-three-concerns.md
permits exactly one cross-concern token edge -- the slash-to-reserve hop -- and
forbids adding another. PrimaryReserveCode had no other reader once both call
sites dropped it, so the constant is deleted; the identically-named constants in
the flow-swap-* / flow-underwriter-slashing packages are a DIFFERENT symbol
on the reserves/swap path and are untouched, as are
SolanaOutpostBootstrapper.PrimaryReserveCodename and RegistrySteps'
regreserve registration.

Per .claude/rules/no-back-compat-before-release.md the signature churn is free
pre-release, so the field is deleted from both DepositNonNativeInput shapes
rather than made optional.

Mutation -> test mapping: re-introduce reserveCode on either StepInput and the
exact toEqual assertions in EthereumCollateralTool.test.ts and the new
SolanaCollateralTool.test.ts "captures the full typed input" cases fail --
toEqual is exact, so it pins the ABSENCE of the field, not just the presence of
the others. Re-adding the positional argument to the anchor depositNonNative
call or the ethers DepositNonNativeArgs tuple is a compile error against the
regenerated IDL / new ABI. The SVM factory had NO coverage before this change;
per STYLE.md ("unit tests required for every symbol") the modified
planNonNativeDeposit / runNonNativeDeposit pair now ships the same two cases
the EVM side already had.

Lands together with the wire-solana change (deposit_non_native) and the
wire-ethereum change (OperatorRegistry.depositNonNative); this repo consumes
both signatures, so building it against un-updated outposts fails. The three are
verified as one combination by the e2e flow-test workflow and must merge
together.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01NoaXitAvpNSNj7114S9338


🤖 Generated with Claude Code

https://claude.ai/code/session_01NoaXitAvpNSNj7114S9338

… (SOL-432)

The harness threaded `WireUnderwriterTool.PrimaryReserveCode` into both
non-native collateral deposit steps -- SVM `opp-outpost::deposit_non_native` and
EVM `OperatorRegistry.depositNonNative`. SOL-432 (CertiK WNS-165) removes that
parameter from both outposts, so the harness stops supplying it.

The depot is the evidence that 0 is the normative value, and that a reserve code
never belonged on a deposit at all:

  * wire-sysio/libraries/opp/proto/sysio/opp/attestations/attestations.proto
    declares `OperatorAction.reserve_code` (field 9) "SLASH-only ... Empty (0)
    for non-SLASH action types."
  * wire-sysio/contracts/sysio.msgch/src/sysio.msgch.cpp `dispatch_operator_action`
    forwards ACTION_TYPE_DEPOSIT_REQUEST to `opreg::depositinle` as
    (account, chain_code, token_code, amount, op_address.kind,
    op_address.address, original_message_id) -- `oa.reserve_code` is not read.
  * The depot's own `sysio.opreg.cpp build_deposit_action` leaves it
    default-initialized (0); only `build_slash_action` populates it.

Removal beats validation on the outposts: validating the code would require
resolving a Reserve on the collateral path, coupling the collateral custody
surface to the reserves surface. `.claude/rules/outpost-three-concerns.md`
permits exactly one cross-concern token edge -- the slash-to-reserve hop -- and
forbids adding another. `PrimaryReserveCode` had no other reader once both call
sites dropped it, so the constant is deleted; the identically-named constants in
the `flow-swap-*` / `flow-underwriter-slashing` packages are a DIFFERENT symbol
on the reserves/swap path and are untouched, as are
`SolanaOutpostBootstrapper.PrimaryReserveCodename` and `RegistrySteps`'
`regreserve` registration.

Per .claude/rules/no-back-compat-before-release.md the signature churn is free
pre-release, so the field is deleted from both `DepositNonNativeInput` shapes
rather than made optional.

Mutation -> test mapping: re-introduce `reserveCode` on either StepInput and the
exact `toEqual` assertions in `EthereumCollateralTool.test.ts` and the new
`SolanaCollateralTool.test.ts` "captures the full typed input" cases fail --
`toEqual` is exact, so it pins the ABSENCE of the field, not just the presence of
the others. Re-adding the positional argument to the anchor `depositNonNative`
call or the ethers `DepositNonNativeArgs` tuple is a compile error against the
regenerated IDL / new ABI. The SVM factory had NO coverage before this change;
per STYLE.md ("unit tests required for every symbol") the modified
`planNonNativeDeposit` / `runNonNativeDeposit` pair now ships the same two cases
the EVM side already had.

Lands together with the wire-solana change (`deposit_non_native`) and the
wire-ethereum change (`OperatorRegistry.depositNonNative`); this repo consumes
both signatures, so building it against un-updated outposts fails. The three are
verified as one combination by the e2e flow-test workflow and must merge
together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NoaXitAvpNSNj7114S9338
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.

1 participant