Multichain trading vault: Sui hub / Robinhood spoke (full plan implementation) - #527
Open
ewitulsk wants to merge 23 commits into
Open
Multichain trading vault: Sui hub / Robinhood spoke (full plan implementation)#527ewitulsk wants to merge 23 commits into
ewitulsk wants to merge 23 commits into
Conversation
Hub-master accounting, dumb spoke vaults, transport-agnostic messaging with a first-party attestor endpoint (required for Robinhood Chain), CCTP as a curator-executed vault integration, and vault-custodied HyperCore trading via CoreWriter. Captures the 2026-08-28 design Q&A, external-dependency checks, build order, and open questions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Per-spoke depositor whitelists, USDG on the Robinhood spoke, tranche support with hub-only accounting, no bridge amount limits, flip-a-switch network config, and a bridge-adapter abstraction (CCTP + Across) with the Robinhood lane selection left open pending bridge validation. Adds the attestor-key rationale and the raw-facts-only spoke messaging principle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Cut the Hyperliquid spoke (HyperCore/CoreWriter, Wormhole lane) and all vault-level bridge integrations (CCTP, Across). Keep cross-chain deposits/withdrawals and a curator-controlled spoke integration interface with zero registered integrations. Add the spoke solvency cap for withdrawals, since no hub-to-spoke funding path exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Withdrawals burn in full at hub ACK with a spoke-side FIFO payout queue (rebalance integration becomes a mainnet launch gate); drop the separate attestor keypair for a relayer-sender-gated endpoint; dual-oracle USDG feed (Switchboard on-demand guaranteed, Pyth when cataloged) switchable via the OracleRegistry pin; faucet-mintable TUSDG testnet mock; role-based governance with transferable admin on both chains. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Correct the wrong claim that no third-party messaging serves Robinhood Chain: both LayerZero V2 and Chainlink CCIP cover the Sui<->Robinhood lane end-to-end, so the protocol ships both as endpoint modules (one active per spoke, admin-switchable) and the relayer-gated endpoint becomes dev/test-only. Make hub-tracked payables and NAV-net-of-queue accounting explicit; governance proposal confirmed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Lock the last two decisions (vault-held message-fee pot; LayerZero primary / CCIP secondary transport) and consolidate all review rounds into one final design doc: locked decision list, fee-pot mechanics, transport roles in the build order, and a closing section of implementation-time checks and accepted limitations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Phase 1-3 of docs/multichain-vault-plan.md: - rust-backend/crates/vault-messages: canonical wire format + golden fixtures (source of truth for the Move and Solidity codecs). - trading-vault-v2: wire codec, spoke state, endpoint layer with dev relayer transport, multichain message handlers (deposit notice / withdraw request / payout receipt / state sync / config sync), appraisal spoke legs with payables netted from NAV, protocol-fee escrow, close/unbind drain guards. 141/141 Move tests green (115 existing + 26 new); layout-incompatible change, fresh publish. - evm-contracts: Foundry workspace with SpokeVault (fund states, whitelist, payout queue, fee pot, roles), Relayer/LayerZero/CCIP endpoints, TUSDG mock, vendored OZ v5.4.0 (contracts only). 61/61 forge tests green incl. byte-exact golden fixtures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
- contracts/endpoint-layerzero: real OApp integration (lz_receive/ lz_send/confirm, peer + eid-mapping admin) against LayerZero-v2 Sui packages, pinned rev; builds + config-surface tests green. - contracts/endpoint-ccip: CCIP receiver-registry integration (ccip_receive via Any2SuiMessage consume, onramp ccip_send) against chainlink-sui packages, pinned rev; builds + tests green. - frontend: /spoke screen (viem-only EVM wallet, deposit/reclaim/ withdraw/payout-queue/faucet panels, per-network spoke config); typecheck + production build pass. - evm-contracts: stop tracking forge build artifacts. - API_DELTA.md + plan doc status updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Phase 4 of docs/multichain-vault-plan.md: ordered per-lane message queues in Postgres, hub PTB construction (appraisal + spoke legs + attestations + handlers + send), EVM delivery and syncState/ConfigSync cranks, tx-alerting-convention alerts (tx-failed-vault-messenger, queue-stalled, payout-queue-aged, fee-pot-low), health/messages/lanes API, and full deployment registration mirroring cctp-relay (ecr.tf left for a targeted apply, per its README). Workspace cargo check clean; 20/20 unit tests over mocked chain traits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The session's git push credentials are down; this dispatch-only workflow regenerates rust-backend/Cargo.lock (missing vault-messenger's token-info-client entry) on a runner and commits it back. Removed once the lock commit lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
Two red checks on the PR head: - affected-filter: deployment/resolve_network.py fails closed on vault-messenger declaring hub.network in a table. Move `network` to the top level (config struct + all three profiles), and flip the prod profile to the testnet set it would actually run today (prod's env is testnet until the mainnet migration, same as cctp-relay documents; a mainnet declaration there breaks the guard's unanimity for every service). The mainnet flip stays documented in the file header. - move (endpoint-layerzero) / move (endpoint-ccip): the pinned upstream LayerZero-v2 / chainlink-sui deps need a newer VM at test runtime than the matrix default (verifier error 2017 / MISSING_DEPENDENCY under mainnet-1.75.2 — the SO-335 false-positive class). Per-package sui_version override to testnet-1.78.1, which these packages' tests pass on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements docs/multichain-vault-plan.md end to end: Sui hub / Robinhood spoke multichain trading vault with hub-master accounting, a dumb spoke vault, transport-agnostic messaging (LayerZero primary, CCIP secondary, dev relayer for CI), and no hub↔spoke fund movement (rebalance integration is a mainnet launch gate).
What's in here
Wire format (phase 1) —
rust-backend/crates/vault-messages: canonical big-endian fixed-width layout for the 7 hub↔spoke messages + committed golden fixtures. The Move and Solidity codecs are pinned to those fixtures byte-for-byte (tests in all three languages).Hub Move (phase 2) —
contracts/trading-vault-v2gainswire,spoke,endpoint(+ sharedEndpointRegistry),endpoint_relayer(dev/CI transport),multichain(spoke binding, ordered-lane handlers, ConfigSync),asset_markers. Key semantics:TrancheBookas wallet positions (tranches supported; entry/exit haircuts, lockups, exit-crystallized fees identical to hub deposits);StateSyncis a freshness proof + reconciliation cross-check, never a value source.payablesare netted out of NAV (§5.1); protocol fee cut mints into an admin-claimable escrow position (cash lives on the spoke).record_spoke_state); a dark spoke blocks NAV vault-wide (fail-safe). Close is blocked until spokes are drained + unbound.TradingVault.spokes,Appraisalspoke fields): ships via fresh publish, per API_DELTA.md.EVM spoke (phase 3) — new
evm-contracts/Foundry workspace:SpokeVault(pending/active/reserved fund states, per-chain depositor whitelist, deposit/reclaim, per-tranche withdraw + FIFO payout queue, native fee pot, endpoint-gatedhandleMessagewith strict seq, ConfigSync-driven curator/endpoint/integration-set — none of those are local roles, stale-heartbeat freeze, OZAccessControlDefaultAdminRulestwo-step admin),Relayer/LayerZero/CCIPendpoints,TUSDGfaucet mock, vendored OZ v5.4.0 (contracts only). 63/63 forge tests incl. golden fixtures, an endpoint-switch drill, and the deploy-script tests below.Transports (phases 5–6) —
contracts/endpoint-layerzero(real OApp integration:lz_receive/lz_send/confirm, peer + eid mapping) andcontracts/endpoint-ccip(receiver-registry +Any2SuiMessageconsume, OnRampccip_send), both building against pinned upstream LayerZero-v2 / chainlink-sui packages, both in the Move CI matrix.Off-chain (phase 4) —
rust-backend/services/vault-messenger: ordered per-lane delivery queues in Postgres, hub PTB construction (appraisal legs + attestations + handler + send), EVM delivery,syncState/ConfigSync cranks, alerting per tx-alerting convention (tx-failed-vault-messenger, queue-stalled, payout-queue-aged, fee-pot-low), small HTTP API, deployment registration mirroring cctp-relay. 24/24 unit tests.Frontend (phase 7) —
/spokescreen (viem-only injected wallet): deposit/reclaim with pending→active status, per-tranche withdraw + payout-queue view, status strip (pause/risk-off/heartbeat/fee pot), testnet TUSDG faucet. Typecheck + production build pass.One place to write addresses (follow-up in this same PR)
The redeploy pipeline is now the single writer of every multichain address, and token-info the single server:
crates/deploymentsgainsendpointLayerzero/endpointCcip/multichain { endpointRegistryId, hubChainId, spokes. }blocks onPackageInfo(all optional, absent-not-null; serde round-trip tests). token-info servesPackageInfoverbatim, so/package-infopicks these up with zero service changes;token-info-clientgains typed accessors.deployment-managergains--deploy-endpoints(publishes both Sui transport packages, extractsLzTransport/OApp/CcipTransportshared objects, refreshesmultichain.endpointRegistryIdfrom the trading-vault publish, cctp-style carry-forward),--hub-chain-id, and--record-evm-spoke(validating read-merge-write of the forge deploy artifact intomultichain.spokes).redeploy-contract.yml— new dispatch inputsdeploy_endpointsanddeploy_evm_spoke; the latter runsevm-contracts/script/DeploySpoke.s.sol(foundry-toolchain, repo secretsSPOKE_RPC_URL+EVM_DEPLOYER_KEY, params in repo variableEVM_SPOKE_PARAMS) and folds the artifact into deployments.json before the existing commit step — EVM addresses ride the same commit, bundle, and token-info restart as Sui ids. Proven end-to-end against anvil (script deploy →castchecks →--record-evm-spokemerge in the exact reader shape).vault_id, RPCs, intervals stay config); the frontend populates the spoke config from/package-info's multichain block (static map reduced to rpc/explorer metadata). deployment-manager 12/12, deployments 7/7, vault-messenger 24/24, forge 63/63.Not done in this PR (honest gaps)
--deploy-endpointsand the messenger's PTB shapes (each fails loudly if wrong).rust-backend/Cargo.lockone line short (the file exceeded the API payload limit). Fixed on-branch: a temporary push-triggered workflow regenerated the lock on a runner (commit f0856e2, byte-identical to the local tree) and was then removed (fbf5fa4/f9fe1e8 add it, a9580fe deletes it).cargo build --lockedworks on the branch.Verification
sui move test(testnet-v1.78.1): trading-vault-v2 141/141; endpoint-layerzero 2/2; endpoint-ccip 2/2.cargo test -p deployment-manager --test deploy_build(pinned deploy compiler): pass, incl. both endpoint packages.forge test: 63/63; anvil deploy-script proof run green.cargo checkworkspace;cargo testfor vault-messages, vault-messenger (24/24), deployments (7/7), deployment-manager (12/12), token-info-client (6/6).🤖 Generated with Claude Code
https://claude.ai/code/session_01EHimiGNoVjEP65m8dch776