Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SPINBRIDGE

ci

A clean-room, MIT-licensed EVM↔EVM bridge: M-of-N attester settlement over an xERC20 (ERC-7281) token layer, deployed at the same address on every chain.

send()  burn xSCI on A  ──Sent(opId, Message)──▶  ≥M of N attesters sign (EIP-712, B's domain, B's epoch)
                                                        │
deliver(Message, sigs) on B: peer ✓ route ✓ replay ✓ quorum ✓ ──▶ mint xSCI (within THIS bridge's daily limit)
  • Settlement = validator set. SpinBridge.deliver verifies ≥ threshold attester signatures on-chain (strictly-ascending unique signers, OZ ECDSA, domain bound to the destination chain + bridge + attester epoch). Delivery is permissionless.
  • Token = xERC20. SpinXERC20 grants each bridge its own linear-refilling daily mint and burn limit — the issuer, not the bridge, decides the blast radius. SpinXERC20Lockbox wraps a canonical asset (SCIEN·TIFIC) 1:1 on its home chain; SpinBridge.sendCanonical locks + burns in one transaction.
  • Same address everywhere. One london artifact, CREATE2 through 0x4e59…956C; factory, token and bridge land at identical addresses on all 9 rail chains (incl. Zilliqa 32769). Proven on two anvils.
  • No upgrade path, no arbitrary calls, no standing approvals, no zero-default trust. Attester rotation bumps an epoch that voids outstanding signatures without orphaning undelivered messages.

Status: fully proven locally, never deployed. 48 forge tests (3 fuzz properties × 512 runs), 40 relayer self-tests, 30-assertion two-chain end-to-end — see contracts/tests/RESULTS.md. Not audited.

Layout

contracts/          Foundry (solc 0.8.24, evm london, OZ 5.0.2)
  src/SpinBridge.sol                 the gateway (send / sendCanonical / deliver / governance)
  src/SpinBridgeMessage.sol          Message struct, EIP-712 typehash, structHash, opId
  src/token/SpinXERC20*.sol          xERC20 token, factory (CREATE2), lockbox — ported from SPINTRADE, hardened
  test/                              SpinXERC20.t.sol · SpinBridge.t.sol · SpinBridge.fuzz.t.sol
  tests/RESULTS.md                   pasted evidence from the last full run
  script/DeploySpinBridge.s.sol      the ONLY signing path: predict → deploy-if-missing → wire → deployments/<chainId>.json
relayer/            attester + relayer (Node, ethers v6 vendored/npm; dry-run default; keys via env only; pure logic + selftest)
sdk/                client SDK — js/ (SpinBridgeClient: quote / buildSend / send / status / waitDelivered) and python/ (spinbridge-sdk,
                    httpx-only, unsigned; used by SPINTRADE's "bridged route" venue); vectors.json pins selectors/topics for both
scripts/            e2e-anvil.sh + e2e.mjs — two chains, real deploy, real relayer, 30 assertions
deploy/             spinbridge-legs.json (rail status), salts.json, deploy-multichain.mjs (predict/probe only — never signs)
docs/               ARCHITECTURE · SECURITY · DEPLOY · RELAYER · INTEGRATION (SPINBRIDGE ⟂ SPINTRADE ⟂ wARbridge boundary) · TECH_MAP · REFERENCE_SET
.github/workflows/  ci.yml — forge (london + gascheck) · relayer + JS SDK selftests (node 20/22) · Python SDK · two-anvil e2e for both asset families

Quickstart

cd contracts && bash scripts/link-libs.sh && forge test        # 48/48
node ../relayer/selftest.mjs                                    # 40/40
bash ../scripts/e2e-anvil.sh                                    # 30/30 on two anvils (needs anvil, forge, node)
node ../deploy/deploy-multichain.mjs --offline                  # predicted rail addresses

Design decisions (short)

decision why
validator set, not intent/relayer or aggregation it is the trust model already audited for the SPINTRADE lockbox rail (multisig-timelock oracle), it is buildable clean-room, and Across (BUSL) / Chainflip (own chain) were not viable bases
xERC20 token layer per-bridge daily limits bound the loss from any bridge failure and keep the issuer sovereign; SCIEN·TIFIC is fixed-supply so a lockbox is required anyway
epoch in the digest, not the opId rotation kills stale signatures but never strands a message
london for the whole rail one initcode hash ⇒ one address, and Zilliqa EVM needs it
fee in the bridged token, ≤ 34 bps, immutable collector matches the BANKON fibonacci ladder cap; a caller can never set the fee
guardian pause-only fast stop without a fast restart key
token decimals set at deploy (12 for xwAR) the lockbox mints base units 1:1, so the xERC20 must mirror its canonical's decimals or every wallet misdisplays by 10^6
SPINTRADE/wARbridge stay outside see docs/INTEGRATION.md: SPINBRIDGE is transport; CEX/AR/custody live elsewhere and call the SDK

Licence

MIT. No BUSL/GPL/LGPL code is included; the reference inventory in docs/REFERENCE_SET.md was read, not copied. The xERC20 port is in-house SPINTRADE code (MIT).

About

SPINBRIDGE — clean-room MIT EVM↔EVM bridge: M-of-N attester settlement over an xERC20 (ERC-7281) token layer, same address on every chain

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages