Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

abs-bridge — Sepolia ↔ Abstract Sepolia ETH bridge

A web dApp to bridge native ETH between Sepolia (L1) and Abstract Sepolia (L2), track L2→L1 withdrawals until they are claimable, and claim them on L1. Also provides a full transfer history for any address.

Built with Astro 4 + React 18 + viem 2, deployed on Vercel as a static site with URL rewrites.

Features

  • Bridge ETH (L1 → L2) — deposit Sepolia ETH into Abstract via the bridge.
  • Track & claim withdrawals (L2 → L1) — given an L2 withdrawal tx hash, shows the cross-chain status timeline (submitted → batch committed → batch proven → batch executed → claimable) and lets the user claim it on L1 with L1Nullifier.finalizeDeposit.
  • Transfer history — for any address, lists native ETH deposits and withdrawals (newest first) with Etherscan links for each leg.
  • WalletConnect support — MetaMask (via injected provider) and WalletConnect v2 (QR on mobile) through Reown's SDK.

Routes

Route Description
/ Bridge page (deposit)
/transaction/<hash> Track / claim an L2 withdrawal
/history/<address> Transfer history for an address

The /:hash and /:address segments are handled client-side from window.location.pathname; Vercel rewrites map these to the static pages.

Getting started

npm install
cp .env.example .env   # add VITE_WALLETCONNECT_PROJECT_ID
npm run dev

Environment variables:

  • VITE_WALLETCONNECT_PROJECT_ID — Reown Cloud project ID (required for WalletConnect; get one at https://cloud.reown.com).
  • SEPOLIA_PK — optional, used only by the CLI scripts.

Scripts

npm run dev          # start dev server
npm run build        # static build → dist/
npm run preview      # preview the production build
node scripts/withdraw-cli.mjs  # CLI for tracking/claiming a withdrawal

Deployment

Deploy to Vercel:

npx vercel --prod

Set VITE_WALLETCONNECT_PROJECT_ID in the Vercel project env vars. The vercel.json rewrites map /transaction/<hash> and /history/<address> to the static pages.

Tech notes

  • L1→L2 deposits and L1Nullifier claims use viem contract calls against the Sepolia bridge contracts (see src/lib/).
  • Withdrawal status is derived from L1 batch commit/prove/execute events and the claim transaction.
  • The CLI mirrors the web claim logic for headless operation.

TVL, fund flow & lock risk

Current TVL is ~0

As of the last on-chain check, every contract this app touches holds 0.000000 ETH:

Contract Balance
BridgeHub (L1) 0.000000 ETH
SharedBridge L1 / L1Nullifier 0.000000 ETH
Diamond proxy / hyperchain 0.000000 ETH
L2 SharedBridge 0.000000 ETH
L2 base token / message sender (0x800a / 0x8008) 0.000000 ETH

This is expected for a base-token bridge on a testnet:

  • No custody pool. Deposits (L1→L2) forward ETH through BridgeHub → SharedBridge and straight into the L2 system contracts. There is no long-lived escrow reserve sitting on L1.
  • Transient claims only. ETH only sits in L1Nullifier between "L2 batch executed on L1" and the user's finalizeDeposit claim, then it is paid out.
  • No economic incentive. Abstract testnet ETH has no value, so nobody parks funds; anyone can withdraw at any time, so balances drain to zero.

When funds can be locked

  • In-flight L2→L1 withdrawal — ETH is burned on L2 at withdraw time and does not exist on L1 until the batch is executed (up to ~a day on testnet). This is the "Waiting for L1 execution" state in the app. (Temporary.)
  • Executed but unclaimed — after execution, ETH sits in L1Nullifier until someone submits finalizeDeposit. (Temporary, but indefinite if never claimed.)
  • Lost or incorrect receiver keyfinalizeDeposit only pays the _l1Receiver baked into the withdrawal message; a wrong or lost address locks the ETH permanently. (Permanent.)
  • Failed or expired L1→L2 deposit — if the L2 deposit tx fails (e.g. l2GasLimit too low) the minted value needs claimFailedDeposit; expired priority txs need a manual reclaim. (Temporary.)
  • Paused bridge / wrong finalizerwhenNotPaused reverts claims while paused; a withdrawal initiated via the legacy Mailbox path cannot be claimed through L1Nullifier.finalizeDeposit (InvalidSelector) until the matching finalizer is used. (Temporary.)

Why other bridges show large TVL

Big bridges report large TVL because they run the escrow model: for every token bridged to L2 (USDC, WETH, …), an equal amount must remain locked in the L1 contract to back the circulating L2 supply. Their pools ≈ cumulative deposits − withdrawals, driven by multi-token support and real mainnet usage. This app bridges only the base token (ETH) on a testnet, which neither escrows reserves nor attracts deposits — so its standing balance is near zero. The meaningful metric for a base-token bridge is cumulative deposit/withdrawal volume, not the standing balance.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages