For the complete documentation index, see llms.txt. This page is also available as Markdown.

Treasury & Delegation

The $MOTION treasury is a MetaMask smart-account multisig on Robinhood Chain. The owners sign tightly scoped permissions that let the backend burn $MOTION and pay claims, and nothing else. Check the c

The $MOTION treasury is a smart-account multisig on Robinhood Chain, and it holds the supply that burns draw from. A burn is a one-way transfer to the dead address, where the tokens sit forever.

Two different powers run this treasury, and it is worth keeping them straight.

  • The backend can burn and pay claims, and can do nothing else. Our servers hold operator keys. The owners signed scoped permissions for them, and audited smart contracts re-check every rule on every single use, so the limits do not depend on our code behaving.

  • Everything else is an owner action. Moving treasury funds any other way takes the owners themselves, signing from their own wallets, and it takes more than one of them. No server can do it, and no single person can either.

This page shows you where to check both of those yourself.

What the burn key can do

The burn authority is one permission. It lets a single backend key do one thing: send $MOTION to the dead address. Here is the full list of what that key can and cannot do, enforced on-chain on every burn:

  • Only one token. It can touch the $MOTION token and no other contract.

  • Only one action. It can call transfer and nothing else. The token has no burn function, so a burn is just a transfer to the dead address.

  • Only one destination. The recipient is pinned to the dead address. The key cannot redirect a single token to a wallet.

  • Only so much. At most 10,000,000 MOTION can move per 30-minute period.

  • No ETH, ever. The permission moves zero ETH value.

Only a treasury owner can create this permission in the first place, and the DelegationManager contract, not our code, re-checks every rule on each burn. In practice the protocol burns far less than the ceiling: the application caps each cycle at 1,000,000 MOTION, and never more than the treasury's own balance.

The owners sign one permission. On-chain rules pin it to moving $MOTION only, to the dead address only, capped per 30-minute period, with zero ETH. The operator redeems that same permission every cycle.

Under the hood (for the technically curious)

The treasury signs one root delegation to the burn-operator key. The deployed grant carries exactly three on-chain caveats, checked by the DelegationManager on every redemption: an erc20PeriodTransfer caveat caps outflow at 10,000,000 MOTION per 1,800-second (30-minute) period; a valueLte caveat pins the ETH value to 0; and an allowedCalldata caveat pins the transfer recipient to the dead address. A burn is a transfer(address,uint256) because the production token exposes no burn(). Separately, the application clamps each cycle's burn to the minimum of its formula amount, 1,000,000 MOTION, and the live treasury balance, so it never approaches the on-chain ceiling.

Who holds the keys?

The application holds no owner key and no admin key. It holds operator keys, and the permissions above scope each one to its single job.

The owners are ordinary wallets, and everything that is not an automated burn or claim payout belongs to them: creating a treasury permission, topping up the treasury, and any other movement of treasury funds. Because they are the treasury's signers, together they can also change the treasury itself, including who the signers are and how many signatures it takes. That is what a multisig treasury is, and it is the same trust any multisig-held treasury asks for. None of it is unilateral and none of it is quiet: the treasury contract decides how many owner signatures an action takes, it is the contract that is asked and not our app, and every owner action lands on-chain in public like any other transaction. Ownership is also the admission ticket: to create a treasury permission, the connected wallet must already be an on-chain owner of the treasury.

Under the hood (for the technically curious)

Owners are EOAs, and the M-of-N threshold is the treasury's own on-chain getThreshold(). Call it on the treasury and read the number back for yourself. At the time of writing it returns 2, against the 3 owners getSigners() lists, so the live configuration is a 2-of-3 and no single owner can move treasury funds or change the treasury's rules. The implementation is the MetaMask Delegation Framework's MultiSigDeleGator, so owner actions at threshold include updateThreshold, changing the signer set, and upgrading the implementation. Creating a delegation requires the caller's wallet to be an on-chain isSigner of the deployed treasury. Owners sign the delegation as EIP-712 typed data inside their own wallets; the app never holds an owner key, and nothing the client sends can widen a permission. The web app and the burn worker read the treasury, operator, and token from the same deployed environment, so they can never disagree.

What can move a burn, and what cannot

Two more things are worth stating plainly, because they are the questions people actually ask.

Where the numbers come from. The protocol's indexing engine reads public X activity: the posts, who engaged them, and the public counts attached. Those records are the raw input, and a cycle scores what was observed. Every point, every creator's share, and the burn amount itself are computed deterministically from those records (the same records always produce the same numbers), and the raw records are retained as they arrived, so any cycle is auditable after the fact.

The input is boxed in by two hard ceilings that are not computed from it: the protocol clamps every cycle to 1,000,000 MOTION, and the on-chain permission refuses more than 10,000,000 MOTION per 30-minute period on top of that. Inside those ceilings, the observed activity shapes how big a cycle is and who gets credited. What it can never do, at any size, is move a token anywhere except the dead address, because that is pinned in the contract, not in our code.

A crash cannot double-burn a cycle. A burn is signed and written down before it is ever sent to the chain. If the worker crashes mid-burn and restarts, it finds the transaction it already signed and re-sends the exact same bytes. The network recognises them as the transaction it already has, not a new one, so the burn lands once.

Check the chain facts yourself

Everything the treasury does is public and on-chain. Production burns run on Robinhood Chain, chain ID 4663, and you can look all of this up on the block explorer, robinhoodchain.blockscout.com.

What
Address

$MOTION token

0x67e54665d8cef89a0bb3f2e21d34145c9f2ec430

Treasury (the smart-account multisig)

0x33fA782dB72FB755ae64f71c3d326C93e027B366

DelegationManager (checks every burn)

0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3

Burn operator (broadcasts the burn)

0x4CF214703d329B681Ebc602bFAA1A96e340b4Ca3

Dead address (where burns go)

0x000000000000000000000000000000000000dEaD

Every burn is a public transaction from the treasury to the dead address. Open the burn log, pick any completed row, and its PROOF link opens that transaction on the explorer. Two things to confirm there: the transfer moved exactly the amount the row shows, and it moved from the treasury to the dead address and nowhere else.

Total supply is fixed at 1,000,000,000 MOTION and never changes. A burn moves tokens to the dead address rather than reducing total supply, so circulating supply is total supply minus the dead-address balance. The treasury's own balance is the pool the burns draw from, and it falls with every cycle: call balanceOf on the treasury and on 0x…dEaD and you can price the whole thing yourself, live, any time.

Under the hood (for the technically curious)

The treasury is a proxy whose implementation is the framework's MultiSigDeleGator at 0x56a9EdB16a0105eb5a4C54f4C062e2868844f3A7. The live bytecode for all three core contracts is pinned by keccak256 hash, so you can confirm the deployed code matches the committed environment:

  • $MOTION token: 0x287afd61627652e33bc7e360a04a59e5c0d34a50914266397bb358583a53b598

  • Treasury: 0x8678a7d794f76a790255c0db52d6276dc7259cc7a211426bca106e5ebb4b1ddf

  • DelegationManager: 0xe45747f90ecec2ba96ae9f4a15c36289653efdfef7690bcfb90a1945bb0fe207

Startup validation checks eth_chainId and bytecode-verifies the token, treasury, and DelegationManager on the live chain before any burn is trusted. Each burn also publishes an evidence hash, the SHA-256 of that cycle's inputs, so a past burn can never be quietly re-scored under new rules.

How the burn authority is contained

Containment works at two layers, independent by design.

The application layer can starve it. An admin flips markRevoked in the application's delegation store, and every burn cycle that starts after the flip finds no delegation and does nothing. Revocation works at the granularity of a cycle: a cycle already past its lookup, or a transaction already signed and on the wire, runs to completion, deliberately, because signed bytes abandoned on the network are how a burn lands twice. Recovery finishes what exists and signs nothing further.

The chain scopes it. The permission itself is the wall: even a fully stolen operator key can only ever send treasury tokens to the dead address, at the capped per-period rate, destruction on a leash, never theft. It cannot reach a wallet, another token, or a single wei of ETH. And rotating an operator key is an owner ceremony, signed from an owner-controlled wallet, never a server.

What is the Smart Accounts Kit?

It is MetaMask's smart-accounts SDK plus its on-chain Delegation Framework: smart-contract accounts, a DelegationManager contract, and a library of small rule-checking contracts called caveat enforcers (MetaMask's docs). MetaMask pitches it as programmable account behavior with rule-based permission sharing, and that is exactly the part Motion runs on.

A delegation is a signed message. In it, one account (the delegator) grants another account (the delegate) permission to perform specific actions under strict conditions. The chain re-checks those conditions every time the permission is used. For $MOTION, the treasury is the delegator, the operator keys are the delegates, and the conditions are the rules listed above.

Naming note. MetaMask formerly shipped this as the "Delegation Toolkit". Same SDK, same framework (npm: @metamask/smart-accounts-kit); only the name changed, and older Motion material may still use the old one.

Why $MOTION builds on it

$MOTION burns on a fixed cadence: one burn every 30-minute cycle, up to 48 treasury transactions a day. That cadence is the whole design problem, and the two obvious ways to run a treasury both fail at it.

  • A plain multisig. Its owners would have to hold a live signing ceremony for every single burn. That is 48 ceremonies a day, every day. The moment a signer is away, burns stall.

  • A backend admin key. It keeps up with the cadence, but a key that can move treasury funds can move them anywhere. One server compromise drains the treasury.

The Smart Accounts Kit gives you the speed of an admin key with the safety of a multisig. The owners sign once. From then on the contracts carry every burn and enforce the rules, instead of trusting anyone to follow them.

Tipping runs on the same building block, one level up. A tip itself never touches the chain: it moves allocation between accounts in the protocol's ledger, person to person, until someone claims. What the owners signed is a second scoped permission, separate from the burn's and held by its own key, that lets the backend pay a creator's accumulated claim out of the treasury, inside its own hard caps. One signed grant covers every claim; no per-tip permission exists, and no tip waits on a signing ceremony. The plain version is on Tipping.

Built on audited, open-source contracts

$MOTION does not roll its own treasury contracts. It builds on MetaMask's Delegation Framework, which is open source, independently audited, and public. You can read the code and the audit reports in the framework repo, and $MOTION pins the on-chain framework to release tag v1.3.0.

Under the hood (for the technically curious)

$MOTION pins exact versions so an upstream change lands in one place: @metamask/smart-accounts-kit at 1.6.0 (exact, no caret), viem at 2.55.2, and the on-chain Delegation Framework at release tag v1.3.0. The standards involved: EIP-712 is how owners sign the delegation as typed data from their own wallets; ERC-7710 defines redeemDelegations, the interface the operator calls each cycle; ERC-7579 defines the execution modes.

Last updated

Was this helpful?