Skip to content
gosh-shPublic

About

Acki Nacki - EVM Bridge

Resources

Stars

2 stars

Watchers

1 watching

Forks

Latest commit

 

History

284 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Acki Nacki Bridge

A cross-chain bridge between Ethereum and Acki Nacki, with zero-knowledge proofs on both directions of travel. USDC is custodied by AckiNackiBridge.sol on Ethereum; Acki Nacki state is committed on-chain from Halo2 proofs verified by SHPLONK aggregator verifiers deployed as Yul bytecode.

Where the truth is. This README orients you; it is not a specification. The document derived from the sources line by line, with a file:line citation for every behavioural claim, is docs/EVM-contracts-spec.md; DOCS.md is the register of current documentation. When any prose disagrees with the code, the code wins.


The current deployment

Arbitrum Sepolia ↔ shellnet, deployed from tag v0.7.0. The CLI, relayers and web form take their addresses from configuration.

Arbitrum Sepolia (chain id 421614)

AckiNackiBridge 0x3FB082a905a895151224F6d93bD074E816338638
deployment block 323405848
USDC 0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d

Acki Nacki (shellnet)

eccUSDCBridge 0:1a1a…1a1a
version 1.14.0, code hash 5cada5db…
Arbitrum block verifier (421614, parent chain Sepolia) 0:f1def367fa6bc245589bfa7bcf54937f5c926624d29e59e19826ee9033f14108
Sepolia beacon light client 0:9121fc37c8ac55a4fc42a73bccaf725cb0d87b9a8c7dfbc6dd2be7d1690d8462
GraphQL https://shellnet.ackinacki.org/graphql

What to set

BRIDGE_ADDRESS=0x3FB082a905a895151224F6d93bD074E816338638
BRIDGE_DEPLOY_BLOCK=323405848
FROM_BLOCK=323405848
RPC_URL=https://arbitrum-sepolia-rpc.publicnode.com

deposit-relayer arbitrum-anchors needs an Arbitrum RPC that keeps a few minutes of state; the public endpoints do not (crates/deposit-relayer-daemon/docs/operator_runbook.md, section 9).


The two directions

Ethereum → Acki Nacki (deposit). The user approves USDC and calls deposit(uint256 amount, bytes32 anAccount). The contract takes custody via transferFrom and emits a Deposit event carrying the Acki Nacki destination. Nothing is verified on the Ethereum side. Off-chain, deposit-prover/ proves the event's presence in a real Ethereum block (receipt-trie inclusion + log binding, with a keccak coprocessor), and the AN-side USDCBridge consumes that Halo2 proof natively through the ZKHALO2VERIFYWITHVK TVM opcode, then mints. Each transfer is capped at 50 USDC, and the outstanding principal at 10,000 USDC per L1 chain.

Acki Nacki → Ethereum (state attestation + payout). Three permissionless entrypoints:

Call Does
verifyBlock Advances the rolling commitment to AN state from a cross-bound pair of proofs: Circuit 1A (≥ 2/3 attestation quorum) or 1B (> 1/2 split), plus Circuit 2 (layer-hash movement).
applyBkSetUpdate Rotates the AN validator-set (BK-set) commitment through a 16-leaf, depth-4 block-id tree.
withdrawByProof Pays out USDC against a Circuit-4 proof of a WithdrawalInitiated event, anchored into state that verifyBlock already recorded. Nullifier-guarded and chain-id scoped.

There is no refund-style withdraw(depositId, …); it was retired. The owner can pause the bridge (pause() / unpause(), read back with paused()): while it is paused, deposit, verifyBlock, applyBkSetUpdate and withdrawByProof revert with BridgePaused(), and the owner's AAVE management stays available. There is no upgrade path — every verifier binding is immutable, so replacing a verifier means deploying a new bridge.

Idle USDC can be routed into AAVE V3 by the owner. That module cannot reach user principal: yield collection is bounded by the surplus above the book value of user deposits, and the functions that collect it do not appear in the principal-accounting equation at all. Contract detail in docs/EVM-contracts-spec.md §10; the operator runbook is docs/aave-yield.md.


Architecture

Every component and the interface each connection goes through, with its call site in the code: docs/bridge-components.md.

                 Ethereum → Acki Nacki (deposit)
  user ──approve+deposit──▶ AckiNackiBridge ──Deposit event──▶ tx receipt log
                                  │                                 │
                            custody (USDC)                    MPT receipt proof
                                  │                                 ▼
                            AAVE V3 (optional)          deposit-prover (Halo2, off-chain)
                                                                    │
                                                        SHPLONK proof + 12 public inputs
                                                                    ▼
                                                    AN USDCBridge.finalizeDeposit
                                                    (ZKHALO2VERIFYWITHVK opcode)

                 Acki Nacki → Ethereum (state + payout)
  AN node ──GraphQL──▶ bridge-prover-libraries ──Circuits 1A/1B, 2, 4──▶ bridge-relayer-daemon
                                                                          │
                                              verifyBlock / applyBkSetUpdate / withdrawByProof
                                                                          ▼
                                                                  AckiNackiBridge
                                                                          │
                                    Primary / Fallback / LayerHashes / BridgeWithdrawal adapters
                                                                          ▼
                                              ShplonkHalo2Verifier ──▶ Yul Halo2Verifier (CREATE)

Repository layout

Path What lives there
contracts/ethereum/src/ The bridge, four verifier adapters, the SHPLONK shim, oracles. Solidity 0.8.19, Foundry.
contracts/ethereum/verifiers/ Production SHPLONK Yul creation bytecode (.bin) per circuit, the generated Solidity source (.sol) it compiles from, and reference calldata. The .bin is what deploys; the .sol is what aggregate-proof self-checks a proof against.
contracts/ethereum/script/ Deploy scripts; ShplonkDeployLib.sol wires .bin → shim → typed adapter.
deposit-prover/ ETH → AN deposit proof (Halo2 on axiom-eth: receipt MPT, log binding, keccak coprocessor).
crates/deposit-relayer-daemon/ Watches the Deposit log, drives the prover, submits finalizeDeposit on AN.
crates/deposit-chain-ids/ The single allowlist of deposit source chains, shared by prover and relayer.
crates/bridge-prover-libraries/ AN-side prover: block-id tree, bridge state, live driver, Circuit-4 event witness. Standalone workspace.
crates/bridge-relayer-daemon/ AN → ETH relayer. src/withdraw_e2e/ is the in-process withdrawal pipeline behind relayer withdraw-e2e.
crates/ackinacki-bridge/ End-user CLI: withdraw moves USDC from an Acki Nacki multisig to an EVM recipient, deposit from an EVM wallet to an Acki Nacki account. Counterpart to the relayers — the daemons own the continuous streams, this owns one withdrawal or one deposit. Installed from published releases, see QUICKSTART.md.
crates/bridge-snark-utils/, crates/bridge-evm-aggregator/ Prover orchestration and the R15 SHPLONK aggregator.
frontend/ WASM deposit UI (Yew).
docs/ EVM-contracts-spec.md and the rest of the current documentation; the register is DOCS.md.

Cargo workspaces. The root workspace holds crates/eth-frontend, crates/acki-nacki-interface and crates/deposit-chain-ids. Everything else is excluded and built standalone, because the Halo2 forks in play cannot share a dependency tree: deposit-prover/ (axiom-eth), crates/bridge-prover-libraries/ (gosh-fork halo2-base), crates/bridge-snark-utils/, crates/deposit-relayer-daemon/, and frontend/. The AN→ETH relayer crates/bridge-relayer-daemon/ and the end-user CLI crates/ackinacki-bridge/ are symlinked members of crates/bridge-prover-libraries/ and build only from there.


Build and test

make setup                 # toolchains and dependencies
make build                 # Rust workspace + Solidity
make test                  # both test suites
make test-all              # every crate's tests + forge test
make check                 # format-check + lint + test

Run make pre-push before pushing: on top of make check it covers the relayer, the aggregator and forge coverage, none of which any GitHub pipeline runs. The CI section of AGENTS.md lists what it does and does not cover.

The end-user CLI is not built from here at all — crates/ackinacki-bridge/scripts/install.sh downloads the published binaries (the CLI, the prover subprocess it shells out to, the verifier bytecode and sources, and the deposit prover), so an operator needs neither Rust nor a checkout. Start at QUICKSTART.md.

Contracts on their own:

cd contracts/ethereum
forge test                                                   # full suite
forge test --match-contract AckiNackiBridgeWithdrawByProof -vv
FOUNDRY_PROFILE=fork forge test --match-contract AaveFork     # needs a mainnet RPC

The suite is inventoried per file, with what each one covers, in docs/EVM-contracts-spec.md §13. Two build settings there are deliberate and worth knowing before you touch them: optimizer_runs = 1 and via_ir = true. The bridge sits close to the EIP-170 size limit, and several functions are otherwise stack-too-deep.

Standalone crates build from their own directories; the relayer and the end-user CLI from the prover workspace they belong to:

cd crates/bridge-prover-libraries && cargo build --release
cd crates/bridge-prover-libraries && cargo test --locked -p bridge-relayer-daemon

Running it against a live network

Deployment, environment variables and genesis parameters: docs/EVM-contracts-spec.md §12. One constraint bites early — the genesis seed must sit on a key-block boundary, currently W·P = 128 × 8 = 1024.

Operating procedures — bootstrapping the prover daemons, the two live proving lanes, deploy timing and recovery — are documented next to the code they describe: the crate READMEs under crates/bridge-prover-libraries/, and each daemon's own --help.


Status

Shellnet / Sepolia. Not audited for mainnet. Known trade-offs and limitations are enumerated in docs/EVM-contracts-spec.md §15 — read that section before making any claim about the bridge's security properties.

About

Acki Nacki - EVM Bridge

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages