Charter v0.1 · 2026-09-16 · Robinhood Chain
The contracts are live on Robinhood Chain mainnet 4663, trading tokenised equities through the Uniswap v3 pools already on the chain. No token exists. This page is the mechanism in full, including the parts that do not flatter it.
To let software trade for you today, you give it a private key. A key is not a permission. It is everything you have, forever, to anyone who ever reads it. LEASH replaces the key with a leash: a scoped, revocable, on-chain grant of authority. The principal writes what the agent may do, which venues, which assets, how much per action, how much per hour, how much it may lose, until when. The agent trades inside that and cannot step outside it, because the contract refuses the transaction before it lands. Value in the purse has exactly one exit and it points at the principal. Revocation takes one transaction and needs nobody's consent. Every attempt is written down, including the refusals, so an agent's public record shows not only what it earned but how often it tried a door that was locked.
A leash is the tuple of five clauses plus the parties and a nonce, hashed to clauseHash at DRAFT and immutable for the term. Governance sets the permitted ranges; the principal picks values inside them.
{ adapterIds[], assets[] }
The purse may call no contract outside adapterIds and may hold no asset outside assets after an action completes. Checked before, and the asset half re-checked after.
{ maxPerActionWei, maxPerHourWei, maxSlippageBps }
The rolling hour is a timestamped ring buffer, not a calendar hour. maxSlippageBps is checked after execution against the quote the adapter returned before it. Without this bound, an agent inside scope can still hand your money to itself at a bad price.
{ stopBps, highWaterWei }
Purse value is priced through the adapters' own quote functions for the assets in scope. Crossing stopBps below the high-water value moves the leash to ENDED with cause LOSS, on the action that crosses it or on any poke.
{ expiresAt, minIntervalSeconds, refusalStreakForHold, holdSeconds }
All timestamps are L2 block.timestamp. On this chain block.number tracks the L1 block and advances roughly every 15 seconds, which makes it useless for tempo and expiry.
{ performanceBps, flatBpsPerYear, highWaterMark }
Crystallized only at SETTLED.
Anyone may poke a leash to force evaluation of Loss and Term against current state. Pokes are cheap and permissionless so that an idle leash cannot outlive its own stop.
Three layers, in order.
What the bond covers, because the three layers cannot: self-dealing that stays inside the slippage bound, churn that manufactures a performance fee, abandonment mid-term while holding a position, and adapter misuse that a later adapter fix reveals. What the bond does not cover: losing money inside the clauses, which is the thing the principal agreed to.
Proposed for governance, not facts
| Parameter | Range or value |
|---|---|
| Max per action | 0.001 to 5 ETH equivalent |
| Max per hour | 1x to 20x max per action |
| Slippage bound | 10 to 1000 bps |
| Loss stop | 2% to 50% of high-water |
| Term | 1 hour to 90 days |
| Min interval between actions | 0 to 3600 s |
| Refusal streak for hold | 3 to 20 |
| Hold duration | 60 s to 24 h |
| Agent performance fee | 0 to 5000 bps over high-water |
| Agent flat fee | 0 to 500 bps per year, accrued per second |
| Protocol take | 10% of crystallized agent fees |
| Agent bond | floor plus 2% of capital under leash |
| Adapter bond | 25x the agent floor |
| Slash split | 70% harmed principal, 20% watcher, 10% treasury |
At SETTLED, in order: price the purse through scope adapters, compute the flat fee accrued per second over the elapsed term, compute the performance fee on the excess over highWaterMark after the flat fee, deduct the protocol take from the agent's total, pay the agent, return everything else to the principal, write the outcome to the agent's record.
Early revocation pays the flat fee accrued to that second and any performance earned to that second. Revoking does not cancel what the agent has already earned, which is the property that makes an instant unilateral revoke acceptable to agents rather than a reason not to accept leashes.
An agent below its high-water mark is paid nothing on performance, including on a leash it ran well after a bad start. High-water is per leash, not per agent, and does not carry across principals.
A claim is filed by a watcher with a stake, names one condition, cites transactions, and runs a challenge window. The agent may answer. Both the claim and the answer are permanent.
Slashable: self-dealing evidenced by a pattern of adverse fills against a related counterparty; churn evidenced by round trips with no economic purpose that raise a performance fee; abandonment; misrepresentation on the agent card. Not slashable: losses inside the clauses, refusals, and being wrong.
Adapter bonds slash on a reported quote that diverges from the executable price beyond a stated tolerance, an unreported reachable call path, or an upgrade that changes behaviour without a new listing.
LeashDrafted(id, principal, agent, clauseHash) · LeashActivated(id, funded) · Acted(id, adapter, selector, valueIn, valueOut, reasonHash) · Refused(id, clause, code, detail) · Held(id, by, until) · Released(id) · Ended(id, cause) · Settled(id, agentFee, protocolTake, returned) · ClaimFiled(claimId, target, condition) · Slashed(target, amount, split)
Refusal codes:
SCOPE_ADAPTER · SCOPE_ASSET · SIZE_ACTION · SIZE_RATE · SLIPPAGE · TERM_EXPIRED · TERM_TEMPO · LOSS_STOP · HELD · NOT_AGENT
Live on Robinhood Chain mainnet. The venue is the Uniswap v3 already deployed on the chain, so the assets are the tokenised equities rather than anything we minted: NVDA, TSLA, SPY, AAPL, MSTR and SPCX, each listed at its deepest fee tier after measuring real depth. Listing an asset names its canonical tier, which is the price every action is measured against, so each listing is a security decision.
Three agents run by us, off chain, each with a published address and a bond in the registry. The reference price for the slippage bound is the canonical tier's spot, read from that pool, so a leash's bound has to be wider than the tier's own fee: 5 bps at the 500 tier, 100 bps at the 10000 tier. The app warns when a bound is too tight to ever fill.
Nothing on this chain is simulated. Every line in a ledger in the app is decoded from a contract event and carries the transaction hash that produced it.
LEASH · Charter v0.1 · 2026-09-16 · Robinhood Chain mainnet 4663. No token exists. Nothing here is an offer or investment advice.