M3 · On-chain and money (T30–T33) 🔒
Every ticket here moves real funds. Human line-by-line review, testnet runs and recorded tx hashes in each PR are mandatory before merge.
Exit gate: on testnet, 23 slices executed over 7 days (or accelerated schedule in test mode), each bought and burned in one transaction, never above 1% of liquidity; treasury split exact to the wei; ledger matches the chain.
T30 · BuybackBurner contract 🔒 ⚠️ Pons#
Goal The only Vivra contract: buy a token with ETH and burn everything received, in one transaction, under hard caps.
Depends on T00
Read first annexe-contrats.md (entire page), buyback-bot.md
Build contracts/src/{IBuybackBurner.sol,BuybackBurner.sol}, contracts/test/{BuybackBurner.t.sol,BuybackBurner.fork.t.sol}, contracts/script/Deploy.s.sol, foundry.toml
Steps
- Start from the interface and skeleton of annexe D verbatim (immutable owner, caps, operator, pause, events, errors).
- Implement
_buyOnCurveand_buyOnV4Poolusing the Pons curve ABI and the Uniswap v4 router / PoolManager path used by the Meme hook. ⚠️ If the exact call path or the hook's fee behaviour is unclear from the verified ABIs, STOP and ask; do not guess. - Refund unused ETH to the operator in the same tx. Assert the contract holds 0 of the bought token at the end.
- Foundry tests: every row of the annexe D test table + fuzz on
amountIn/minOut+ fork tests on a recorded mainnet block for one curve token and one graduated token. - Deploy script reading owner, operator, caps from env; prints the address; verification command in README.
Done when
-
forge testgreen (unit + fuzz, 1,000 runs) -
forge test --fork-url $RPC_URL_MAINNETgreen on both routes - Deployed on testnet; address + verified explorer link in the PR
- Gas report included in the PR
Out of scope Scheduling (T31).
T31 · Buyback planner and executor 🔒#
Goal Plan ~23 secret random slices over 7 days and execute them safely.
Depends on T02, T11, T22, T30
Read first buyback-bot.md, annexe-base-de-donnees.md (buyback_plans, buyback_slices), parcours-4.md
Build packages/core/src/buybackPlan.ts, apps/workers/src/jobs/{buyback.start,buyback.slice,buyback.refill}.ts
Steps
planBuyback({ envelopeWei, capWei, start, end, slices=23, seed })(pure): random times with min 2h spacing, amounts sum ≤ min(envelope, cap); returns schedule. Times encrypted (SLICE_SCHEDULE_KEY) before storage.buyback.startat J+1: computes envelope (reserve + leftovers, capped at the token's market cap at vote time), creates plan + slices, schedules delayed BullMQ jobs at each time.buyback.slice: re-read liquidity; size = min(planned, 1% of liquidity); quote;minOutwith 2% slippage; callbuyAndBurnviasendTx; on revert/slippage →skipped+ alert, never retry bigger; write ledger + publish WSslice.executed; publish the tx after execution only.- Early stop at J+3 if average volume hasn't doubled vs the 7 days before the vote → remaining slices
skipped, leftover flagged for next token. - Curve token graduating mid-plan → stop per spec (setting).
buyback.refilldaily: top up the hot wallet from reserve up to one day of slices (manual signature if the reserve is a team wallet: create a validation instead).- Same planner reused for
$VIVRAbuybacks from CTO fees (targetvivra).
Done when
- Property tests: amounts never exceed envelope/cap; ≥ 2h spacing; deterministic for a given seed
- Executor test with mocked chain: slice > 1% liquidity is resized; slippage revert →
skipped+ alert, no retry - Early-stop test on fixture volumes
- Testnet accelerated mode (
BUYBACK_TEST_SPEEDUP=1, 23 slices in 23 min): all burned, tx hashes in the PR
T32 · Treasury daily job 🔒 ⚠️ Pons#
Goal Sweep, claim and split $VIVRA fees every day; claim CTO fees into the Fees CTO wallet for the $VIVRA burn.
Depends on T02, T10
Read first token-vivra-et-tresorerie.md, cto-pons-et-frais.md, annexe-contrats.md (Job quotidien), questions-ouvertes.md (Pons questions)
Build apps/workers/src/jobs/treasury.daily.ts, packages/core/src/split.ts
Steps
- Read pending fees (hook or curve); sweep if needed; handle
InternalSwapRequiresOperatorby skipping and alerting. - Claim from the escrow for
CollecteandFees CTOwallets. ⚠️claim()vsclaim(uint256): detect from the verified ABI; if both exist or neither matches, stop and ask. split(amountWei)(pure): 17/37 team, 15/37 buyback reserve, 5/37 AI; remainder wei goes to buyback reserve; sum must equal input.- Transfers + ledger rows (
fees_in,split,cto_fees_in); attribution per CTO token from escrowCreditedevents. - AI wallet: create a manual task (validation) "swap to USDC and bridge to Base for Surplus" with the amount; automation of the bridge is out of scope for V1.
Done when
-
splitproperty test: parts always sum to input exactly, ratios within 1 wei - Testnet run on a test token with
creatorTaxBps=300: claimed and split, ledger matches balances to the wei (PR includes tx hashes) - Running the job twice the same day does nothing the second time (idempotency test)
T33 · Ledger and Pons CTO tracking#
Goal Public ledger API and live tracking of each CTO request until fees flow.
Depends on T01, T02, T32
Read first cto-pons-et-frais.md, annexe-api.md (/ledger, /wallets), parcours-5.md
Build apps/api/src/routes/{ledger,wallets}.ts, apps/workers/src/jobs/tracking.cto.ts, admin page apps/admin/app/cto/page.tsx
Steps
GET /ledgerwith filters + cursor;GET /walletswith live balances.cto_requestslifecycle: draft (dossier generated by CM step) → submitted (team clicks after manual submission on cto.ponsfamily.com) → accepted/refused (team) →recipient_pending(detectedpendingCreatorFeeRecipient= Fees CTO wallet) →recipient_active(eventCreatorFeeRecipientUpdated).- Daily check for each CTO token; alert on status change.
Done when
- Ledger API test: filters and pagination return stable order
- Fixture events drive a request from
submittedtorecipient_active(test) - Admin page shows each request with its status and dates