Petaldocs

How it works

The money path hop by hop, and an example settlement from a charity address on Robinhood Chain to USDC on Base.

The money path

Pons curve or poolRobinhood Chain

Every trade accrues creator fees in ETH.

sweepPons, when a curve or pool is swept
Pons Fee EscrowRobinhood Chain

Pull-based ledger. The balance is credited to the charity address; only the balance holder can claim.

claimAndBridge: claim()anyone; the keeper on a 300 s tick
Charity addressRobinhood Chain

The contract set as creatorFeeRecipient. One per config ID. No owner, no admin, no way to redirect.

claimAndBridge: depositV3, at least the minimum bridge amount, fee at most the live fee capsame call
AcrossAcross

depositV3 from the charity address, recipient = the receiver for the same config ID on Base. Fills in about a second.

fill, delivered as WETHan Across relayer
ReceiverBase

One per config ID. Across pays it in WETH; flush unwraps and hands the whole balance to donate.gg.

flush: unwrap WETH, donateNative(configId, 0, receiver, message)anyone; the keeper on the same tick
donate.gg donateNativeBase

Credited under the charity's config ID with tip 0. donate.gg emits DonationMade.

DonationEpochClosed, DonationEpochProcesseddonate.gg
donate.gg epoch processingBase

donate.gg closes the epoch, converts to USDC and pays out on-chain. Timing is donate.gg's.

Charity

90% of the settled USDC, paid to the charity's own address.

donate.gg

10% of the settled USDC, donate.gg's fee.

The money path. Every hop from the charity address onward is a public function on an immutable contract or an event emitted by donate.gg; there is no step where a private key can send the money anywhere else.

Hop by hop

  1. Pons curve or pool → Pons Fee Escrow. Every trade on a Pons token accrues creator fees. Fees only land in Pons Fee Escrow after Pons sweeps the curve or pool; the escrow credits them to the token's creatorFeeRecipient, which is the charity address. Escrow is pull-based: nothing is pushed, and only the balance holder can claim.
  2. Charity address: claimAndBridge. One call, callable by anyone. It calls claim() on Pons Fee Escrow, adds any ETH the charity address already holds and any WETH it holds (an Across refund arrives as WETH), and requires the total to be at least the minimum bridge amount (0.01 ETH). The caller supplies outputAmount from a live Across quote; the contract requires total - outputAmount to be at most the registry's live fee cap. It then calls Across depositV3 with the charity address as depositor and the receiver for the same config ID on Base as recipient. The receiver address is computed on Robinhood Chain from the Base registry and receiver implementation addresses fixed in the registry at construction.
  3. Across. A relayer fills the deposit on Base, normally within a block. Contract recipients are paid in WETH, never native ETH. A deposit not filled within the 2-hour fill deadline is refunded to the charity address on Robinhood Chain, as WETH, and is included in the next claimAndBridge.
  4. Receiver: flush. Callable by anyone. It unwraps any WETH it holds, requires a non-zero balance, and calls donate.gg donateNative(configId, 0, receiver, "pons-charity-relay/robinhood") with the whole balance. donate.gg emits DonationMade under the charity's config ID with tip 0.
  5. donate.gg epoch processing. donate.gg closes the epoch (DonationEpochClosed), converts the pooled ETH to USDC and pays out (DonationEpochProcessed): 90% to the charity's own address, 10% to donate.gg. Timing is donate.gg's.

The keeper triggers hops 2 and 4 on a 300-second tick. It has no on-chain role; if it stops, anyone else can make the same calls. See Keeper and relay.

The four steps on the landing page

The landing page compresses the path into four steps. Each maps onto the hops above:

StepMechanism
LaunchBefore hop 1: TokenParams.creatorFeeRecipient set to a charity address at launch, or transferCreatorFeeRecipient later, with native ETH as the pair token. See Integration guide.
TradeHop 1. Fees accrue per trade on the curve or pool and are credited to the charity address in Pons Fee Escrow at sweep.
RelayHops 2 and 3: claimAndBridge on the charity address, callable by anyone, and the Across fill.
PaidHops 4 and 5: flush on the receiver hands the ETH to donate.gg, whose epoch processing pays the charity in USDC on Base.

The figures the landing and the charities page show beside this path come from the indexer, which is not part of it. See Live data.

An example settlement

One settlement recorded on-chain, from ETH arriving at a charity address on Robinhood Chain to USDC arriving at the charity through donate.gg on Base. The table is rendered from the same data record as the landing page timeline.

Date
2026-09-07
Charity
Lung Cancer Foundation of America
Config ID
0x1afeffb9a6ec345f9ba7819cc9759bdf4a66fef51225cebae777c6859e04c505
Charity address
0xe9Be25C1E46d05033d71bBcAc649C5D53782EA50
#StepChainAmountTransaction
10.011 ETH sent to the charity address (the held-ETH path, identical to an Across refund)Robinhood Chain0.011 ETH0xef9f…c11d(Blockscout)
2Keeper calls claimAndBridge; Across deposit 197442Robinhood Chain0.011 ETH0xee83…7ffe(Blockscout)
3Across fills 0.0109966 WETH to the receiverBase0.0109966 ETH0x2832…5272(Basescan)
4Keeper calls flush; WETH unwrapped, donate.gg records DonationMade (epoch 1, tip 0)Base0xa162…78c9(Basescan)
5donate.gg closes the epochBase0xe420…82ef(Basescan)
6donate.gg processes the epoch and settles 27.258856 USDCBase27.258856 USDC0x06bd…47a7(Basescan)
Settled by donate.gg27.258856 USDC
To the charity (90%)24.532970 USDC
To donate.gg (10%)2.725886 USDC

Reading the settlement

  • Step 1: ETH arrives at the charity address directly rather than through a Pons sweep. claimAndBridge treats held ETH exactly like an Across refund, so the call runs the same path with a zero escrow balance. The escrow path itself is covered by fork tests against the real Pons Fee Escrow.
  • Step 2: claimAndBridge. The Across fee is 0.0000034 ETH, well under the live fee cap of 0.001 ETH.
  • Step 3: the Across fill, delivered as WETH. The receiver unwraps it before calling donate.gg.
  • Step 4: flush. The receipt carries donate.gg's DonationMade event with the charity's config ID, tip 0, and the receiver as the credited address.
  • Steps 5 and 6 are donate.gg's epoch processing. Bridge to fill: 1 block. Fill to flush: 3 blocks. Flush to payout: 7 blocks. Under 30 seconds from bridge to the charity being paid.
  • The split: 27.258856 USDC settled, 24.532970 USDC to the charity and 2.725886 USDC to donate.gg.