Protocol AUDIT — Donate to pools card (indexer + wallet top-up) #262
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#262
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
GitLab #261 adds onchain
topUpPodiumPools— permissionless DOUBtransferFrom(msg.sender)into active + next-round prize vaults with no platform take. Operators and participants need a single AUDIT-page card that (1) submits donations, (2) shows the required no-benefit disclosure, and (3) surfaces indexer-backed donation history and totals on the same card.Parent epic: #238. Blocked by / pairs with: #261 (contract + event shape).
Follow the #231 pattern: one protocol section, one HTTP read-model, shared
data-testid, invariants in QA issue #260.Relevant files
Indexer
indexer/migrations/— e.g.idx_arena_podium_pool_top_up(oridx_timecurve_podium_pool_top_upuntil arena rename)indexer/src/decoder.rs— decodePodiumPoolsToppedUp(or final event name from #261)indexer/src/api.rs— new route +SCHEMA_VERSIONbumpindexer/tests/integration_stage2.rsdocs/indexer/design.mdFrontend
frontend/src/pages/TimeCurveProtocolPage.tsx(v2: arena protocol / audit route) — mount new sectionTimeCurveProtocolDonatePoolsSection.tsx(rename toTimeArenaProtocolDonatePoolsSection.tsxwhen #256 lands)frontend/src/lib/indexerApi.ts— fetch helper + typesuseTimecurveProtocolDonatePools.ts(hook: indexer read + wagmi write)frontend/src/lib/ensureCl8yTimeCurveAllowance.tspattern → DOUB approve toTimeArena(exact allowance per #143)docs/frontend/timecurve-views.md— AUDIT section docfrontend/e2e/timecurve.spec.tsor arena equivalentIndexer acceptance criteria
tx_hash,log_index,block_number,block_timestamp,donor_address(lowercase),amount_doub_wadGET /v1/arena/podium-pool-donations(or/v1/timecurve/podium-pool-donationspre-rename) returns:total_donated_doub_wad(network-wide sum)unique_donors_countrecent[]: latest N donations{ donor, amount_doub_wad, block_timestamp, tx_hash }(default N=10, paginated optional)donor_summarywhen?donor=0x…set: that wallet’stotal_donated_doub_wad+ count500bodies redacted per #157Frontend acceptance criteria — single card
Placement: protocol / AUDIT page (
/timecurve/protocoltoday;/arena/protocolor equivalent after #256).data-testid="timecurve-protocol-donate-pools".Disclosure (required, always visible above the donate CTA):
Use a
StatusMessageor equivalent warning variant — not dismissible, not fine print.Write path (connected wallet):
ChainMismatchWriteBarrier+ exact DOUBapprovethentopUpPodiumPools(amount)(#261)friendlyRevertFromUnknownRead path (same card, below or beside write UI):
donor_summary)EmptyDataPlaceholder/ muted copy — no fake zeros (#200, #96)Out of scope for this issue: counting donations toward XP, CRED, CHARM, or platform-usage wallet spend totals unless spec #240 explicitly amends.
Verification checklist
Indexer
integration_stage2: ingest syntheticPodiumPoolsToppedUp→ HTTP totals + recent rows matchSCHEMA_VERSIONdocumented inindexer/README.mdFrontend
Docs / invariants (can land in #260 if split)
INV-INDEXER-*-DONATE-POOLS+INV-FRONTEND-*-DONATE-POOLSindocs/testing/invariants-and-business-logic.mddocs/frontend/timecurve-views.md§ donate-poolsmarked as related to #238
marked as related to #261
mentioned in commit
b78aa914bdImplementation summary (merged to
main)Delivered GitLab #262 together with onchain #261 (
topUpPodiumPools+PodiumPoolsToppedUp).Contracts
TimeArena.topUpPodiumPools(uint256)— permissionless DOUB pull, 100% to eight prize vaults viaArenaBuyRouting.splitPrizeTopUpAmount(10:7.5 active:seed per category), no admin vault / nototalDoubRaisedbump.ArenaPrizeRouting.t.sol,TimeArena.t.sol::test_topUpPodiumPools_*.Indexer (schema 2.1.0)
idx_arena_podium_pool_top_up.PodiumPoolsToppedUp.GET /v1/arena/podium-pool-donations— totals,recent[], optionaldonor_summarywhen?donor=0x….integration_stage2HTTP smoke.Frontend (AUDIT
/timecurve/protocol)data-testid="timecurve-protocol-donate-pools"with required no-benefit disclosure, DOUB approve + donate write path, indexer read path, wallet profile on donor rows.Docs / invariants / play skill
INV-TIME-ARENA-PODIUM-TOPUP,INV-INDEXER-262-DONATE-POOLS,INV-FRONTEND-262-DONATE-POOLSVerification checklist
forge test --match-contract "ArenaPrizeRouting|TimeArena"cd indexer && cargo clippy --all-targets -- -D warnings && cargo test(withYIELDOMEGA_PG_TEST_URLfor fullintegration_stage2)cd frontend && npm testandnpm run typecheckPodiumPoolsToppedUptx; confirmGET /v1/arena/podium-pool-donationstotals matchtopUpPodiumPools→ vault balances match 700e18 prize slice equivalence@brouie — please run the checklist above on devnet/staging when you have a moment. Leaving this issue open until verified.
mentioned in issue #264
mentioned in issue #267
marked as related to #267
mentioned in issue #261
mentioned in commit
7ee04422acVerification complete (GitLab #262)
Verified on worktree
issue/262-verify-donate-pools, merged tomainas7ee0442.What was verified
Contracts (#261 dependency)
forge test --match-test test_topUpPodiumPools— 5/5 passArenaPrizeRouting.t.soltop-up split tests — passIndexer
postgres_stage2_persist_all_events_and_rollback_afterwithYIELDOMEGA_PG_TEST_URL— pass (includesapi_podium_pool_donations_smoke)bash scripts/verify-donate-pools-anvil.sh— mint → approve →topUpPodiumPools(700e18)→GET /v1/arena/podium-pool-donationstotal700000000000000000000Frontend
ArenaProtocolDonatePoolsSection.test.tsx— disclosure + indexer empty/offline placeholders (3 tests)npm run typecheck— passe2e/arena.spec.ts— AUDIT carddata-testid="arena-protocol-donate-pools"visibilityDocs / invariants
INV-INDEXER-262-DONATE-POOLS,INV-FRONTEND-262-DONATE-POOLS, arena-views § donate-pools, indexer design, play-time-arena-doub skill — already crosslinkeddocs/testing/manual-qa-checklists.mdChanges in this verification pass
scripts/verify-donate-pools-anvil.shfor repeatable Anvil + indexer E2EChecklist for follow-up QA
bash scripts/verify-donate-pools-anvil.sh(needs Anvil, Postgres on:5433,PGPASSWORD=password)export YIELDOMEGA_PG_TEST_URL=postgres://yieldomega:password@127.0.0.1:5433/yieldomega_indexer && cd indexer && cargo test postgres_stage2cd frontend && npm test -- src/pages/arena/ArenaProtocolDonatePoolsSection.test.tsx/arena/protocol: disclosure visible without wallet; wrong-network write gate; connected donate refreshes totals after indexer catch-upFollow-up from #267 QA: donate-pools path (
PodiumPoolsToppedUp→idx_arena_podium_pool_top_up+GET /v1/arena/podium-pool-donations) remains unchanged. Per-buy vault funding events (PodiumFunded/SeedFunded/AdminVaultFunded) are tracked separately in #267 — now verified and closed withbash scripts/verify-vault-funding-anvil.sh(no regression to this donate API).