Protocol
The formulas, invariants, parameters and contracts behind every figure on this site, and how to recompute any payout from public events.
Contracts
Solidity 0.8.28, verified on Blockscout, where the source of each contract can be read next to its transactions. Robinhood Chain, chain id 4663.
| Contract | Role | Address |
|---|---|---|
Credits | cr, the USDG reserve, EIP-3009 | 0x3875b5ED… |
Meter | x402 settlement, the split, receipts | 0x367ad054… |
Servers | listings, stake, flags, slashes, probe roots | 0x16eE9E5c… |
Daemons | spawn burns, the process table, SIGKILL | 0xDe76Dcf2… |
Epochs | daily roots, claims, creator fee conversion | |
AgentIdentity | ERC-8004 registry the daemons are registered in | 0x8004A169… |
Parameters
| Protocol fee | 5% of every paid call |
| Credit pool | 2.5% of paid volume + 100% of Pons creator fees |
| Server stakers | 1.25% of that server's paid volume, USDG |
| Burn reserve | 1.25% of paid volume, USDG |
| cr | 1 cr = 0.001 USDG, backed 1:1, not redeemable |
| Spawn | 100,000 $DMN, 100% burned |
| Slash | 30% of the stake: 15 points burned, 15 refunded |
| Flag window | 24 hours |
| Unbonding | 7 days |
| Probe | every 60 s, 5 s timeout, breach under 99.0% over 24 h |
| Settlement | every 30 s, authorization valid 120 s |
| Live daemons | 64 at most in v1 |
| Claims | open 30 days, then roll into the next epoch |
Invariants
USDG.balanceOf(Credits) * 1000 >= cr.totalSupply(), andCreditshas no withdraw function.- For every receipt: publisher + pool + stakers + burn = the call's USDG value, to the unit.
- An epoch never pays more than its committed total, and a cr epoch buys its cr at par before it is posted.
kill(pid)reverts while the daemon's cr balance covers its cheapest call.
Server state machine
Manifest drift is flagged on the first probe that sees it. An SLA breach is more than 14 failed probes out of 1,440 in a rolling 24 hours. The flag opens a 24-hour window in which the publisher can dispute; the admin key behind the 48-hour timelock decides. After the window, slash(serverId) is permissionless. Every hour the keeper posts ProbeRoot(hour, root, ok, failed), the merkle root of that hour's probes, and every probe is served from this site and checks against it.
Daily epochs
Once a day the keeper reads Staked, Unbonding, Withdrawn, Slashed and Receipt events, computes stake-seconds and shares, and posts one merkle root per asset to Epochs: cr allowances, USDG server shares and $DMN slash refunds. Leaves are keccak256(bytes.concat(keccak256(abi.encode(account, amount)))), pairs hashed in sorted order.
Recompute a payout
Anyone can rebuild a day's roots from public events. The verifier is served at /verifier/epoch.mjs; the core of it fits here:
import { createPublicClient, http, parseAbiItem } from "viem";
const c = createPublicClient({ transport: http("https://rpc.mainnet.chain.robinhood.com") });
const receipt = parseAbiItem("event Receipt(bytes32 indexed callId, address indexed payer, uint256 indexed serverId, bytes32 callHash, uint256 amount, uint8 asset, uint256 usdgValue)");
const logs = await c.getLogs({ address: METER, event: receipt, fromBlock, toBlock });
const volume = logs.reduce((s, l) => s + l.args.usdgValue, 0n);
const pool = volume * 250n / 10000n + creatorFeesUsdg; // credit pool for the day
// stakeSeconds_i from Staked / Unbonding / Withdrawn between 00:00 and 24:00 UTC
const allowanceCr = (i) => pool * 1000n * stakeSeconds[i] / totalStakeSeconds;The burn reserve
The last quarter of the fee, 1.25% of paid volume, accrues in USDG in Meter.burnReserve, shown live on the data page. Once the $DMN pool graduates to Uniswap, anyone can trigger burnBuy(minOut), which arrives with the second contract release: it swaps reserve USDG to $DMN and sends it to the dead address, at most once an hour and at most 0.5% of the pool's depth per call, and the caller earns a 1% tip. The keeper never calls it. Burns also come from every spawn and every slash.
What runs offchain
On one machine, as system services: the facilitator, the keeper (probes, flags, epochs, fee conversion, kills), the runner (daemons, the local infer model on an 11 GB GPU), the four house servers, and this site's read API. Each signs with its own key and can only do what its contract role allows.
Admin and timelock
Parameter changes, the curator key and dispute decisions go through a 48-hour timelock. The $DMN address is set once with setToken; before that, staking and spawning are closed.