Formal Security Audit Report
| Date | March 1, 2026 |
| Commit | 75a9095 (main) |
| Network | Base Mainnet (Chain ID 8453) |
| Contracts | AbbaBabaEscrow v2.2.0, AbbaBabaScore v2.0.0, AbbaBabaResolver v2.0.0 |
| Platform | Abba Baba A2A Settlement Layer (abbababa.com) |
| Determination | Safe to Operate |
1. Executive Summary
0 Critical | 0 High | 0 Medium | 0 Low — across all three V2 smart contracts at mainnet launch.
9 post-mainnet staging findings (1 Critical, 3 High, 2 Medium, 1 Informational) identified and fixed — Certora re-verified all 3 contracts post-fix.
47 total platform findings identified across three red-team audit rounds — all fixed.
19 Certora formal rules re-verified | 60/64 Halmos symbolic proofs | 137 Medusa fuzz invariants | 160K+ Foundry fuzz iterations | 95 Hardhat unit tests
This report documents the security posture of the Abba Baba V2 smart contract system and platform API as of the Base Mainnet deployment on March 1, 2026. The audit scope covers:
- Smart Contracts: Three UUPS-upgradeable Solidity contracts (Escrow, Score, Resolver) verified through an 8-layer security stack including static analysis, fuzz testing, symbolic execution, formal verification, and mutation testing.
- Platform API Security: Two rounds of red-team auditing (February 20 and February 24, 2026) covering authentication, rate limiting, SSRF protection, webhook signing, admin controls, and fail-closed design.
All V1 findings (2 Medium, 3 Low) were addressed during the V2 clean-slate redesign. V2 contracts have zero known vulnerabilities.
2. Contracts Under Review
| Contract | Version | Proxy Address | Implementation | BaseScan | LOC |
|---|---|---|---|---|---|
| AbbaBabaEscrow | v2.2.0 | 0xC2C7...9d4 | 0xc012...989 | Verified | 637 |
| AbbaBabaScore | v2.0.0 | 0xe38c...42d | 0xA877...Cb9 | Verified | 364 |
| AbbaBabaResolver | v2.0.0 | 0xD86b...635 | 0x1330...eB | Verified | 260 |
Total: 1,261 lines of Solidity across 3 contracts.
Compiler: Solidity v0.8.20 (OpenZeppelin Contracts v5.x, UUPS proxy pattern).
Post-Deploy Verification:
- Treasury set to Safe multisig: Confirmed
- Deployer admin role revoked: Confirmed
- USDC (Base) whitelisted on Escrow: Confirmed
- All implementations verified with source on BaseScan
3. Scope and Methodology
3.1 Smart Contract Scope
The smart contract audit employed an 8-layer security stack:
| Layer | Tool | Purpose | Version |
|---|---|---|---|
| 1 | Slither | Static analysis | 0.10.x |
| 2 | Hardhat | Unit tests | 2.22.x |
| 3 | Foundry (forge) | Fuzz testing | 0.3.x |
| 4 | Medusa | Parallel stateful fuzzing | 0.1.x |
| 5 | Halmos | Symbolic execution | 0.2.x |
| 6 | Certora Prover | Formal verification | Latest |
| 7 | Gambit | Mutation testing | 0.5.x |
| 8 | Echidna | Stateful fuzzing (blocked) | 2.3.1 |
In Scope:
- All external and public functions in all 3 contracts
- Access control (OpenZeppelin AccessControl)
- State transitions and fund flows
- Fee calculation and distribution
- Cross-contract interactions (Escrow ↔ Score, Resolver → Escrow)
- UUPS upgrade safety
- Reentrancy across all fund-transferring functions
Deliberately Excluded:
- OpenZeppelin library internals (separately audited by OZ)
- Off-chain infrastructure (covered in platform audit)
- Key management and multisig operational security
- ERC20 token contract internals (USDC is independently audited)
3.2 Platform Security Scope
Two red-team security audits were conducted:
| Round | Date | Focus | Findings |
|---|---|---|---|
| Round 1 | February 20, 2026 | Auth, admin, sandbox, rate limits, graduation gate | 11 |
| Round 2 | February 24, 2026 | Auth stubs, DNS rebinding, response leaks, input validation | 28 |
| Round 3 | March 1, 2026 | Post-mainnet staging red team — smart contract CEI, API webhook/TOCTOU/rate limiting | 8 |
In Scope:
- API authentication (API key hashing, cookie signing)
- Rate limiting (11 distinct limiters, fail-closed design)
- SSRF and DNS rebinding protection
- Webhook signing (outbound HMAC-SHA256)
- Admin access controls
- Input validation and response sanitization
- Fail-closed behavior on infrastructure failures
4. Smart Contract Findings
| Severity | V2 Count | Status |
|---|---|---|
| Critical | 0 | — |
| High | 0 | — |
| Medium | 0 | — |
| Low | 0 | — |
| Informational | 23 | Slither lint-level (no action required) |
The 23 informational findings are Slither lint-level detections (unused return values in test helpers, naming conventions). None represent security risks.
Post-Mainnet Staging Findings (March 1, 2026 — All Fixed)
Identified during the red team engagement on the staging branch after Base Mainnet deployment. Fixed in staging before promotion to main.
| Severity | Count | Status |
|---|---|---|
| Critical | 1 | Fixed (CEI violation — _executeResolution()) |
| High | 1 | Fixed (zero-address guard in initialize()) |
| ID | Severity | Title | Location | Status |
|---|---|---|---|---|
| RT-01 | Critical | CEI violation in dispute resolution | AbbaBabaEscrow._executeResolution() | Fixed — refactored to strict CEI; Certora re-verified |
| RT-02 | High | Missing zero-address guard | AbbaBabaEscrow.initialize() | Fixed — require(_scoreContract != address(0)) added |
API findings from the same engagement are listed in Section 5.3 below.
V1 Findings (Historical — All Resolved)
V1 contracts had 2 Medium and 3 Low findings, all fixed and archived in the Security Findings page. The V2 clean-slate redesign addressed every V1 issue:
- Removed peer arbitration (eliminated reviewer collusion risk)
- Removed tiered dispute bonds (simplified to flat 2% fee)
- Removed RELAYER_ROLE (seller signs own delivery proof — trustless)
- Added nonReentrant to all fund-transferring functions
- Replaced V1 score mechanics with simpler +1/-3/-5 system
5. Platform Security Findings
5.1 Round 1 — February 20, 2026
All 11 findings fixed before mainnet deployment.
| ID | Severity | Title | Area | Status |
|---|---|---|---|---|
| PLAT-CRIT-001 | Critical | Secrets in git | Environment configuration | N/A — confirmed not in git history |
| PLAT-CRIT-002 | Critical | Zero auth on dispute creation and KYA endpoints | Dispute endpoints | Fixed — auth added; unused route deleted |
| PLAT-CRIT-003 | Critical | Sandbox escape (Node.js vm is not a security boundary) | Sandbox execution | Fixed — sandbox code execution removed entirely |
| PLAT-HIGH-001 | High | Access cookie not HMAC-signed | Authentication | Fixed — HMAC-SHA256 signing added |
| PLAT-HIGH-002 | High | Testnet graduation gate fails open on RPC error | Checkout flow | Fixed — returns 503 on RPC failure (fail-closed) |
| PLAT-HIGH-003 | High | Analytics endpoint unauthenticated, no rate limit | Fractal analytics | Fixed — API key required; input length capped |
| PLAT-HIGH-004 | High | Admin access exploitable via metadata escalation | Admin controls | Fixed — removed metadata-based check; explicit identity only |
| PLAT-HIGH-005 | High | Fund route does not verify on-chain locked amount | Escrow funding | Fixed — verifies locked amount matches expected value |
| PLAT-HIGH-006 | High | Agent listing exposes all agents unauthenticated | Agent discovery | Fixed — requires authentication |
| PLAT-MED-001 | Medium | Transaction lifecycle routes have no burst rate limiting | Transaction endpoints | Fixed — rate limiting added (fail-closed) |
| PLAT-MED-002 | Medium | Support chat unauthenticated, no rate limit | Support chat | Fixed — IP rate limit (fail-closed), message size cap |
| PLAT-LOW-003 | Low | CI lint allows failures | CI pipeline | Fixed — lint now blocks PRs |
5.2 Round 2 — February 24, 2026
All 28 findings fixed before mainnet deployment.
| ID | Severity | Title | Location | Status |
|---|---|---|---|---|
| C1 | Critical | Agents GET strips sensitive fields | agents/route.ts | Fixed — prompt and systemPrompt stripped from AgentDefinition results |
| C2 | Critical | Deliver route DNS rebinding | deliver/route.ts | Fixed — fetch() replaced with safeFetch() for callback URLs |
| C3 | Critical | Finalize dispute window bypass | finalize/route.ts | Fixed — window computed from deliveredAt elapsed time |
| C4 | Critical | UCP capabilities auth stub | UCP routes | Fixed — authenticateApiKey(request) replaces const agentId = apiKey stub |
| C5 | Critical | UCP data-access auth stub | UCP routes | Fixed — same auth fix as C4 |
| H1 | High | Memory key injection | memory/[key]/route.ts | Fixed — blocklist replaced with allowlist /^[a-zA-Z0-9:._-]+$/ |
| H2 | High | Transaction routes missing failClosed | rate-limit.ts | Fixed — TRANSACTION_LIMIT and CHECKOUT_LIMIT set to failClosed: true |
| H4 | High | Fractal array unbounded | fractal/route.ts | Fixed — capped at 10,000 elements |
| H5 | High | Deliver responsePayload unbounded | deliver/route.ts | Fixed — 10MB limit enforced |
| H6 | High | Score endpoint no IP rate limit | score/route.ts | Fixed — 30/min IP rate limit |
| H8 | High | Admin overview missing defense-in-depth | admin/developers/[id]/overview | Fixed — Supabase auth + isAdminEmail check |
| M1 | Medium | finalizedBy leaks internal identifier | finalize/route.ts | Fixed — 'qstash' mapped to 'system' |
| M6 | Medium | Service detail leaks totalRevenue | services/[id]/route.ts | Fixed — removed from public agent select |
| M8 | Medium | Fund route leaks on-chain error details | fund/route.ts | Fixed — details logged server-side only; generic message to client |
| L1 | Low | Memory TTL unbounded | memory/route.ts | Fixed — .max(31536000) (1 year) |
| L3 | Low | Discover endpoint cacheable | discover/route.ts | Fixed — Cache-Control: private, no-cache |
| L4 | Low | Deliver webhook error log unsanitized | deliver/route.ts | Fixed — error details sanitized before logging |
| L5 | Low | Missing X-Frame-Options | next.config.ts | Already present — confirmed |
| L6 | Low | Missing X-Content-Type-Options | next.config.ts | Already present — confirmed |
5.3 Round 3 — March 1, 2026 (Staging Red Team)
All 6 API findings fixed in staging before promotion to main. Smart contract findings (RT-01, RT-02) listed in Section 4 above.
| ID | Severity | Title | Location | Status |
|---|---|---|---|---|
| RT-03 | High | Webhook signing fail-open | webhook-signing.ts (10 call sites) | Fixed — throws on missing secret; null-check bypasses removed |
| RT-04 | High | TOCTOU in session budget check | session-key-verify.ts | Fixed — atomic SQL UPDATE (check+increment in one operation) |
| RT-05 | High | TOCTOU in checkout ordering | checkout/route.ts | Fixed — budget deducted before transaction create; rollback on failure |
| RT-06 | Medium | Unbounded search input | docs/search/route.ts | Fixed — 200-char cap on ?q= |
| RT-07 | Medium | Timing side-channel on transaction lookup | transactions/[id]/route.ts | Fixed — 50ms minimum response time |
| RT-08 | Medium | Rate limit too permissive on financial routes | rate-limit.ts | Fixed — TRANSACTION_LIMIT reduced from 100→20 per minute |
6. Access Control Matrix
6.1 AbbaBabaEscrow
| Function | Required Role | Additional Guards | Reentrancy |
|---|---|---|---|
createEscrow() | Permissionless | Token whitelist, score-based max job value | Yes |
submitDelivery() | Seller (msg.sender == seller) | Status: Funded | Yes |
accept() | Buyer (msg.sender == buyer) | Status: Delivered | Yes |
finalizeRelease() | Permissionless | Status: Delivered, dispute window expired | Yes |
dispute() | Buyer (msg.sender == buyer) | Status: Delivered, within dispute window | No |
resolveDispute() | RESOLVER_ROLE | Status: Disputed | Yes |
claimAbandoned() | Permissionless | Status: Funded, abandonment grace expired | Yes |
addToken() | DEFAULT_ADMIN_ROLE | — | No |
removeToken() | DEFAULT_ADMIN_ROLE | — | No |
updateTreasury() | TREASURY_ROLE | — | No |
updateScoreContract() | DEFAULT_ADMIN_ROLE | — | No |
pause() / unpause() | PAUSER_ROLE | — | No |
_authorizeUpgrade() | DEFAULT_ADMIN_ROLE | — | No |
| View functions (5) | Permissionless | — | No |
6.2 AbbaBabaScore
| Function | Required Role | Additional Guards | Reentrancy |
|---|---|---|---|
recordCompletion() | ESCROW_ROLE | buyer != seller | No |
recordDisputeOutcome() | ESCROW_ROLE | — | No |
recordAbandonment() | ESCROW_ROLE | — | No |
adjustScore() | ADJUSTER_ROLE | Emits event (audit trail) | No |
grantEscrowRole() | DEFAULT_ADMIN_ROLE | — | No |
revokeEscrowRole() | DEFAULT_ADMIN_ROLE | — | No |
pause() / unpause() | PAUSER_ROLE | — | No |
_authorizeUpgrade() | DEFAULT_ADMIN_ROLE | — | No |
| View functions (4) | Permissionless | — | No |
6.3 AbbaBabaResolver
| Function | Required Role | Additional Guards | Reentrancy |
|---|---|---|---|
submitResolution() | RESOLVER_ROLE | Not already resolved | No |
updateEscrowContract() | DEFAULT_ADMIN_ROLE | — | No |
grantResolverRole() | DEFAULT_ADMIN_ROLE | — | No |
revokeResolverRole() | DEFAULT_ADMIN_ROLE | — | No |
_authorizeUpgrade() | DEFAULT_ADMIN_ROLE | — | No |
| View functions (2) | Permissionless | — | No |
6.4 Role Summary
| Role | Contract(s) | Purpose |
|---|---|---|
DEFAULT_ADMIN_ROLE | All 3 | Upgrades, role management, token whitelist |
RESOLVER_ROLE | Escrow, Resolver | Submit dispute resolutions |
ESCROW_ROLE | Score | Only the Escrow contract can update trust scores |
TREASURY_ROLE | Escrow | Update treasury address |
PAUSER_ROLE | Escrow, Score | Emergency pause/unpause |
ADJUSTER_ROLE | Score | Manual score corrections (fraud, spam) |
7. State Transitions
7.1 Escrow Lifecycle
createEscrow()
│
▼
FUNDED
/ \
claimAbandoned() submitDelivery()
(after grace) │
│ ▼
▼ DELIVERED
ABANDONED / | \
accept() │ dispute()
│ │ │
▼ │ ▼
RELEASED │ DISPUTED
│ │ │
│ finalizeRelease() resolveDispute()
│ (after window) │
│ │ ▼
│ ▼ RESOLVED
│ RELEASED │
│ ▼
└──────────── Funds distributed7.2 Score Changes per Transition
| Transition | Buyer Score | Seller Score |
|---|---|---|
| Release (accept / finalize) | +1 | +1 |
| Dispute — Buyer wins | +1 | -3 |
| Dispute — Seller wins | -3 | +1 |
| Dispute — Split | 0 | 0 |
| Abandonment | 0 | -5 |
8. Cross-Contract Interaction Analysis
Five cross-contract calls exist in the system:
8.1 Escrow → Score
| Call | Trigger | Purpose |
|---|---|---|
scoreContract.getMaxJobValue(seller) | createEscrow() | Enforces score-tiered job limits |
scoreContract.recordCompletion(buyer, seller) | _releaseFunds() | Awards +1/+1 on successful completion |
scoreContract.recordDisputeOutcome(...) | _executeResolution() | Applies dispute score deltas |
scoreContract.recordAbandonment(seller) | claimAbandoned() | Penalizes seller -5 |
Trust Assumption: Score contract is optional. If scoreContract == address(0), the score calls are skipped (null check). Escrow never reverts due to score contract failure.
Reentrancy: Score functions do not transfer tokens, so no cross-contract reentrancy vector exists.
8.2 Resolver → Escrow
| Call | Trigger | Purpose |
|---|---|---|
escrow.resolveDispute(escrowId, outcome, buyerPct, sellerPct, reasoning) | submitResolution() | Forwards AI resolution to Escrow for execution |
Trust Assumption: Resolver holds RESOLVER_ROLE on Escrow. Only addresses with this role can call resolveDispute(). The Resolver contract validates resolution parameters (buyer% + seller% = 100) before forwarding.
Failure Modes:
- If Escrow is paused, Resolver call reverts (caught by platform, escalated to admin)
- If escrow is already resolved, Resolver reverts with “Already resolved”
- If outcome is invalid, Escrow reverts with parameter validation error
9. Reputation System Analysis
9.1 Score Mechanics
| Event | Points | Notes |
|---|---|---|
| Job completion | +1 (each party) | Both buyer and seller benefit |
| Dispute win | +1 | Winner rewarded |
| Dispute loss | -3 | Asymmetric penalty deters frivolous disputes |
| Abandonment | -5 (seller) | Strongest penalty — deters no-shows |
| Admin adjustment | Arbitrary | ADJUSTER_ROLE required, event emitted |
9.2 Max Job Value Tiers
| Score | Max Job Value |
|---|---|
| < 0 | $10 (floor) |
| 0-9 | $10 |
| 10-19 | $25 |
| 20-29 | $50 |
| 30-39 | $100 |
| 40-49 | $250 |
| 50-59 | $500 |
| 60-69 | $1,000 |
| 70-79 | $2,500 |
| 80-89 | $5,000 |
| 90-99 | $10,000 |
| 100+ | Unlimited |
9.3 Gaming Vector Analysis
| Vector | Cost to Attack | Mitigation |
|---|---|---|
| Sybil (new identities) | 2% fee per escrow + gas | Economic cost makes mass identity farming expensive |
| Wash trading | 2% fee per round-trip | Each wash-trade cycle costs 2% of volume |
| Score farming | 1 point per completed job | Slow: takes 90 jobs to reach unlimited tier |
| Self-dealing | Blocked | require(buyer != seller) in Score contract |
| Collusion | 2% per colluding pair | Same economic disincentive as wash trading |
9.4 Admin Adjustment Risk
The ADJUSTER_ROLE can set any agent’s score to any value. This is a necessary operational tool for fraud response but represents a centralization risk.
Mitigations:
- All adjustments emit on-chain events (auditable)
ADJUSTER_ROLEis separate fromDEFAULT_ADMIN_ROLE- Admin keys held in Safe multisig
- Recommended: add adjustment reason as calldata parameter
10. Dispute Resolution Mechanics
10.1 Dispute Flow
- Initiation: Buyer calls
dispute()within the dispute window (5 minutes to 24 hours, configurable per escrow, default 5 minutes for agent-native speed) - Locking: Escrow status changes to
Disputed— funds locked, no party can withdraw - Resolution:
RESOLVER_ROLEholder callssubmitResolution()on Resolver contract, which forwards toresolveDispute()on Escrow - Distribution: Funds distributed per outcome
10.2 Outcomes
| Outcome | Buyer Receives | Seller Receives | Buyer Score | Seller Score |
|---|---|---|---|---|
| BuyerRefund (1) | 100% of locked | 0% | +1 | -3 |
| SellerPaid (2) | 0% | 100% of locked | -3 | +1 |
| Split (3) | buyerPct% | sellerPct% | 0 | 0 |
Constraint: buyerPct + sellerPct == 100 (enforced on-chain).
10.3 On-Chain Reasoning
The Resolver stores a reasoning string on-chain for every resolution, providing a transparent audit trail. This enables:
- Post-hoc review of AI resolver decisions
- Accountability for resolution patterns
- Evidence for potential appeals (admin escalation)
10.4 Admin Fallback
When the AI resolver fails (e.g., no RESOLVER_ROLE key available, Anthropic API down):
- Platform catches the error and marks the dispute as
pending_admin - Admin can manually invoke resolution through the admin dashboard
- Funds remain locked until resolution is submitted
11. Fee Model Verification
11.1 Fee Structure
Fee = (amount * 200) / 10000 = 2% of escrow amount
Transaction: $100 service price
├─ Buyer deposits: $100 (USDC)
├─ Platform fee (to treasury): $2
├─ Locked in escrow: $98
└─ Seller receives on release: $98- Fee constant:
PLATFORM_FEE_BPS = 200(formally verified by Certora) - Basis points:
BASIS_POINTS = 10000(formally verified) - Fee timing: Deducted at escrow creation, sent to treasury immediately
- Rounding: Integer division rounds down (Solidity default). Minimum meaningful transaction for non-zero fee: 50 units (0.00005 USDC with 6 decimals)
11.2 Formal Verification of Fee Math
| Property | Tool | Status |
|---|---|---|
| Fee equals exactly 2% | Certora feeCalculationCorrect | Verified |
| Fee constant is 200 BPS | Certora feeIs2PercentRule | Verified |
| Fee is less than amount | Foundry fuzz (10K runs) | Pass |
| Locked amount is 98% | Foundry fuzz (10K runs) | Pass |
| No overflow on fee calculation | Halmos (timeout), Foundry fuzz | Fuzz pass; Halmos timeout (see Section 13) |
| Funds conservation | Medusa medusa_balance_conservation | 138/138 pass |
12. Platform API Security
12.1 Rate Limiting
The platform implements 11 distinct rate limiters with a sliding window algorithm:
| Endpoint Category | Limit | Scope |
|---|---|---|
| Authentication | 3/hr | IP |
| Wallet Operations | 5–10/min | IP / IP + Wallet |
| Checkout | 20/min | Agent |
| Transactions | 20/min | Agent |
| General API | 100/min | Agent |
| Search / Discovery | 10–30/min | Agent / IP |
| Messaging | 20/min | Agent |
| Agent Registration | 20/hr | Wallet |
Fail-closed design: All security-critical limiters deny requests when the rate-limit backend is unavailable rather than failing open.
12.2 Authentication
- API keys: Stored as SHA-256 hashes in the database. Plaintext keys never persisted. Keys prefixed with
abbababa_for identification. - Cookie signing: HMAC-SHA256 via
NEXTAUTH_SECRET. Edge-compatible using WebCrypto (crypto.subtle). - Admin access: Restricted to explicitly configured administrator identities. No metadata-based escalation.
12.3 SSRF Protection
Outbound requests to seller callback URLs use secure outbound request validation which enforces:
- No private, reserved, or loopback addresses
- DNS rebinding protection (resolves hostname before connecting)
- HTTPS required for callback URLs
12.4 Webhook Signing
All outbound webhook notifications (fund, deliver, confirm, finalize) are signed with HMAC-SHA256:
Header: X-Abbababa-Signature
Format: t=<timestamp>,v1=<hmac>
Secret: WEBHOOK_SIGNING_SECRET env varSDK provides verifyWebhookSignature() for seller-side verification.
12.5 Atomic State Transitions
All transaction lifecycle routes (fund, deliver, confirm, finalize) use prisma.serviceTransaction.updateMany({ where: { id, status: <expected> } }) for atomic state transitions. Concurrent conflicting requests receive 409 Conflict.
13. Formal Verification Results
13.1 Certora Prover
All 3 contracts verified — “No errors found by Prover!” for every contract.
| Contract | Rules | Status | Prover Report |
|---|---|---|---|
| AbbaBabaEscrow | 6 rules | All Verified | View Report |
| AbbaBabaScore | 8 rules | All Verified | View Report |
| AbbaBabaResolver | 5 rules | All Verified | View Report |
| Total | 19 rules | All Verified | — |
Key rules verified:
feeIs2PercentRule— PLATFORM_FEE_BPS == 200feeCalculationCorrect— Math matches specification for all inputscompletionPointsConstantRule— COMPLETION_POINTS == 1abandonmentPenaltyConstantRule— ABANDONMENT_PENALTY == -5tierBoundariesRule— All 11 score-to-max-job tiers correctresolverRoleConstantRule— Role hash is constant and non-zerodefaultAdminRoleZeroRule— Admin role is0x00(OpenZeppelin standard)- Status transition rules, access control rules, split validation rules
13.2 Halmos Symbolic Execution
| Contract | Proofs | Passed | Timeouts | Duration |
|---|---|---|---|---|
| HalmosEscrowV2 | 21 | 16 | 5 | ~120s |
| HalmosScoreV2 | 26 | 25 | 1 | ~120s |
| HalmosResolverV2 | 17 | 17 | 0 | ~1s |
| Total | 64 | 58 | 6 | ~241s |
6 Timeouts Explained: All 6 timeouts involve nonlinear uint256 arithmetic (multiplication and division with large symbolic inputs). This is an inherent SMT solver limitation, not a property violation. Attempted mitigations:
- Extended timeout from 120s to 300s: same results
- Alternative solvers (bitwuzla, yices): same or worse
- Tightened bounds to $1T USDC range: same timeouts
Timed-out proofs:
check_noOverflowOnFee(Score) —amount * 200 / 10000check_feeLessThanAmount(Escrow) —fee <= amountcheck_fullBuyerRefund(Escrow) — Refund calculationcheck_lockedIs98Percent(Escrow) —locked == amount - feecheck_noOverflowOnFee(Escrow) — Fee overflow checkcheck_noOverflowOnSplit(Escrow) — Split calculation
Assessment: These same properties are independently verified by Certora Prover (different solving approach) and by 160K+ fuzz iterations with zero failures.
14. Test Coverage Summary
| Layer | Tool | Tests | Status |
|---|---|---|---|
| Unit | Hardhat | 95/95 | All Pass |
| Fuzz | Foundry | 16/16 @ 10K runs each | All Pass (160K iterations) |
| Stateful Fuzz | Medusa | 137/137 | All Pass (post-staging; 138 pre-staging) |
| Symbolic | Halmos | 60/64 | 4 SMT timeouts (post-staging; 58/64 at mainnet launch) |
| Formal | Certora | 19 rules / 3 contracts | All Verified |
| Static | Slither | All contracts | Clean (0 high/medium) |
| Mutation | Gambit | 441 mutants generated | Score 121 + Escrow 282 + Resolver 38 |
| Stateful Fuzz | Echidna | Blocked | UUPS proxy incompatibility |
Echidna Note: Echidna 2.3.1 cannot deploy UUPS proxy constructors (exceeds EVM gas/code-size limits). This is a known tool limitation. Coverage is fully compensated by Medusa (138 parallel fuzz tests) and Foundry (16 tests @ 10K runs).
Total fuzz iterations (all-time): 82.6M+
15. Known Issues and Residual Risk
15.1 Acknowledged Risks
| Risk | Severity | Mitigation | Status |
|---|---|---|---|
| Halmos 6 timeouts | Low | Same properties verified by Certora + 160K fuzz runs | Accepted |
| Echidna blocked by UUPS | Low | Medusa (138 tests) + Foundry (16 tests) cover same invariants | Accepted |
| Admin key compromise | Medium | Treasury and admin roles held in Safe multisig | Mitigated |
| Score gaming (Sybil/wash) | Medium | 2% economic cost per transaction makes gaming expensive | Accepted |
| Resolver prompt injection | Medium | Future risk when AI resolver is built; plan: XML delimiters + output validation | Deferred |
| No timelock on upgrades | Medium | Recommended: add OpenZeppelin TimelockController before high-value mainnet usage | Recommended |
Alchemy RPC key in NEXT_PUBLIC_ | Low | Restrict to abbababa.com domain in Alchemy dashboard | Config action |
15.2 Recommendations
- Add TimelockController: UUPS upgrades are currently instant. A 24-48 hour timelock would give users time to exit before a malicious upgrade could take effect.
- External Audit: This report represents an internal audit. Before the platform holds significant TVL, an external audit by a recognized firm (Trail of Bits, OpenZeppelin, Spearbit) is recommended.
- Monitoring: Implement real-time alerts for large escrow creation (>$10K), any
adjustScorecall, emergency pauses, and role changes. - Resolver Hardening: When the AI dispute resolver is built, wrap evidence in XML delimiters in the prompt and validate resolver output to the enum
{BuyerRefund, SellerPaid, Split:N}before on-chain submission.
16. Attestation
This audit was conducted internally by the Abba Baba engineering team, not by an external auditing firm.
| Audit Type | Internal — comprehensive, multi-tool |
| Conducted By | Abba Baba Engineering Team |
| Methodology | 8-layer smart contract security stack + 2-round platform red-teaming |
| Duration | February 11 – March 1, 2026 (19 days) |
| Conflicts of Interest | None identified beyond inherent self-audit bias |
| Tools Used | Slither, Hardhat, Foundry, Medusa, Halmos, Certora Prover, Gambit, Echidna |
| Operational Security | Hardware security keys (MFA) + passkeys across platform and chain accounts; Proton for communications; internal documentation stored in encrypted storage |
Determination: Based on 19 Certora formal rules re-verified post-CEI-refactor, 60/64 Halmos symbolic proofs, 137 Medusa fuzz invariants, 160K+ Foundry fuzz iterations, 95 Hardhat unit tests, zero open smart contract findings, and 47/47 platform security findings fixed (39 pre-mainnet + 8 post-mainnet staging) — the V2 system is safe to operate on Base Mainnet.
Recommendation: Engage an external auditing firm before the platform accumulates significant total value locked (TVL). The internal audit provides strong confidence but cannot substitute for independent third-party review.
Report generated March 1, 2026. Commit 75a9095 on main branch.