Staking economics: exposure-scaled collateral
When your agent puts USDC into escrow with an operator it found on its own, the thing standing
between you and a cheat is that operator's stake. It is sized to always answer for the money the
operator holds, yet never so large that only funds and firms can run a node: a node's stake sets
the entry floor, caps how much client escrow it may hold, and sizes the penalty an upheld dispute
takes. The mechanics live in StakingManager, PaymentManager and DisputeManager.
Why not a flat stake
The obvious design is one number, minNodeStake, doing all the work. It fails you twice. Set
it high enough to matter and it becomes a barrier to entry: at any meaningful ZAI price, a
five-figure flat stake excludes the long tail of independent operators the network needs to be
a marketplace rather than a cartel, and an agent that wants to try one service against another
finds nobody to switch to. Set it lower and security decouples from harm: a flat stake gates
only the number of concurrent sessions (tokensPerSession), not their value. A node
staking the minimum could hold unlimited client escrow, and an upheld dispute would slash a
fixed 5,000 ZAI whether the operator was a hobbyist or a whale holding a million dollars of
client deposits. Neither is acceptable when it is your deposit in the escrow, so the design
uses three levers.
The model
Each lever has one job, and each is a parameter governance retunes without touching the others.
| Lever | Job | Parameter |
|---|---|---|
| Entry floor | Sybil resistance + a baseline slashable identity | StakingManager.minNodeStake (the node's total, own + delegated) over minSelfStake (the operator's own) |
| Exposure cap | Bound the harm a node can do by its collateral | PaymentManager.escrowCapPerStake[asset] |
| Proportional slash | Make the penalty track the operator's size | DisputeManager.slashBps floored by slashAmount |
1. Entry floor — anchored at $5,000–$10,000
A node serves behind $5k–$10k of ZAI of total stake, the operator's own and their backers'
together. Enough skin in the game that an upheld dispute, slashing 10% of stake, is a real
penalty, and enough that burning an identity to escape a bad reputation costs thousands rather
than cents. The operator's own share is small, minSelfStake (100 ZAI): enough to list and to
be first in line for the slash, while the rest comes from the network's staking node or from
delegators, who are diluted alongside them. The staking node is a pool anyone runs: it backs a
listing only after real checks (the listing on its node, the operator's own floor, no slash or
open dispute, a price within the gallery's band, one sample call) and a model's reading against
a rubric, earns the delegator share like any delegator, and pulls its ZAI the moment a node stops
answering, a dispute is raised or a slash lands. The floor is met by capital that looked. Reputation is worth
escaping because the agents that use a node rate its operator on-chain after every settled
session, from the errors and slow answers they saw, so a record of poor service follows the
address. The floor is reachable for a serious independent operator who has convinced nobody yet, and
far below a six-figure stake that would centralise the network to funds and firms. Going live
and growing do not need more of the operator's own: delegation supplies both, so the own
floor is an entry ticket, not a growth ceiling.
Both floors are denominated in ZAI. Governance sets minNodeStake to the ZAI amount worth
≈ $7,500, keeps minSelfStake a small fraction of it, and retunes them when price moves
materially (the same setParams governance action).
2. Exposure cap — escrow bounded by stake
This lever protects your deposit directly. PaymentManager tracks each operator's total
open escrow per asset (openEscrowOf[operator][asset], maintained on
open/settle/reclaim/close/dispute-refund) and rejects openSession when it would exceed:
escrowCapacityOf(operator, asset) = totalStakeOf(operator) × escrowCapPerStake[asset] / 1e18
escrowCapPerStake[asset] is the number of units of asset (in its own decimals) that each
1e18 of staked ZAI may back. 0 disables the cap for that asset; a production deployment
sets a value for every accepted asset.
The invariant: a node can never hold more client escrow than its slashable collateral can
answer for. Open escrow value stays at or below 50% of stake value (k = 0.5). Capacity
scales with delegation, because totalStakeOf includes delegated ZAI, so a small operator with
a $7.5k floor stake serves more escrow by attracting delegators, who earn the delegator share
of every settlement and eat slash dilution pro-rata: paid to underwrite the node. Entry is
cheap, scale is underwritten. The ratio doubles as a manual price oracle: it converts ZAI
stake into asset-units of allowed escrow, so governance retunes it when ZAI/asset moves. The
stale-ratio risk is asymmetric. If ZAI rises the caps become too tight and capacity runs short,
annoying but safe; if ZAI falls the caps become too generous and the network is
under-collateralised, unsafe. So k carries margin and governance retunes on drawdowns first.
3. Proportional slash with a floor
An upheld dispute slashes:
max( slashAmount, stakeAtRaise × slashBps / 10_000 )
slashBps is 1000 (10% of stake): an operator who defrauds one client loses 10% of
everything they and their delegators posted, plus reputation, plus, if repeated, their spot
above minNodeStake; repeated offences stack multiplicatively. slashAmount is the floor,
≈ 5–10% of minNodeStake, which keeps a sting even when live stake is tiny. stakeAtRaise
is snapshotted when the dispute is raised (Dispute.stakeAtRaise), so an operator cannot
shrink the penalty base by unstaking while the case is heard; the unbonding cooldown (7 days)
outlasting the dispute window (3 days) makes queued stake reachable (A1), and the snapshot
closes the calculation side of the same hole. The challenger reward (A4, 20% of recovered
slash) and the post-settlement slash-to-client (A2) scale with the operator's size, so a client
harmed by a whale node receives whale-sized compensation.
Why fraud doesn't pay (worked example)
Take example numbers: ZAI = $0.75, minNodeStake = 10,000 ZAI ($7.5k), k = 0.5,
slashBps = 10%, floor = 1,000 ZAI ($750), challenger reward 20%.
A node staked at the floor has $7,500 at risk, the operator's own and their backers'
together, and may hold $3,750 of open escrow. The best-case theft per session is the unspent service, not the escrow: the operator
can never settle more than the vouchers your agent signed, so cheating means taking payment and
not delivering, exactly what a dispute punishes. One upheld dispute slashes $750 (10%),
$150 of it to the challenger on top of their refunded escrow and bond, and that one dispute
already drops a floor-staked node below minNodeStake: isActiveNode turns false and no new
sessions open until the operator or their backers top up. Every later dispute takes at least the 1,000-ZAI
floor, so ten of them take the whole stake. To hold 10× the escrow ($37.5k), the operator needs
$75k of stake at risk, and attracting it through delegation means convincing delegators who are
first in line for dilution.
A sybil fleet buys nothing: N floor-stake nodes cost N × $7.5k and each is capped at $3,750 of escrow, so fraud capacity scales linearly with capital burned, with no discount.
Backing: skin in the game, and the network's staking node
Two floors, two jobs. minSelfStake (100 ZAI) is the operator's own: the entry ticket, first in
line for a slash, small enough that anyone with an API key can list. minNodeStake (10,000 ZAI)
is the total behind the node, own plus delegated, at which it may take paid calls: the collateral
that answers for buyers' deposits. The gap between them is filled by capital that looked. A person
who trusts an operator delegates and earns the delegator share; for everyone else there is the
network's staking node (how it decides):
a pool of ZAI anyone runs that backs a listing only after real checks, the listing on its node,
the own floor, no slash or open dispute, a price within the gallery's band, one sample call, and
a model's reading of the listing against a rubric, then delegates the gap plus two sessions of
headroom, earns like any delegator, is slashed like any delegator, and pulls its ZAI the moment
the node stops answering, a dispute is raised or a slash lands. A seller goes live with 100 ZAI of
their own and a review that takes seconds; a listing that is fake, useless, mispriced or dishonest
finds no backer and never goes live. The floor stays a floor; what changes is who has to supply it.
Why providers list
The same numbers are the case for a provider. Listing costs nothing beyond stake, and the stake can be backed: the network's share, 5%, is taken at settlement out of what a buyer already paid, so there is no fee to list, no card on file, no invoice. The provider integrates nothing beyond the API it already runs, and whoever holds a key can list it, but the first-party listing earns the reputation: the rating agents write after every settled session follows the operator address, the Official mark follows the domain that names it, and both rank the listing first among equals. Agents buy on merit, at every call, on price, rating and speed, so a listing wins calls by what it delivers, and demand pricing shows when to add capacity.
Skills: paid once, or per use
A skill is the smallest thing on the marketplace, a folder of instructions and scripts, and it has two prices. Per use: every load is a paid call through a session like any other, settled the same way. One-time: the agent pays once and keeps the files; every later load is served from its own copy, no session, no charge. The seller chooses; the buyer's agent sees the terms in the skill's line before it loads, and a bought skill is the agent's until the agent is deleted. The open-source index sits beside them for free, each skill with its licence, so a paid skill competes with the free ones on what it does. The same stake, split and slash apply as to any listing; a skill's node stakes like any node.
The auto-scaling loop
Stake answers for money held; price answers for capacity. A listing may let its node move the
price with demand (pricing in services.json: a floor, a ceiling, a target load, a window, a
step; selling). When calls queue on
a listing for a window, its price climbs a step, on-chain, and the marketplace says so: the indexer
keeps the price trail from ServiceUpdated events and the calls per hour, and every listing shows
"price up 25% today · 340 calls/h · 1 operator serves this".
That line is the incentive. Every gallery listing names its template, and anyone can run a copy from the service page, the CLI or Claude with their own key and stake. A second operator earns at the raised price; two nodes now share the load, each sees fewer calls in flight than its target, and each lowers its price a step per window back toward its floor. Agents that rank by price move to the cheaper copy first, so the operator who keeps undercutting keeps the calls. Capacity arrives where the money is and prices fall back as it arrives, with nobody setting either number by hand.
Bounds keep it honest. A price never leaves base–max, moves at most once per window, and every
move is an event anyone can audit against the load the node reported. A client that signed for the
old price gets a 402 with the current one; nobody pays more than they signed. Demand pricing does
not touch the stake rules above: a copy needs the same floors and the same slashable collateral as
the original.
The network learns
Price and stake say what a listing asks and risks; the rating says what it delivered, one number per operator. Buying on merit needs one more thing: what a tool is like for a particular kind of job. A price feed that is exact for bitcoin may be stale for a small token; an image model that wins on portraits may lose on diagrams. So every paid call an agent makes is also a report. When the session settles, the runner records one experience per session per tool: the kind of job, whether it worked or failed with the upstream's message, the judge's score when the output was judged, latency, cost, one line about it, signed by the wallet that paid.
The directory takes a record only from the client of a settled session with that service, never from the listing's own operator, one per session per tool, and weighs it by what was paid. A record costs a session, the deposit and the gas, and a session buys exactly one opinion: praising your own listing means paying yourself through escrow, minus the network's share, and earns one record per session for it; running down a rival means opening sessions with them and paying for what they serve. A failed call charges nothing, so its record is taken on the open session and counts as one call at the listing's price. The aggregate per tool per need is what every agent reads before it pays, and what the marketplace shows on the listing: Tested for image:gen: 92/100 over 12 runs · 96% ok · 8 s, with the latest notes.
The search an agent makes ranks by that experience for the need first, then price, rating and speed. A listing wins calls by what agents found with it, kind of job by kind of job, and a new listing earns its place through the calls it serves. Together with the rating and demand pricing, the network routes money to what works and away from what does not, with nobody in the middle.
Local development network defaults and production values
The local development network deploy (script/Deploy.s.sol, offchain deploy) demonstrates
mechanics, not prices: minSelfStake 100 ZAI, minNodeStake 10,000 ZAI, escrowCapPerStake[USDC]
= 100,000 (0.10 USDC per staked ZAI, so a 12,000-ZAI node backs 1,200 USDC), slashBps 1000,
floor 5,000 ZAI. The env overrides are MIN_SELF_STAKE, SLASH_BPS, ESCROW_CAP_USDC and
ESCROW_CAP_USDT.
Governance holds the production values against the ZAI price and retunes them when it moves
materially: minNodeStake at ZAI worth ≈ $7,500 (entry anchor $5k–10k) with minSelfStake a
small fraction of it,
escrowCapPerStake[asset] at k ≈ 0.5 for every accepted asset, slashAmount (the floor)
at ZAI worth ≈ 5–10% of the entry floor with slashBps = 1000, and tokensPerSession for
concurrency scaling.
Implementation map
The escrow cap lives in PaymentManager.sol:
escrowCapPerStake, openEscrowOf, setEscrowCapPerStake, escrowCapacityOf, the _open
check, and the releases in _settle / reclaim / operatorClose / resolveDispute. The
proportional slash lives in DisputeManager.sol:
slashBps, setSlashBps, Dispute.stakeAtRaise, _slashAndReward. The tests are in
EconomicsUpgrade.t.sol: cap enforcement and release on
every terminal path, delegation-scaled capacity, floor-vs-proportional slash, and the
raise-time snapshot against unstake.
Supply, allocation and the treasury's use of ZAI are in tokenomics.md and tokenomics-proposal.md.
Next: Arbitration — how an open set of staked jurors rules on a dispute without herding and without acquitting by apathy.