One link. A bar that fills itself from every chain. It pays out together, or refunds everyone — automatically.
Rally is conditional group money. One link lets any group — a trip chat, a family, a savings committee — move money together under a condition the group can see and a contract enforces. Friends open the link, sign in with email, and chip in. The pot either does exactly what the group agreed, or every person gets their money back, automatically. Nobody installs a wallet, pays gas, or picks a network.
The thesis: the money that actually pools is money between people who know each other — and nobody owns that primitive. PayPal shut down Money Pools in 2021 and never replaced it. Rotating savings circles (chit funds, tandas, susus) are the largest informal financial instrument on earth and still run on a trusted foreman who can walk off with the pot. Every group-money product before this died of the same thing: somebody had to hold the money. Rally's pot is a contract. Nobody holds the money — including us.
Live: https://rally-production-94cc.up.railway.app (Goals · Circles switch on the landing)
| Shape | Contract (Arbitrum Sepolia, verified) |
|---|---|
Goals — GoalVault |
0x914e4682aD2FeBb3e00a21dB29B93c16fc080AB4 |
Circles — RotatingVault (ownerless) |
0xdd9b3e5F407B99e2C2827695608741B328F97838 |
Testnet only. No real money is ever involved.
One-shot, all-or-nothing. "Send the crew to Tokyo — $2,000 by Friday."
- An organizer sets a goal and deadline and gets one shareable link (
createCampaignis permissionless — anyone can start one). - Friends open the link, sign in with email, and chip in USDC from whatever chain they hold it on. The bar rises live, colored by the chains the money came from.
- Goal hit before the deadline → the organizer withdraws one consolidated pot. Missed → every backer reclaims their contribution. The escrow tracks each backer's
{sourceDomain, amount}onchain so refunds can rail back to where the money came from.
A rotating savings circle — the chit fund / tanda / susu, with the foreman replaced by a contract.
- An organizer starts a circle: N seats, a fixed amount, a round length. Each seat gets a signed invite link; joining is an email login.
- Every round, everyone chips in the same amount. When the round fills, one member takes the whole pot — the turn rotates until everyone has had theirs.
- Anyone misses a round? The circle stops and everyone still holding a deposit is refunded, automatically. No foreman, no ledger notebook, no absconding. The
RotatingVaultis ownerless — there is no admin key that can touch the money.
Same link mechanics, same email login, same refund guarantee. One primitive, two shapes.
We'd rather show receipts than adjectives. Everything below is live and verifiable on public explorers.
Goals
| What | Value |
|---|---|
| Campaign #1 — filled live, cross-chain | /c/1 — the landing hero reads this exact campaign from Arbitrum over public RPC. Two real CCTP fills (~$6.50 of $30 at submission time), named feed |
| Burn tx (Base) | 0x297eb6… |
| Mint tx (Arbitrum) | 0xc354c2… |
| Measured attestation latency | 9.8 s (Circle CCTP v2 fast transfer) — fast enough to watch live |
| Campaign #2 — "Coffee for the launch crew" | Opened end-to-end through the product's own /create flow, live at /c/2 |
Circles
| What | Value |
|---|---|
| Circle #1 — live, mid-fill | /circle/1 — 4 seats · $1/round, created onchain (tx), every seat joined via an org-signed EIP-712 invite, round 1 funded 3-of-4 |
| Circle #2 — broke on schedule, and auto-refunded | /circle/2 — a round went unfunded, the circle derived Broken, and the refund returned a member's deposit: refund tx. The refund rail is proven onchain, not promised. |
Assurance
- 86/86 Foundry tests across both vaults — GoalVault's 58 (54 unit + 4 invariants incl.
invariant_solvency) plus RotatingVault's 28, including two fund-conservation fuzzes (green at 2,000+ runs). RotatingVault assertsbalance == Σ deposited − Σ claimedafter every state mutation. - Audited twice, independently: a 12-agent self-audit (Pashov solidity-auditor methodology) and a separate adversarial review — zero Critical/High/Medium findings. The remaining Lows are on the roadmap, named.
Full explorer-linked proof and reproduction steps: deployments/phase1-live-proof.md.
The user's entire interaction is email → amount → done. Underneath:
- Email login → embedded EIP-7702 wallet. Magic mints the wallet behind the one-time code — no seed phrase, no extension. The 7702 delegation is a real Type-4 transaction with an
authorizationList, running on a ZeroDev kernel with a paymaster, so every step is gasless. - Chip in from any chain. Circle CCTP v2 burns the USDC on the source chain, waits ~10 s for Circle's attestation, and mints it on Arbitrum — no bridge UI, no network switch, no gas.
- Custody is the two vaults. Everything on screen — the bar, the pot, the feed, a refund — is read from Arbitrum Sepolia over public RPC.
flowchart TD
Email["Email login\n(Magic embedded 7702 wallet · ZeroDev gasless)"]
Amount["Pick an amount"]
Burn["USDC burned on the source chain\n(CCTP v2 depositForBurn, fast)"]
Iris["Circle attestation (~10s)"]
Mint["USDC minted on Arbitrum Sepolia"]
Email --> Amount --> Burn --> Iris --> Mint
subgraph Vaults["Custody on Arbitrum Sepolia — both verified"]
Goal["GoalVault 0x914e…0AB4\nall-or-nothing goals"]
Rot["RotatingVault 0xdd9b…7838\nrotating circles · ownerless"]
end
Mint --> Goal
Mint --> Rot
Goal -->|goal hit| Payout["Organizer withdraws the pot"]
Goal -->|goal missed| RefundG["Every backer refunded"]
Rot -->|round funded| Pot["This round's member claims the pot"]
Rot -->|round missed| RefundC["Circle stops — everyone refunded"]
Honest caveats (stated, not hidden)
We'd rather a judge hear these from us than find them.
- Magic OTP is human-in-the-browser. Email login needs a real person to enter the one-time code. Genuinely gasless and seedless — but not headless.
- The relayer is a demo concierge. Fresh email wallets hold no testnet USDC, so in the demo a relayer fronts the source-chain burn (Goals) and organizes the demo-friends circles (the toggle on
/circles/new— labeled in the UI: the Rally crew runs the demo). Circles you create for real are self-custodied:createCircleis sent from the creator's own sponsored 7702 wallet, so their address is the on-chain organizer; every seat invite is an EIP-712 signature minted by their key in the browser; andstart— organizer-gated on-chain — only works from their wallet. Rally's server never holds a key that can sign an invite, start, or cancel one of those circles; it can only relay already-signed messages. The CCTP rail, the escrow accounting, and every refund are real in both lanes. - Testnet only. Arbitrum / Base / OP Sepolia with faucet USDC. No mainnet, no real money — by design (see ROADMAP for the mainnet path).
- Frontend: TanStack Start (React 19 + Vite) + Tailwind CSS v4, Motion for spring physics, canvas-rendered liquid bars
- Cross-chain rail: Circle CCTP v2 — burn-and-mint USDC across Arbitrum, Base, and OP Sepolia
- Embedded wallet + gasless: Magic email login → EIP-7702 embedded wallet; ZeroDev kernel + paymaster for sponsored transactions
- Contracts:
GoalVault+RotatingVaultin Solidity via Foundry, both deployed + verified on Arbitrum Sepolia (86 tests total) - Deploy: Railway (SSR)
- Package manager: bun
Built for the UXmaxx / 7702 Collective hackathon.
- Arbitrum bounty ($2k) — the brief asks for consumer apps that "feel less like crypto apps and more like normal consumer products," where the user never thinks about wallets, gas, bridges, or chains. That is Rally's entire design brief. Both vaults live on Arbitrum; every read, payout, and refund settles there. It is the home chain, not an afterthought.
- Magic bonus ($500) — email is the front door. The embedded EIP-7702 wallet is what makes "just use your email" possible for a goal and a savings circle, without a seed phrase.
- General Track / ZeroDev subtrack — gasless 7702 end-to-end on ZeroDev's kernel + paymaster; a Smart Routing Address integration is on the pre-deadline runway (see ROADMAP).
bun install
bun run dev # http://localhost:3000Other scripts:
bun run build # production build
bun run start # serve the production build
bun run test # run the test suiteCreate a .env.local with the following keys before running against live testnet services (all free, all testnet):
VITE_MAGIC_PUBLISHABLE_KEY= # Magic — email login + EIP-7702
VITE_ZERODEV_PROJECT_ID= # ZeroDev — gasless 7702 (Arbitrum Sepolia)
CIRCLE_API_KEY= # Circle — CCTP v2 + testnet USDC faucet
ALCHEMY_API_KEY= # Alchemy — RPC for Arbitrum/Base/OP Sepolia
ARBISCAN_API_KEY= # Arbiscan — contract verification
Solidity contracts live in contracts/ and use Foundry.
cd contracts
forge build
forge test # 86 tests: GoalVault + RotatingVault + invariantssrc/routes/ index (Goals landing) · circles.index (Circles landing) · create ·
circles.new · c.$id (live campaign) · circle.$id (live circle) · invite
src/components/ thermometer + round bar, contribute/circle sheets, feeds, celebrations
src/lib/ auth (Magic), cctp (Circle rail), campaign + circle read/write models
src/design/ design tokens + chain brand colors
contracts/ Foundry project (GoalVault + RotatingVault)
deployments/ onchain proof + deployed addresses
Both shapes work end-to-end today. The near-term plan — the Jul 19 submission runway, then Circles for the people who already run savings committees — lives in ROADMAP.md. A beat-by-beat demo script is in PITCH.md.
MIT