The whole loop,
run live on testnet.
Deposit → earn → authorize → spend, plus a native USDC bridge — every leg executed on-chain, with real transaction hashes you can open in a block explorer. The plumbing working end to end, not a mock-up.
Deposit & earn
Proven on ArcArc · MintwareYieldVault 0x11Ef…C4215 USDC deposited into the treasury vault. The same transaction routed it through the adapter into the yield source — the capital went straight to work rather than sitting idle.
Authorize — sub-10 ms, off live NAV
Live serviceedge-auth → live Arc NAV (7.00 USDC backing)The Rust edge-auth service, pointed at the live Arc vault, decided each spend off the real NAV — reserving a hold on approval, failing closed otherwise. Off-chain, so no tx hash; these are the running service’s live responses.
| Request | Decision | Reason | Latency |
|---|---|---|---|
| $2.00 | Approved | hold reserved · headroom 7→5 | 7.2 ms |
| $10.00 | Declined | insufficient_equity (over 5 headroom) | 6.9 ms |
| $300.00 | Declined | high-value lane · 2nd-signer absent → fail-closed | 6.1 ms |
| $2.00 · no bearer | 401 | fail-closed: endpoint reserves equity | — |
Settle — spend as USDC
Proven on ArcArc · MintwarePaymentGateway 0x1D07…5399A signed EIP-712 spend permit → the gateway burned exactly the shares needed and paid the merchant 2 USDC. The event trace unwinds the earn path in reverse (yield source redeemed → adapter → vault → merchant) — the dollars came out of the earning position at the moment of the spend.
Bridge — native USDC, Base → Arc
Proven end-to-endBase Sepolia → CCTP domain 26 (Arc)1 USDC burned on Base Sepolia through Circle’s CCTP v2, attested by Circle (~22 min, standard finality), then minted natively on Arc and deposited straight into the vault as yield-earning shares. Bridged capital arrived already earning.
Stage one side, earn,
pair when ready.
The capital-constrained liquidity path, run live on Base Sepolia. A team parks the single side it holds; it earns while it waits; then one call forms the pool — and the yield it earned flowed into the position, not away.
Stage a single side
Proven on Base SepoliaBase Sepolia · MintwareStagedLiquidityRouter 0x36fa…33e31,000 sUSD — the one side the team holds — was staged into the router and supplied to the yield adapter in the same action. No 50/50, no forced swap, no second asset required.
It earns while it waits
Proven on Base Sepoliarouter · per-adapter yield poolYield accrued to the staged position. The router’s on-chain stagedAssets read reflects principal plus its pro-rata share of the yield — the buffer was productive from the first block, never idle.
Pair into the pool
Proven on Base SepoliaBase Sepolia · router → pair vaultThe owner brought the other side (2,000 TKA). One call pulled the staged side back with its earned yield, paired both, and minted LP straight to the owner — the yield went into the position, and the stage closed.
| Contract | Network | Address |
|---|---|---|
| Staged router | Base Sepolia | 0x36fa…33e3 |
| Staged token (sUSD) | Base Sepolia | 0xE236…8401 |
| Yield adapter | Base Sepolia | 0xe412…0B5F |
| Pair vault | Base Sepolia | 0xB014…D2F7 |
The router is the real product bytecode; the yield source + pair vault here are an open-mint mock rig so the loop is self-contained. The real AaveV3YieldAdapter + MintwareDeFiPairVault implement the same interfaces (Forge-tested). Try it live →
A card that spends the
LP balance.
A member swipes a card; it draws on the org’s LP-backed treasury through the same authorize + settle primitives above — not a separate pool. Proven end-to-end on 2026-08-20: a real $2 sandbox swipe was authorized off live NAV, then settled on-chain, burning $2 of the treasury’s senior shares. Sandbox card (synthetic PAN, no real merchant), testnet vault: no real-world money moves.
A real $2 Lithic sandbox swipe → ASA webhook → edge-auth decided off live vault NAV → APPROVED, in the same NAV-hold engine as leg 2. Automatic, as card authorization always is; no tx (it’s an off-chain hold).
settleSpend burned exactly $2 of the member’s senior shares (12.0 → 10.0 USDC) → paid out — a real card-ORIGINATED settlement, not a scripted one.
0x7ef19942…30d8bb · basescan ↗The above settle was the owner-triggered path. The automatic capture (Lithic SETTLED event → auto-settle small swipes ≤ $50) is wired — subscription live — but off by default and not yet fired via the webhook.
Proven end-to-end on 2026-08-20: a real sandbox swipe authorized off live NAV, then a card-originated settleSpend burned $2 of senior shares on-chain (linked above). The one still-dormant piece is the AUTOMATIC capture path (off by default). This same run also surfaced a real bug — the settle core was marking a reverted tx as settled — now fixed. The card surface →
The vault math,
proven — not just tested.
Seven safety properties are backed by a machine-checked proof, not only fuzzing. Halmos symbolically proves the live fee-logic bounds over every possible input; the nonlinear rounding and solvency lemmas that defeat any SMT solver (division by a symbolic value) are proved in Coq. Both run as gates in CI.
Surge fee never exceeds its configured ceiling
MWDynamicFee.volatilityFee · live code
Volatility only ever adds to the base fee — never below it
MWDynamicFee.volatilityFee · live code
Per-block fee move never exceeds the rate-limit step
MWDynamicFee.rateLimit · live code
Fee split conserves exactly (zero dust) + rounding favors LPs
_splitFee mulDiv lemma
Idle redeem rounds down — never pays out more than the leg
redeem mulDiv lemma
Concurrent redeemers can never together draw more than backing
solvency mulDiv lemma
Deposit mint creates no value from nothing (inflation-safe)
deposit mulDiv lemma
Honest scope: the 3 Halmos proofs bind to the real MWDynamicFee bytecode; the 4 Coq lemmas prove the exact mulDiv arithmetic the vault relies on (proven as lemmas, not bound 1:1 to bytecode — flagged for the external audit). All 7 are also fuzz-proven at 256×128k. Testnet + unaudited. The math →
We ran a firm-grade checklist
on ourselves — and fixed it.
Before paying for an external audit, we reviewed the entire contract stack against the same public standards the firms use — SCSVS, the SWC weakness registry, Solcurity, and the DeFi-specific vulnerability classes — with parallel reviewers, then deduped, ranked, remediated, and re-reviewed the findings.
Senior "par" NAV now solvency-aware — tail haircuts pro-rata, no first-redeemer run
FixedNo unbounded token approvals — a distributor can no longer drain vault principal
FixedSettlement pays only a pinned rail — a relayer can’t redirect funds
FixedDead, misleading FeeVault (unverified owner-set root) deleted
FixedMatched-launch can’t be deployed at a manipulated empty-pool price
FixedGuardian pause auto-heals — a single key can’t freeze user exits forever
FixedJIT return balance-verified; hot-path calls can’t brick swaps/redemptions
FixedCircuit breaker no longer blocks the arb that heals a thin-pool price
FixedThis is a SELF-REVIEW, not an external audit — it surfaces what a firm would flag before we pay for one; it does not replace it. All 6 High findings + the core Mediums are fixed, re-reviewed, and testnet-deployed; a few lower-severity items are scoped as follow-ups. Everything remains testnet + unaudited — an external audit is the gate before real value.
Then we ran it again —
and audited our own fixes.
A second independent pass over the whole stack, a day after the first. Each reviewer re-verified round-1’s remediations adversarially and hunted for what a checklist misses — attacks that only appear across a sequence of legitimate calls. It found that three of round-1’s own fixes were incomplete or opened a new hole. We fixed those too, then re-ran everything.
Deposits can no longer be tricked by a depressed pool price into minting cheap senior shares
FixedA fully-used JIT slice can’t be stranded — senior NAV can never count phantom backing at par
FixedCompleted round-1’s approval fix across every fee-funding path — rent + yield no longer revert
FixedJunior first-loss can’t exit while senior liquidity is still deployed
FixedSettlement now caps cumulative extraction, not just per-call — a rogue relayer can’t bleed it
FixedReward pot credits fees actually received (fee-on-transfer safe), never the requested amount
FixedStill a SELF-REVIEW, not an external audit. The candid takeaway: a fix isn’t done until it’s been attacked as a sequence, not just re-checked in isolation — the second pass caught what the first pass’s own remediations missed. All three new Highs + the core Mediums are fixed and re-run green; lower-severity items are scoped as follow-ups. Testnet + unaudited — an external audit remains the gate before real value.
A firm-grade matrix,
run on ourselves.
The third pass wasn’t another checklist — it was the layered matrix a security firm runs: static analysis, unit + negative tests, stateful fuzzing, formal proofs, and economic/fork simulation, each a distinct net. The ETH senior tranche got its own reviewer across every layer. 39 new tests, no new findings, and the one critical architecture check — delegatecall storage-layout collision — came back safe.
Attempted; blocked by a local tooling/version incompat (crytic-compile ↔ forge 1.5.1 build-info) — a CI-config issue, not a finding. Rounds 1–2 covered these classes by hand.
Access-control-negative sweep, zero-address injection, first-depositor/inflation, fee-on-transfer, zero/max, event emission.
Solvency · share-conservation · monotonic battery on the settlement + staged-router pools that previously had no stateful suite. 0 reverts.
3 symbolic fee-bound proofs + 4 machine-checked mulDiv/solvency lemmas, both CI-gated. (Certora/HEVM not provisioned.)
Flash-style spot manipulation → settle reverts with backing conserved; stale oracle fails closed; truncated oracle frozen intra-block; delegatecall storage-layout SAFE (all 4 libs, 0 storage vars).
Honest scope: Layer-1’s automated scanners (Slither/Aderyn) could not run to completion in this local environment — a crytic-compile/forge version incompatibility + the monorepo’s dual Foundry root, documented in the report and recommended for CI; Certora/HEVM/Echidna/Medusa/Mythril are not provisioned here. What did run — 39 new dynamic tests across Layers 2/3/5, the Halmos+Coq formal gates, and the storage-collision check — found no new defect. Self-review, not an external audit; testnet + unaudited.
We audited our own
newest code, too.
New code deserves the same scrutiny as old code — so the operating-float settlement and the 48h risk-param timelock got their own adversarial pass (money-path, governance, composition reviewers) before sitting un-reviewed on main. It found a genuine High in our own fresh work. We fixed everything, and confirmed the earlier three rounds are regression-free.
The settlement oracle can no longer be re-pointed after go-live — closes a compromised-owner instant-drain path
FixedThe keeper’s rebalance fails closed until throttled — it can’t churn the whole backing on the default config
FixedThe windowed extraction cap can’t be silently reset per-block — the accumulator carries forward
FixedValuation handles real 6-decimal USDC and prices against the un-sandwichable staking rate
FixedBoth swap legs fail closed symmetrically, and the new settlement adopts the same 48h timelock
FixedSelf-review, not an external audit. The point of this round: newly-shipped code is the most dangerous code — so we adversarially audited our own float-settlement + timelock the moment it landed, found a real High (an instant oracle re-point path), and fixed it plus every Medium and Low. A separate reviewer confirmed the earlier three rounds’ invariants are byte-for-byte intact. Testnet + unaudited — an external audit remains the gate before real value.
We ran it the way
a firm would.
This round deliberately mirrored the published SOPs of Hacken and CertiK — a STRIDE threat model, a micro (function) + macro (system) split, the 15-category checklist, severity scored on likelihood × impact × exploitability, and a required proof-of-concept for anything High. Six reviewers read the whole stack. It found two genuine Highs — both in our own recent code — and we fixed them, wrote the PoC as a permanent regression test, and fixed the lows too.
JIT settlement now measures the return inside the settle call — a stale cross-transaction baseline had let a routine op hide a real loss onto the protected tranche (PoC-confirmed, now a regression test)
FixedThe agent pay-per-call settle now verifies the payer’s signed payment authorization and binds it to the exact receiver + amount — closing a drain path in code we’d just shipped
FixedThe redemption NAV no longer counts an outstanding JIT slice at par, and the price-guard rejects a param that could silently disable it
FixedA settlement swap can’t strand backing on a partial fill, and the settlement destination is set-once (no re-point after go-live)
FixedSelf-review, not an external audit — run at firm quality (Hacken/CertiK methodology), not by a firm. The honest headline: a firm-grade pass on our own newest code found two real Highs, including one with a working exploit against our JIT loss-attribution, and we fixed them plus the lows and re-verified everything else held. Testnet + unaudited — an external audit remains the gate before real value.
We didn’t just review it.
We attacked it.
Reviewing finds what you think to look for; attacking finds what actually breaks. So we turned five autonomous agents loose to each construct a working multi-step exploit — as a real, executable proof-of-concept — against a different surface: reentrancy, JIT loss-attribution, oracle/MEV manipulation, tranche solvency, and settlement/access-control. One got through: a slippage band that could be widened in a single block, skipping the 48-hour governance delay its sibling band enforces. We fixed it and proved the fix. The other four attacks were blocked — with the executable proof to show it.
A settlement slippage floor could be widened instantly by the owner, skipping the 48h governance delay its sibling band enforces — a rogue-owner drain path. Now routed through the same timelock (widening delayed, tightening instant).
FixedHeld under attack: a malicious yield adapter’s re-entrancy is reverted by the guard on every money-path entry point (proven with a real reentrant-adapter PoC).
HeldHeld under attack: the JIT loss-attribution and stranded-slice redemption fixes both resisted; oracle manipulation is blocked in-block and bounded to the first-loss tranche across blocks; the first-redeemer run stays closed.
HeldSelf-review run at real red-team depth, not an external audit. Attacking our own code with executable exploits found one genuine Medium that a checklist review and static analysis both missed — a sibling-setter timelock asymmetry — which we fixed and regression-tested; every other attack was blocked with proof. Two nuanced edge cases are documented for follow-up rather than claimed closed. Testnet + unaudited — an external audit remains the gate before real value.
The suites behind it
The on-chain run rides code that is green across every layer — Solidity, Rust, and the property-based invariants where money can be lost.
| Contract | Network | Address |
|---|---|---|
| Treasury vault | Arc | 0x11Ef…C421 |
| Payment gateway | Arc | 0x1D07…5399 |
| Yield adapter | Arc | 0xb9FB…2B88 |
| CCTP deposit router | Arc | 0xDB9D…Fc03 |
| CCTP TokenMessenger | Base Sepolia | 0x8FE6…2DAA |
Recorded 2026-08-19 · Arc testnet (5042002) + Base Sepolia (84532) · unaudited. To reproduce or extend the run, see the deploy scripts in contracts-v4/script and the runbook docs/developers/session-handoff-arc.md. What is YPN? →