Fund a balance
$PONCHO

Docs / Reference

API reference

Everything a client or a provider needs to speak Poncho: the 402 quote, the signed note and the header it travels in, how a note is checked, where the protocol describes itself, and every function of the four contracts with its arguments and the errors it can revert with.

The contract sections below are generated from protocol/abi and the contract source, so they change only when the contracts do. Checked against the release of 23 Sep 2026

Overview

Poncho is HTTP 402 with a signature instead of a transaction. A provider answers a paid route with a quote. The agent signs an EIP-712 note for exactly that quote and asks again with the note in one header. The provider checks the note off chain, serves the call, and redeems its notes on Robinhood Chain later, many in one transaction. The vault moves USDG from the payer's balance to the provider and writes a receipt that anyone can read.

Protocol
poncho/1
Network
Robinhood Chain, chain id 4663 (0x1237)
Settlement
USDG, 6 decimals. Every amount in the protocol is USDG atoms: 1000000 is 1 USDG.
Note header
X-Poncho-Note
RPC
https://rpc.mainnet.chain.robinhood.com

Addresses

The four Poncho contracts and the two contracts they rely on. This page and Poncho for agents are the only pages on this site that print them. Check an address on the explorer before you send anything to it.

The payment flow

One paid call, as the parties see it. Only the last two rows touch the chain, and the provider decides when they happen.

  1. Agent ProviderThe request, as the route's own docs describe it. No payment yet.
  2. Provider Agent402 Payment Required with a quote: provider, service, route, amount, nonce and deadline.
  3. AgentChecks the quote against its own ceiling, fills in the payer and itself as the agent, and signs the SpendNote with EIP-712. A signature, not a transaction: no gas and no block to wait for.
  4. Agent ProviderThe same request again, with the note and the signature in the X-Poncho-Note header.
  5. ProviderChecks the note: its fields, its signature, and the payer's balance and the key's cap on chain. Serves the call and banks the note.
  6. Provider Agent200 and the response.
  7. Provider VaultLater, when it chooses: trySettleMany (or settleMany) with the banked notes, up to 128 in one transaction.
  8. VaultTakes each amount from the payer's balance, credits the provider less the fee, and emits Settled, the public receipt of that call.

The 402 quote

A route that wants payment answers 402 with content-type: application/json and this body. Every integer that can pass 253 travels as a decimal string, because a JSON number cannot hold a uint256.

Fields

error "payment_required"
Always "payment_required".
protocol "poncho/1"
Always "poncho/1".
chainId 4663
Always 4663.
vault string
The PonchoVault the note is signed against, 0x hex.
header string, optional
Where the signed note goes on the retry. Default X-Poncho-Note.
docs string, optional
Optional link to the provider documentation.
quote.provider string
Who is paid, and the only address that may redeem the note.
quote.serviceId string, optional
PonchoRegistry service id, decimal. "0" when the route is not listed.
quote.routeId string, optional
PonchoRegistry route id, decimal. "0" when the route is not listed.
quote.amount string
USDG atoms, 6 decimals, decimal string.
quote.nonce string
Any value the provider picks, decimal string. The note hash is what is consumed.
quote.deadline integer
Unix seconds after which the note cannot be redeemed.

The quote leaves out payer and agent on purpose: only the agent knows which balance it spends from. The agent copies every other field into the note unchanged, or the signature will not match what the provider checks.

The spend note

The agent signs a SpendNote with EIP-712 (eth_signTypedData_v4). The vault keys the note's receipt by its full EIP-712 digest, so a note is bound to this chain, this vault, this payer, this agent, this provider and this amount, and it can be redeemed once.

name
Poncho
version
1
chainId
4663
verifyingContract
PonchoVault, listed under Addresses

Type string

SpendNote(address payer,address agent,address provider,uint256 serviceId,uint256 routeId,uint256 amount,uint256 nonce,uint64 deadline)

Typehash

0x63b4fe9ae6466a2a5023863a71a673905241a0740072403cf45824e59209d77f

Fields, in type order

payer address
whose balance is spent
agent address
the key that signs; may equal payer
provider address
who is paid, and the only address that may settle this note
serviceId uint256
registry service, for indexing only
routeId uint256
registry route, for indexing only
amount uint256
USDG atoms (6 dp)
nonce uint256
provider supplied, any value; the note hash is what is consumed
deadline uint64
unix seconds

SettleSkipped reasons

What trySettleMany writes in SettleSkipped(noteHash, payer, reason) when it leaves a note unsettled. Each reason is the check the strict path reverts on.

1 ZERO_AMOUNT
The note is for zero USDG.Strict path: ZeroAmount
2 AMOUNT_TOO_LARGE
That amount is above what the contract can hold.Strict path: AmountTooLarge
3 EXPIRED
That note is past its deadline. Ask the provider for a new quote.Strict path: NoteExpired
4 ALREADY_SETTLED
That note has already been redeemed.Strict path: NoteAlreadySettled
5 BAD_SIGNATURE
The signature does not match the agent key on the note.Strict path: BadSignature
6 NO_GRANT
That key has no grant on this balance.Strict path: NoGrant
7 GRANT_EXPIRED
That agent key has expired. Authorize it again.Strict path: GrantExpired
8 CAP_EXCEEDED
That is over what the key may spend this epoch.Strict path: CapExceeded
9 INSUFFICIENT_BALANCE
The payer balance is too low for that note.Strict path: InsufficientBalance

The payload a wallet signs

Checking a note

A provider checks a note before it serves the call, because nothing is paid until the note settles. Off chain, checkNote in js/chain/settle.js does the part that needs no network: the fields, the deadline, the price and the signature. The rest needs one read of the chain.

When the note is redeemed, the vault runs these checks, in this order, and the first one that fails decides the error:

  1. The vault is not paused. EnforcedPause
  2. The caller is the provider the note names, and that provider is not zero. NotProvider, ZeroAddress
  3. The amount is above zero and fits in 128 bits. ZeroAmount, AmountTooLarge
  4. The deadline has not passed. NoteExpired
  5. The note has never settled, refunded ones included. NoteAlreadySettled
  6. The signature is the agent's: ECDSA for a plain key, ERC-1271 when the agent is a contract. BadSignature
  7. When the agent is not the payer: the payer granted the agent a key, the grant has not expired, and the amount fits in what is left of the key's cap this epoch. NoGrant, GrantExpired, CapExceeded
  8. The payer's balance covers the amount. InsufficientBalance

A payer may withdraw between signing and settlement, and nothing stops it. settleMany then reverts as a whole; trySettleMany skips that note with a SettleSkipped reason and settles the rest. That is why a provider checks the balance and the cap before it serves, counts what it has served and not yet settled against them, and settles often.

Smart account agents. An agent with code signs through ERC-1271, which no off chain check can confirm. verifyNote answers null for those and never pretends. A provider that accepts them hashes the note with hashNote and asks the agent's isValidSignature with one eth_call.

Gate answers

What the provider kit's gate, poncho-gate.mjs on the sell page, answers besides the route's own response. A provider that writes its own gate is free to answer differently; a client should read the status and error first.

Discovery

Poncho describes itself to machines in plain files on this site, so an agent that has never seen it can find the chain, the vault, the note type and the 402 schema without reading a page written for people.

  • GET/.well-known/poncho.jsonThe protocol descriptor: the chain and its RPC, the settlement token, the four contract addresses and the deploy block, the EIP-712 domain and type, the header names, the 402 schema, the categories and where the ABIs live. The addresses are null until the contracts are deployed.
  • GET/protocol/abi/*.jsonThe ABI of each contract, as the compiler wrote it: vault, registry, staking, requests, and the ERC-20 surface.
  • GET/protocol/agentsPoncho written for an agent: the base URLs, the note, the header and the error codes on one page.
  • GET/llms.txtThe map of this site in plain text.
The descriptor, as this site serves it now
Open this to load it.

Site modules

The pages of this site sign and read with plain ES modules that also run in Node 22 with no dependencies. The kits fetch them into a poncho/js/ folder and import them, so a client, a gate and this site can never disagree about the protocol. Each file opens with the full list of what it exports.

  • JS/js/chain/settle.jsThe note: quoteToNote, typedData, hashNote, signNote, checkNote, verifyNote, parse402, quoteBody, encodeNoteHeader, decodeNoteHeader.
  • JS/js/chain/core.jsEvery read and every transaction builder: readService, readGrant, vaultBalanceOf, readReceipts, buildDeposit, buildGrant, buildTrySettleMany, explainRevert and the rest. setTransport(url) points it at any RPC.
  • JS/js/chain/abi.jsThe four ABIs as readable fragments, and the sentence behind every custom error.
  • JS/js/config.jsThe chain, the addresses, the protocol constants and the categories.
  • JS/js/pages/learn/kit/poncho-pay.mjsThe agent client of the quickstart: a fetch that pays a 402 within a ceiling, and a command line around it.
  • JS/js/pages/sell/kit/poncho-gate.mjsThe provider gate of the sell page: quotes, checks, banks, and poncho-settle.mjs redeems.

PonchoVault

Balances, agent keys, spend notes, receipts, provider earnings and the protocol fee.

The custody and settlement half of Poncho. A human deposits USDG once and authorizes an agent key with a cap per epoch and an expiry. The agent signs an EIP-712 SpendNote for a provider's quote; no transaction, no gas, no latency. The provider verifies the note off chain, serves the call, and later redeems banked notes with settle, settleMany or trySettleMany. USDG moves from the payer's balance to the provider's earnings, the protocol keeps a fee, and one Settled event carries everything the site indexes.

61 functions, 18 events, 34 errors in protocol/abi/vault.json.

Writes

Anyone may call these, subject to the checks each one lists.

grantpausable

grant(
  address agent,
  uint128 capPerEpoch,
  uint32 epochLen,
  uint64 expiry
)

Let agent spend up to capPerEpoch USDG atoms of your balance in every window of epochLen seconds, until expiry. Resets what the key has spent and starts a fresh epoch now, so calling it again on a key hands that key a full cap at once: to renew a key, use extend. The windows are on a fixed grid, so across a window boundary a key can spend up to twice the cap within one epoch length. The key signs and never holds funds.

Reverts with BadEpochLength BadExpiry EnforcedPause SelfGrant ZeroAddress ZeroAmount

Selector0xc2079981

extendpausable

extend(address agent, uint64 expiry)

Move an existing grant's expiry, later or earlier, to any time in the future. The cap, the epoch length, the current window and what the key has spent in it are kept, so a renewal never resets the key's spend. A revoked or never made grant reverts NoGrant.

Reverts with BadExpiry EnforcedPause NoGrant

Selector0x59828aed

revoke

revoke(address agent)

Take an agent key's authority away. Never paused: a revoke must always go through.

Selector0x74a8f103

trySettleManypausable

trySettleMany(
  SpendNote[] notes,
  bytes[] sigs
) returns (
  uint256 settledMask,
  uint256 settledAmount
)

Redeem what can be redeemed of a batch. A note that fails a payer side check (its amount, its deadline, already settled, its signature, the agent's grant, cap or expiry, the payer's balance) is skipped with SettleSkipped and nothing is written for it; the rest settle exactly as settleMany would settle them. A note naming another provider, or none, still reverts the whole batch: that is the caller's bug, and skipping it would hide it.

An agent with code is asked through ERC-1271 with the gas that is left, exactly as settle asks it. One that burns all of it can still run the batch out of gas, so a provider that takes notes from smart account agents simulates the batch before it sends it.

Returns

settledMask uint256
Bit i is set when notes[i] settled.
settledAmount uint256
The gross USDG atoms settled, before the fee.

Reverts with BatchTooLarge EmptyBatch EnforcedPause LengthMismatch NotProvider ReentrancyGuardReentrantCall ZeroAddress

Selector0x31fbc2c0

Owner

Only the Poncho owner may call these.

Reads

feeBps

feeBps() view returns (uint16)

The protocol fee on every settlement, in basis points.

Selector0x24a9d853

feeSink

feeSink() view returns (address)

Where sweepFees sends the fees (PonchoStaking after the deploy wiring).

Selector0x4b38474d

tierSource

tierSource() view returns (address)

The contract asked for a provider's fee discount, or zero for no discounts.

Selector0x6738c1b1

feesAccrued

feesAccrued() view returns (uint256)

Fees taken and not yet swept.

Selector0x94db0595

balanceOf

balanceOf(
  address
) view returns (uint256)

Deposited USDG, spendable by the payer and by its live agent keys.

Selector0x70a08231

grantOf

grantOf(
  address,
  address
) view returns (
  uint128 capPerEpoch,
  uint128 spent,
  uint32 epochLen,
  uint64 epochEnds,
  uint64 expiry
)

A payer's grant to one agent. capPerEpoch == 0 && expiry == 0 means no grant; a payer always has an implicit unlimited grant to itself.

Selector0xb98e8226

receiptOf

receiptOf(
  bytes32
) view returns (
  address payer,
  address provider,
  uint128 amount,
  uint128 fee,
  uint64 settledAt,
  bool refunded
)

Every settled note, by its EIP-712 digest.

Selector0x72a41fdd

earningsOf

earningsOf(
  address
) view returns (uint256)

A provider's unclaimed earnings, pulled with withdrawEarnings.

Selector0x8df08bd4

totalSettled

totalSettled() view returns (uint256)

Lifetime aggregates the site reads without walking logs. Gross: totalRefunded and the Refunded events say what came back.

Selector0xeace4c91

totalVolume

totalVolume() view returns (uint256)

Lifetime aggregates the site reads without walking logs. Gross: totalRefunded and the Refunded events say what came back.

Selector0x5f81a57c

totalFees

totalFees() view returns (uint256)

Lifetime aggregates the site reads without walking logs. Gross: totalRefunded and the Refunded events say what came back.

Selector0x13114a9d

totalRefunded

totalRefunded() view returns (uint256)

Lifetime aggregates the site reads without walking logs. Gross: totalRefunded and the Refunded events say what came back.

Selector0xd9082962

refundCount

refundCount() view returns (uint256)

Lifetime aggregates the site reads without walking logs. Gross: totalRefunded and the Refunded events say what came back.

Selector0x0bda4dbf

spentBy

spentBy(address) view returns (uint256)

Lifetime aggregates the site reads without walking logs. Gross: totalRefunded and the Refunded events say what came back.

Selector0x862c4508

earnedBy

earnedBy(address) view returns (uint256)

Lifetime aggregates the site reads without walking logs. Gross: totalRefunded and the Refunded events say what came back.

Selector0x5d215049

grantView

grantView(
  address payer,
  address agent
) view returns (
  uint128 capPerEpoch,
  uint128 spent,
  uint32 epochLen,
  uint64 epochEnds,
  uint64 expiry,
  uint128 available,
  bool live
)

The grant as it stands right now, with the epoch rolled forward in memory: what the key may still spend before the current window ends, and whether it is live at all.

Selector0x28df39e1

hashNote

hashNote(
  SpendNote note
) view returns (bytes32)

The EIP-712 digest of note: the key of its receipt, and what the agent signs.

Selector0x0f6488e6

DOMAIN_SEPARATOR

DOMAIN_SEPARATOR() view returns (bytes32)

The EIP-712 domain separator of this vault.

Selector0x3644e515

feeBpsFor

feeBpsFor(
  address provider
) view returns (uint16)

The fee a provider pays, after the discount its stake earns. A missing, reverting or nonsense tier source means the full fee; the discount can never raise it.

Selector0x2fc1c400

quote

quote(
  address provider,
  uint256 amount
) view returns (
  uint256 fee,
  uint256 net
)

What a settlement of amount would split into for provider, at today's fee.

Selector0x8f79306e

eip712Domain

eip712Domain() view returns (
  bytes1 fields,
  string name,
  string version,
  uint256 chainId,
  address verifyingContract,
  bytes32 salt,
  uint256[] extensions
)

The EIP-5267 description of the EIP-712 domain the vault signs against.

Selector0x84b0196e

owner

owner() view returns (address)

The current owner.

Selector0x8da5cb5b

paused

paused() view returns (bool)

True while the owner has paused the functions that pause.

Selector0x5c975abb

pendingOwner

pendingOwner() view returns (address)

The address a two step ownership transfer is waiting on, or zero.

Selector0xe30c3978

Constants

NOTE_TYPE string
"SpendNote(address payer,address agent,address provider,uint256 serviceId,uint256 routeId,uint256 amount,uint256 nonce,uint64 deadline)"The EIP-712 type of a SpendNote. The site signs against this exact string.
NOTE_TYPEHASH bytes32
keccak256(bytes(NOTE_TYPE))
USDG IERC20
Set at deployThe settlement token, 6 decimals.
REFUND_WINDOW uint64
7 daysHow long after settlement a provider may still refund a note.
MAX_FEE_BPS uint16
500The highest protocol fee the owner can ever set.
MIN_EPOCH uint32
1 hoursThe shortest and longest epoch a grant may use.
MAX_EPOCH uint32
30 daysThe shortest and longest epoch a grant may use.
MAX_SETTLE_BATCH uint256
128The most notes one settleMany or trySettleMany may carry. At most 256, so every note of a batch has its own bit in settledMask.
ZERO_AMOUNT uint8
1Why trySettleMany skipped a note, as SettleSkipped carries it. Each is the payer side check settle reverts with the matching custom error, in the order the checks run. ZeroAmount.
AMOUNT_TOO_LARGE uint8
2AmountTooLarge: above uint128.
EXPIRED uint8
3NoteExpired: past the note's deadline.
ALREADY_SETTLED uint8
4NoteAlreadySettled, refunded ones included.
BAD_SIGNATURE uint8
5BadSignature: not the agent's, ECDSA or ERC-1271.
NO_GRANT uint8
6NoGrant: the payer never authorized the agent.
GRANT_EXPIRED uint8
7GrantExpired.
CAP_EXCEEDED uint8
8CapExceeded: over what is left of the epoch.
INSUFFICIENT_BALANCE uint8
9InsufficientBalance: the payer withdrew or never had it.

Types

struct SpendNote

payer address
whose balance is spent
agent address
the key that signs; may equal payer
provider address
who is paid, and the only address that may settle this note
serviceId uint256
registry service, for indexing only
routeId uint256
registry route, for indexing only
amount uint256
USDG atoms (6 dp)
nonce uint256
provider supplied, any value; the note hash is what is consumed
deadline uint64
unix seconds

Events

Deposited

event Deposited(
  address indexed payer,
  address indexed from,
  uint256 amount,
  uint256 balance
)

Emitted by deposit depositTo

Topic0xf5681f9d0db1b911ac18ee83d515a1cf1051853a9eae418316a2fdf7dea427c5

EIP712DomainChanged

event EIP712DomainChanged()

Emitted by nothing: EIP-5267 declares it, and this domain never changes

Topic0x0a6387c9ea3628b88a633bb4f3b151770f70085117a15f9bf3787cda53f13d31

EarningsWithdrawn

event EarningsWithdrawn(
  address indexed provider,
  uint256 amount,
  uint256 remaining
)

Emitted by withdrawEarnings

Topic0x90dac969af4a4897610ef8f0cd934c54409861eb7bd2205e552f8f2296ee5d3e

Extended

event Extended(
  address indexed payer,
  address indexed agent,
  uint64 expiry
)

A grant's expiry moved; its cap, its window and what it has spent did not.

Emitted by extend

Topic0xd9881e4c2d67eedd1e4db769e2733f160bbd05d51233e32a0b68ef516b1d9708

FeeBpsSet

event FeeBpsSet(uint16 feeBps)

Emitted by setFeeBps the constructor

Topic0x9bcf94806ecd549c5fde16e51a1aa08969f40766e486082ffa0776f594ceeba0

FeeSinkSet

event FeeSinkSet(
  address indexed feeSink
)

Emitted by setFeeSink the constructor

Topic0x93f45e69cdabde5c8296469e04ee6765b806aa9c3ef27883e43d1c3d227c4f22

FeesSwept

event FeesSwept(
  address indexed caller,
  address indexed sink,
  uint256 amount,
  bool synced
)

Emitted by sweepFees

Topic0x03cd827e355881bd0c492bdf99e799ba5e7a42854acaf42b7cadbb4a76239af4

Granted

event Granted(
  address indexed payer,
  address indexed agent,
  uint128 capPerEpoch,
  uint32 epochLen,
  uint64 epochEnds,
  uint64 expiry
)

Emitted by grant

Topic0x3bbc2b967e89f0a4b9bf541a8822e638dab942fe1f5b6f323feeb19995f3ae08

OwnershipTransferStarted

event OwnershipTransferStarted(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by transferOwnership

Topic0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700

OwnershipTransferred

event OwnershipTransferred(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by acceptOwnership the constructor

Topic0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0

Paused

event Paused(address account)

Emitted by pause

Topic0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258

Refunded

event Refunded(
  bytes32 indexed noteHash,
  address indexed payer,
  address indexed provider,
  uint256 amount,
  uint256 fee
)

Emitted by refund

Topic0x0fa33579c567b96c5c4a3a1abb3e58cdbe61e07b29718a2c9b7cd67cb89150ae

Revoked

event Revoked(
  address indexed payer,
  address indexed agent
)

Emitted by revoke

Topic0xc336937d058cc0fc95b7491390ffcf122da8cf400512d9714a76f644aa8955b7

SettleSkipped

event SettleSkipped(
  bytes32 indexed noteHash,
  address indexed payer,
  uint8 reason
)

trySettleMany left a note unsettled and wrote nothing for it. reason is one of the nine codes above. The same note may still settle later, once whatever failed is fixed, unless it was ALREADY_SETTLED or its deadline has passed.

Emitted by trySettleMany

Topic0x264d063feb7fd433446769c0f578ff57cefe59dd2d95f1de221c342ce2c19794

Settled

event Settled(
  bytes32 indexed noteHash,
  address indexed payer,
  address indexed provider,
  address agent,
  uint256 serviceId,
  uint256 routeId,
  uint256 amount,
  uint256 fee
)

Emitted by settle settleMany trySettleMany

Topic0x1101c9b8a44a93df62fce97647d32ffdd8c291af8746cc70a922f6771f719ce0

TierSourceSet

event TierSourceSet(
  address indexed tierSource
)

Emitted by setTierSource

Topic0x8c952f3501d066d94cd9a1c4f036c3f5a59aac073df5624a31ee7199fcebd3ec

Unpaused

event Unpaused(address account)

Emitted by unpause

Topic0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa

Withdrawn

event Withdrawn(
  address indexed payer,
  uint256 amount,
  uint256 balance
)

Emitted by withdraw

Topic0x92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6

Errors

The sentence beside each error is the one this site shows when a transaction would revert with it.

AmountTooLarge(uint256 amount)0x08083b2a
That amount is above what the contract can hold.From settle, settleMany
BadEpochLength(uint32 epochLen, uint32 min, uint32 max)0x5c1f5e40
The epoch has to be between one hour and thirty days.From grant
BadExpiry(uint64 expiry)0x115d3d42
Set an expiry in the future.From extend, grant
BadSignature(bytes32 noteHash, address agent)0xe49c6ba0
The signature does not match the agent key on the note.From settle, settleMany
BatchTooLarge(uint256 count, uint256 max)0xbb1cb70b
That is more rows than one call may carry.From settleMany, trySettleMany
CapExceeded(uint256 wanted, uint128 spent, uint128 capPerEpoch)0x917462df
That is over what the key may spend this epoch.From settle, settleMany
EmptyBatch()0xc2e5347d
Send at least one note.From settleMany, trySettleMany
EnforcedPause()0xd93c0665
That is paused by the Poncho owner right now.From deposit, depositTo, extend, grant, pause, settle, settleMany, trySettleMany
ExpectedPause()0x8dfc202b
That only runs while the contract is paused.From unpause
FeeSinkNotSet()0xe0c77412
The fee sink is not set yet.From sweepFees
FeeTooHigh(uint16 feeBps, uint16 max)0x3c057d7b
That fee is above the hard cap of 5%.From setFeeBps
GrantExpired(uint64 expiry)0x06bbb9b1
That agent key has expired. Authorize it again.From settle, settleMany
InsufficientBalance(address payer, uint256 balance, uint256 amount)0xdb42144d
The payer balance is too low for that note.From settle, settleMany, withdraw
InsufficientEarnings(address provider, uint256 earnings, uint256 amount)0xb9fc9860
That is more than the earnings you can pull.From refund, withdrawEarnings
InvalidShortString()0xb3512b0c
That text is too long for the contract.Inherited, or raised by a library the contract uses.
LengthMismatch(uint256 notes, uint256 signatures)0xab8b67c6
The batch has a different number of notes and signatures.From settleMany, trySettleMany
NoGrant(address payer, address agent)0x6e67cd62
That key has no grant on this balance.From extend, settle, settleMany
NotProvider(address provider, address caller)0x344b0904
Only the provider a note names may redeem or refund it.From refund, settle, settleMany, trySettleMany
NoteAlreadyRefunded(bytes32 noteHash)0xe68b20d5
That note has already been given back.From refund
NoteAlreadySettled(bytes32 noteHash)0x03a5b4e0
That note has already been redeemed.From settle, settleMany
NoteExpired(uint64 deadline)0x70495aa6
That note is past its deadline. Ask the provider for a new quote.From settle, settleMany
NoteNotSettled(bytes32 noteHash)0xa358395f
That note was never redeemed, so there is nothing to give back.From refund
NothingToSweep()0x351261fc
There are no fees to sweep.From sweepFees
OwnableInvalidOwner(address owner)0x1e4fbdf7
That owner address is not allowed.Inherited, or raised by a library the contract uses.
OwnableUnauthorizedAccount(address account)0x118cdaa7
Only the Poncho owner can do that.From acceptOwnership, pause, renounceOwnership, setFeeBps, setFeeSink, setTierSource, transferOwnership, unpause
ReentrancyGuardReentrantCall()0x3ee5aeb5
That call is not allowed from here.From deposit, depositTo, refund, settle, settleMany, sweepFees, trySettleMany, withdraw, withdrawEarnings
RefundWindowClosed(bytes32 noteHash, uint64 settledAt)0x25354f59
The seven day refund window on that note has closed.From refund
RenounceDisabled()0x89051165
Ownership cannot be renounced.From renounceOwnership
SafeERC20FailedOperation(address token)0x5274afe7
The token transfer failed.From deposit, depositTo, sweepFees, withdraw, withdrawEarnings
SelfGrant()0x0b67ee90
A payer already spends its own balance. Grant to another key.From grant
StringTooLong(string str)0x305a27a9
That text is too long for the contract.Inherited, or raised by a library the contract uses.
TransferShortfall(uint256 expected, uint256 received)0xaea7b7c0
The USDG transfer came up short.From deposit, depositTo
ZeroAddress()0xd92e233d
An address is missing.From depositTo, grant, setFeeSink, settle, settleMany, trySettleMany
ZeroAmount()0x1f2a2005
Enter an amount above zero.From deposit, depositTo, grant, settle, settleMany, withdraw, withdrawEarnings

PonchoRegistry

Services and their routes, with a price in USDG atoms on every route.

What an agent can buy. A provider lists a service once, gives it routes with a price in USDG atoms, and keeps them. Listing is permissionless: the owner can set a listing fee in wei (zero at launch, at most 0.01 ether) and can flag a service so the site hides it, but it can never take a service away, change its price, or stop it being settled against.

41 functions, 13 events, 21 errors in protocol/abi/registry.json.

Writes

Anyone may call these, subject to the checks each one lists.

setPaused

setPaused(uint256 id, bool paused)

Stop offering a service without delisting it. The site greys it out; the chain keeps settling notes already signed against it.

Reverts with NoService NotServiceOwner

Selector0xdaff97b5

Owner

Only the Poncho owner may call these.

Reads

treasury

treasury() view returns (address)

Where the listing fee goes.

Selector0x61d027b3

listingFeeWei

listingFeeWei() view returns (uint256)

The listing fee in wei, zero at launch.

Selector0x2906a0a1

serviceCount

serviceCount() view returns (uint256)

How many services exist. Ids run 1 to serviceCount.

Selector0x06237526

routeCount

routeCount() view returns (uint256)

How many routes exist. Ids run 1 to routeCount.

Selector0xbf539cb4

idBySlug

idBySlug(string) view returns (uint256)

The service that owns a slug, or zero.

Selector0x25192169

getService

getService(
  uint256 id
) view returns (Service)

One service. Reverts NoService for an id that was never registered.

Reverts with NoService

Selector0xef0e239b

serviceMeta

serviceMeta(
  uint256 id
) view returns (
  address owner_,
  uint64 createdAt,
  uint8 category,
  bool paused,
  bool flagged
)

A service's header without its five strings: what another contract needs and what a list view can afford to read.

Reverts with NoService

Selector0xb2dd2226

getRoute

getRoute(
  uint256 id
) view returns (Route)

One route. Reverts NoRoute for an id that was never added.

Reverts with NoRoute

Selector0xfa66358a

routeIdsOf

routeIdsOf(
  uint256 serviceId
) view returns (uint256[])

Every route id of a service, in the order they were added.

Selector0x59b23c41

servicesOf

servicesOf(
  address owner_
) view returns (uint256[])

Every service id an address owns.

Selector0x5582c6b2

getServices

getServices(
  uint256 from,
  uint256 count
) view returns (
  uint256[] ids,
  Service[] list
)

A page of services, ids ascending from from (1 based), at most count and at most MAX_BATCH. Short when the page runs past the end, empty when it starts past it.

Reverts with BadRange BatchTooLarge

Selector0xb6dc429f

getRoutes

getRoutes(
  uint256[] ids
) view returns (Route[] list)

Many routes in one read, in the order asked. An id that does not exist reverts, so the site always knows what it got.

Reverts with BatchTooLarge NoRoute

Selector0xadff7c5c

owner

owner() view returns (address)

The current owner.

Selector0x8da5cb5b

pendingOwner

pendingOwner() view returns (address)

The address a two step ownership transfer is waiting on, or zero.

Selector0xe30c3978

Constants

CATEGORY_COUNT uint8
9How many uint8 categories js/config.js mirrors: Search, Data, Creative, Developer, Finance, Commerce, Social, Compute, Other.
MIN_SLUG_BYTES uint256
3The fewest bytes a slug may take.
MAX_SLUG_BYTES uint256
32The most bytes a slug may take.
MAX_NAME_BYTES uint256
48The most bytes a name may take.
MAX_SUMMARY_BYTES uint256
240The most bytes a summary may take.
MAX_ENDPOINT_BYTES uint256
200The most bytes a endpoint may take.
MAX_DOCS_BYTES uint256
200The most bytes a docs may take.
MAX_METHOD_BYTES uint256
8The most bytes a method may take.
MAX_PATH_BYTES uint256
120The most bytes a path may take.
MAX_ROUTE_SUMMARY_BYTES uint256
160The most bytes a route summary may take.
MAX_ROUTES_PER_SERVICE uint256
64The most routes one service may hold, so routeIdsOf and getRoutes stay bounded.
MAX_BATCH uint256
100The most rows one batch view may return.
MAX_LISTING_FEE_WEI uint256
0.01 etherThe highest listing fee the owner can ever set.

Types

struct Route

serviceId uint256
No note in the source.
price uint128
No note in the source.
active bool
No note in the source.
method string
No note in the source.
path string
No note in the source.
summary string
No note in the source.

struct Service

owner address
No note in the source.
createdAt uint64
No note in the source.
category uint8
No note in the source.
paused bool
No note in the source.
flagged bool
No note in the source.
slug string
No note in the source.
name string
No note in the source.
summary string
No note in the source.
endpoint string
No note in the source.
docs string
No note in the source.

Events

ListingFeeSet

event ListingFeeSet(uint256 feeWei)

Emitted by setListingFeeWei the constructor

Topic0x1e824c7e20e36968ef401e2236f2bf4779d7c0792b029593bb95c98f3567ca55

OwnershipTransferStarted

event OwnershipTransferStarted(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by transferOwnership

Topic0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700

OwnershipTransferred

event OwnershipTransferred(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by acceptOwnership the constructor

Topic0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0

RouteActiveSet

event RouteActiveSet(
  uint256 indexed routeId,
  uint256 indexed serviceId,
  bool active
)

Emitted by setRouteActive

Topic0x924dc6915562b57c96d633c6d2b987cf54f95260c8e8f76a4ed2739b9a095a4a

RouteAdded

event RouteAdded(
  uint256 indexed routeId,
  uint256 indexed serviceId,
  address indexed owner,
  string method,
  string path,
  string summary,
  uint128 price
)

Emitted by addRoute

Topic0x316f7d571cfc832e54ecf59c445cf46be08607a4a5f8826c1c360009fd879efb

RoutePriceSet

event RoutePriceSet(
  uint256 indexed routeId,
  uint256 indexed serviceId,
  uint128 price
)

Emitted by setRoutePrice

Topic0xe87409bb6c5b92051278f7f63ea4705100f1e99ee4666653709a2ab3b2c3991c

RouteUpdated

event RouteUpdated(
  uint256 indexed routeId,
  uint256 indexed serviceId,
  address indexed owner,
  string method,
  string path,
  string summary,
  uint128 price,
  bool active
)

Emitted by setRoute

Topic0x4d0a95f0c0989fc3b848435105af97c62392939f9379b6e99b6bcb564590ed5a

ServiceFlagged

event ServiceFlagged(
  uint256 indexed id,
  bool flagged
)

Emitted by setFlagged

Topic0x374de4afcfab68b6220dd47c62089a7753e59554522d478e0e2e8ec8f53dfd98

ServicePausedSet

event ServicePausedSet(
  uint256 indexed id,
  bool paused
)

Emitted by setPaused

Topic0xf7aa5ff1ad744f35614f7eb111b4428510ee1774f49f94ae74b7d1e49df59d64

ServiceRegistered

event ServiceRegistered(
  uint256 indexed id,
  address indexed owner,
  uint8 indexed category,
  string slug,
  uint64 createdAt,
  uint256 feeWei
)

A service is born. The content it is born with arrives in the ServiceUpdated that register emits straight after, so one filter on ServiceUpdated always gives an indexer the current name, summary, endpoint, docs and category of every service.

Emitted by register

Topic0x0b9b624cc4097dffb414e59b81f8b1788c3ecf99c4cfb49ce2ab3d9a2384e34e

ServiceTransferred

event ServiceTransferred(
  uint256 indexed id,
  address indexed from,
  address indexed to
)

Emitted by transferService

Topic0xed6e902c86d1dfb307e56a04bcbc9a1e0ca0a54a068fbf876245bb328dce3647

ServiceUpdated

event ServiceUpdated(
  uint256 indexed id,
  address indexed owner,
  uint8 indexed category,
  string name,
  string summary,
  string endpoint,
  string docs
)

Emitted by register updateService

Topic0xaff23e58adc5ee6529127ac688227aec4e1c1fb8065e70f3e870dfb540b7b256

TreasurySet

event TreasurySet(
  address indexed treasury
)

Emitted by setTreasury the constructor

Topic0x3c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f

Errors

The sentence beside each error is the one this site shows when a transaction would revert with it.

BadCategory(uint8 category)0x8395f495
Pick one of the nine categories.From register, updateService
BadEndpoint(string endpoint)0x386788fe
An endpoint has to start with https://.From register, updateService
BadListingFee(uint256 sent, uint256 expected)0xfa4313ce
Send exactly the listing fee the registry asks for.From register
BadMethod(string method)0x23503cb3
A method is 1 to 8 uppercase letters, such as GET or POST.From addRoute, setRoute
BadPath(string path)0x773eb90b
A path has to start with a slash.From addRoute, setRoute
BadRange(uint256 from)0xc7714240
Ask for a page that starts at 1 or later.From getServices
BadSlug(string slug)0x47f48a93
A slug is 3 to 32 characters of a to z, 0 to 9 and dashes, and cannot start or end with one.From register
BatchTooLarge(uint256 count, uint256 max)0xbb1cb70b
That is more rows than one call may carry.From getRoutes, getServices
Empty(string field)0xa47fea01
One of the required fields is empty.From register, updateService
ListingFeeTooHigh(uint256 feeWei, uint256 max)0xc47cea55
That listing fee is above the hard cap.From setListingFeeWei
NoRoute(uint256 id)0xd02fef66
That route does not exist.From getRoute, getRoutes, setRoute, setRouteActive, setRoutePrice
NoService(uint256 id)0xc5bfa00f
That service does not exist.From addRoute, getService, serviceMeta, setFlagged, setPaused, transferService, updateService
NotServiceOwner(uint256 id, address owner, address caller)0xe8340ac1
Only the wallet that owns the service can do that.From addRoute, setPaused, setRoute, setRouteActive, setRoutePrice, transferService, updateService
OwnableInvalidOwner(address owner)0x1e4fbdf7
That owner address is not allowed.Inherited, or raised by a library the contract uses.
OwnableUnauthorizedAccount(address account)0x118cdaa7
Only the Poncho owner can do that.From acceptOwnership, renounceOwnership, setFlagged, setListingFeeWei, setTreasury, transferOwnership
RenounceDisabled()0x89051165
Ownership cannot be renounced.From renounceOwnership
SlugTaken(string slug, uint256 id)0x920b4d21
That slug is already taken. Pick another one.From register
TooLong(string field, uint256 length, uint256 max)0x6d3b0993
One of the fields is longer than the contract allows.From addRoute, register, setRoute, updateService
TooManyRoutes(uint256 serviceId, uint256 max)0x721a7edd
A service carries at most 64 routes.From addRoute
TreasuryTransferFailed(address treasury, uint256 amount)0xa3c0499c
The treasury refused the listing fee.From register
ZeroAddress()0xd92e233d
An address is missing.From setTreasury, transferService

PonchoStaking

$PONCHO stake, the USDG fee share and the provider fee tiers.

The fee sink of PonchoVault and PonchoRequests. Fees arrive as USDG; sync() takes in whatever has arrived since the last call and streams it to the stakers, by stake, over STREAM_PERIOD. Stakers claim USDG. A provider's stake also earns it a discount on the vault's fee, by tier, once that stake has warmed up for TIER_WARMUP. $PONCHO launches on ponsfamily.com after this contract does, so the stake token is set once, later, by the owner. Until then stake reverts TokenNotSet, discountBpsOf answers 0 and the vault charges the full fee. Fees that arrive before anyone stakes wait in pending: the stream only runs while something is staked, so they start to flow on the first stake. Nothing here can be faked in the meantime: every number the coin page shows is read straight out of this contract.

38 functions, 10 events, 18 errors in protocol/abi/staking.json.

Writes

Anyone may call these, subject to the checks each one lists.

sync

sync()

Take in the USDG that has arrived since the last call and stream it to the stakers over STREAM_PERIOD. Called by PonchoVault.sweepFees() and PonchoRequests.sweepFees(); anyone may call it.

Reverts with ReentrancyGuardReentrantCall

Selector0xfff6cae9

Owner

Only the Poncho owner may call these.

setTiersowner

setTiers(
  uint128[4] thresholds,
  uint16[4] discounts
)

Set the four tier thresholds (whole $PONCHO) and discounts. The first threshold is always 0, thresholds rise, discounts never fall, and none may pass MAX_DISCOUNT_BPS.

Reverts with BadTiers DiscountTooHigh OwnableUnauthorizedAccount

Selector0x3a06c2e8

Reads

token

token() view returns (address)

$PONCHO, once the owner has set it. Zero until then.

Selector0xfc0c546a

tokenUnit

tokenUnit() view returns (uint256)

10 ** decimals of the stake token, zero until the token is set.

Selector0xe93c980d

totalStaked

totalStaked() view returns (uint256)

The stake, in stake token atoms.

Selector0x817b1cd2

accPerShare

accPerShare() view returns (uint256)

USDG per stake atom, scaled by ACC_SCALE.

Selector0xd2890a01

pending

pending() view returns (uint256)

USDG taken in and not yet released to the stakers: the stream still to flow.

Selector0xe20ccec3

accounted

accounted() view returns (uint256)

The USDG this contract has accounted for: pending plus every unclaimed reward.

Selector0x19f8dcf1

streamEnds

streamEnds() view returns (uint64)

When pending will have been released in full, if something stays staked. The clock stops while nothing is staked.

Selector0x9dbb4705

lastRelease

lastRelease() view returns (uint64)

When the stream last released into accPerShare.

Selector0x180b2607

stakeOf

stakeOf(address) view returns (uint256)

What an account has staked.

Selector0x42623360

rewardDebt

rewardDebt(
  address
) view returns (uint256)

stakeOf * accPerShare / ACC_SCALE when the account was last settled: rounded up when a stake or an unstake takes it, rounded down when a settlement moves it forward.

Selector0x5873eb9b

rewards

rewards(address) view returns (uint256)

USDG settled to an account and not yet claimed. earned is the live figure.

Selector0x0700037d

freshStakeOf

freshStakeOf(
  address
) view returns (uint256)

The part of stakeOf still warming up for the fee tier, and the amount weighted time it started. Once freshSince + TIER_WARMUP has passed all of it counts.

Selector0x41cd71b5

freshSince

freshSince(
  address
) view returns (uint64)

The part of stakeOf still warming up for the fee tier, and the amount weighted time it started. Once freshSince + TIER_WARMUP has passed all of it counts.

Selector0x71ea9e94

earned

earned(
  address account
) view returns (uint256)

What an account could claim right now.

Selector0x008cc262

discountBpsOf

discountBpsOf(
  address account
) view returns (uint16)

The fee discount in basis points that account's warmed up stake earns. Zero until the stake token is set, so the vault charges the full fee before $PONCHO exists.

Selector0xfe9cc2be

tierStakeOf

tierStakeOf(
  address account
) view returns (uint256)

The part of an account's stake that counts toward its fee tier: all of it, less whatever is still inside its TIER_WARMUP.

Selector0xf3ebdd3c

tierOf

tierOf(
  address account
) view returns (uint8)

Which tier an account is in, 0 to 3.

Selector0xc8f74bb8

tiers

tiers() view returns (
  uint128[4] thresholds,
  uint16[4] discounts
)

The four thresholds in whole $PONCHO and the four discounts in basis points, for the coin page to render from the chain.

Selector0x4a95d9d5

owner

owner() view returns (address)

The current owner.

Selector0x8da5cb5b

paused

paused() view returns (bool)

True while the owner has paused the functions that pause.

Selector0x5c975abb

pendingOwner

pendingOwner() view returns (address)

The address a two step ownership transfer is waiting on, or zero.

Selector0xe30c3978

Constants

ACC_SCALE uint256
1e36accPerShare is USDG atoms per stake atom times this. It is 1e36, not the 1e18 of a textbook accumulator, because the reward has 6 decimals and the stake is expected to have 18: at 1e18 a sweep of a few USDG over a million staked tokens rounds to nothing and the fee share is silently lost. Every product goes through Math.mulDiv, so the 512 bit intermediate cannot overflow whatever the two decimals turn out to be.
MAX_DISCOUNT_BPS uint16
5000The highest discount a tier may give: 50% off the vault fee.
TIER_COUNT uint256
4How many tiers there are.
STREAM_PERIOD uint64
7 daysHow long a fresh arrival of USDG takes to reach the stakers in full.
TIER_WARMUP uint64
7 daysHow long new stake waits before it counts toward a fee tier.
USDG IERC20
Set at deployThe reward token, 6 decimals on Robinhood Chain.

Events

Claimed

event Claimed(
  address indexed account,
  uint256 amount
)

Emitted by claim

Topic0xd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a

OwnershipTransferStarted

event OwnershipTransferStarted(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by transferOwnership

Topic0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700

OwnershipTransferred

event OwnershipTransferred(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by acceptOwnership the constructor

Topic0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0

Paused

event Paused(address account)

Emitted by pause

Topic0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258

Staked

event Staked(
  address indexed account,
  uint256 amount,
  uint256 stake,
  uint256 totalStaked
)

Emitted by stake

Topic0xb4caaf29adda3eefee3ad552a8e85058589bf834c7466cae4ee58787f70589ed

Synced

event Synced(
  address indexed caller,
  uint256 amount,
  uint256 accPerShare,
  uint256 pending
)

Emitted by sync

Topic0x7a39bcd5583b528fead25426b0960f47def7fdb070b11ad5725e20fb3922b40a

TiersSet

event TiersSet(
  uint128[4] thresholds,
  uint16[4] discounts
)

Emitted by setTiers the constructor

Topic0x8c61b4e2d5ac1b2a3313409693a4338e415e136f3e649c0f8d046223a59f71a4

TokenSet

event TokenSet(
  address indexed token,
  uint8 decimals,
  uint256 tokenUnit
)

Emitted by setToken

Topic0x39a6c0a9d74278eea3b3d87951e703e46c08473feb25e5a62832af87eb0f0436

Unpaused

event Unpaused(address account)

Emitted by unpause

Topic0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa

Unstaked

event Unstaked(
  address indexed account,
  uint256 amount,
  uint256 stake,
  uint256 totalStaked
)

Emitted by unstake

Topic0x204fccf0d92ed8d48f204adb39b2e81e92bad0dedb93f5716ca9478cfb57de00

Errors

The sentence beside each error is the one this site shows when a transaction would revert with it.

BadTiers()0x40403517
Tier thresholds have to rise and discounts may never fall.From setTiers
BadToken(address token)0x732d20af
That token cannot be staked here.From setToken
BadTokenDecimals(uint8 decimals)0x930c6f13
That token has more decimals than the tiers can hold.From setToken
DiscountTooHigh(uint16 discount, uint16 max)0x5e8d968d
A tier discount cannot pass 50%.From setTiers
EnforcedPause()0xd93c0665
That is paused by the Poncho owner right now.From pause, stake
ExpectedPause()0x8dfc202b
That only runs while the contract is paused.From unpause
InsufficientStake(address account, uint256 stake, uint256 amount)0x936d426d
That is more than you have staked.From unstake
NothingToClaim()0x969bf728
There is nothing to claim yet.From claim
OwnableInvalidOwner(address owner)0x1e4fbdf7
That owner address is not allowed.Inherited, or raised by a library the contract uses.
OwnableUnauthorizedAccount(address account)0x118cdaa7
Only the Poncho owner can do that.From acceptOwnership, pause, renounceOwnership, setTiers, setToken, transferOwnership, unpause
ReentrancyGuardReentrantCall()0x3ee5aeb5
That call is not allowed from here.From claim, stake, sync, unstake
RenounceDisabled()0x89051165
Ownership cannot be renounced.From renounceOwnership
SafeERC20FailedOperation(address token)0x5274afe7
The token transfer failed.From claim, stake, unstake
TokenAlreadySet(address token)0x7e16511f
The stake token is already set.From setToken
TokenNotSet()0x4b62f013
Staking opens when $PONCHO launches.From stake, unstake
TransferShortfall(uint256 expected, uint256 received)0xaea7b7c0
The USDG transfer came up short.From stake
ZeroAddress()0xd92e233d
An address is missing.From setToken
ZeroAmount()0x1f2a2005
Enter an amount above zero.From stake, unstake

PonchoRequests

The demand board: bounties in USDG escrow, proposals and awards.

The other half of the marketplace. An agent that needs a capability nobody has listed yet posts it with a USDG bounty held in escrow. Anyone can add to the bounty, so the board is a demand signal and not just one buyer's wish. A provider proposes one of its registry services; the requester awards, and the service owner pulls the bounty minus the protocol fee. Once the deadline passes with nothing awarded, anyone may close the request, and then the requester and every backer each take back exactly what they put in.

46 functions, 16 events, 34 errors in protocol/abi/requests.json.

Writes

Anyone may call these, subject to the checks each one lists.

close

close(uint256 id)

Close an open request whose deadline has passed with nothing awarded. Anyone may, and it moves no USDG, so nothing any one address does (a lost key, an absent requester, a frozen account) can keep a request open. Every backer, the requester included, is then refunded by reclaimFor. Never paused.

Reverts with DeadlineNotReached NoRequest NotOpen ReentrancyGuardReentrantCall

Selector0x0aebeb4e

Owner

Only the Poncho owner may call these.

Reads

feeBps

feeBps() view returns (uint16)

The protocol fee taken out of an award, in basis points.

Selector0x24a9d853

feeSink

feeSink() view returns (address)

Where sweepFees sends the fees (PonchoStaking after the deploy wiring).

Selector0x4b38474d

feesAccrued

feesAccrued() view returns (uint256)

Fees taken and not yet swept.

Selector0x94db0595

requestCount

requestCount() view returns (uint256)

How many requests exist. Ids run 1 to requestCount.

Selector0x5badbe4c

backedBy

backedBy(
  uint256,
  address
) view returns (uint128)

What an address put into a request and has not been paid back: refundable once the request closes unawarded.

Selector0x2bab2a7e

proposedBy

proposedBy(
  uint256,
  uint256
) view returns (bool)

Whether a service has a live proposal on a request: set by propose, cleared by dismiss.

Selector0x73f73870

dismissedBy

dismissedBy(
  uint256,
  uint256
) view returns (bool)

Whether the requester dismissed a service's proposal. A dismissed service cannot propose on that request again.

Selector0x66f8fbfa

hasProposed

hasProposed(
  uint256,
  address
) view returns (bool)

Whether an address has proposed on a request. One proposal per address per request, dismissed or not, so one address cannot fill the proposal slots with many services.

Selector0xc96f52c0

earningsOf

earningsOf(
  address
) view returns (uint256)

An awarded service owner's unclaimed bounty, pulled with withdrawEarnings.

Selector0x8df08bd4

totalAwarded

totalAwarded() view returns (uint256)

Lifetime USDG awarded, gross, and what is in escrow right now.

Selector0x10f009ff

totalEscrowed

totalEscrowed() view returns (uint256)

Lifetime USDG awarded, gross, and what is in escrow right now.

Selector0xf9168231

getRequest

getRequest(
  uint256 id
) view returns (Request)

One request. Reverts NoRequest for an id that was never posted.

Reverts with NoRequest

Selector0xc58343ef

getRequests

getRequests(
  uint256 from,
  uint256 count
) view returns (
  uint256[] ids,
  Request[] list
)

A page of requests, ids ascending from from (1 based), at most count and at most MAX_BATCH. Short when the page runs past the end, empty when it starts past it.

Reverts with BadRange BatchTooLarge

Selector0x0750ae3f

proposalsOf

proposalsOf(
  uint256 id
) view returns (uint256[])

The service ids that proposed on a request, in the order they proposed.

Selector0xcf93454c

backersOf

backersOf(
  uint256 id
) view returns (
  address[] backers,
  uint128[] amounts
)

Everyone who put USDG into a request and how much of it is still theirs. The requester is the first entry. Request.bounty keeps the total that was raised whatever happens to it; these amounts go to zero as a closed request is refunded, so what is left here is what still has to be paid back.

Selector0xa30cb728

owner

owner() view returns (address)

The current owner.

Selector0x8da5cb5b

paused

paused() view returns (bool)

True while the owner has paused the functions that pause.

Selector0x5c975abb

pendingOwner

pendingOwner() view returns (address)

The address a two step ownership transfer is waiting on, or zero.

Selector0xe30c3978

Constants

USDG IERC20
Set at deployThe settlement token, 6 decimals.
REGISTRY PonchoRegistry
Set at deployThe registry a proposal's service must come from.
MIN_BOUNTY uint128
1_000_000The smallest bounty, and the smallest top up: 1 USDG.
MIN_DURATION uint64
1 daysHow far out a deadline must be.
MAX_DURATION uint64
365 daysHow far out a deadline must be.
MAX_TITLE_BYTES uint256
80How far out a deadline must be.
MAX_DETAIL_BYTES uint256
600How far out a deadline must be.
MAX_PROPOSALS uint256
64The most proposals one request may take, so proposalsOf stays bounded.
MAX_BACKERS uint256
128The most backers one request may take, so backersOf stays bounded.
MAX_BATCH uint256
50The most rows one batch view may return.
MAX_FEE_BPS uint16
500The highest protocol fee the owner can ever set.

Types

struct Request

requester address
No note in the source.
bounty uint128
No note in the source.
deadline uint64
No note in the source.
createdAt uint64
No note in the source.
status Status
No note in the source.
awardedService uint256
No note in the source.
awardedTo address
No note in the source.
title string
No note in the source.
detail string
No note in the source.

enum Status (uint8)

0
Open
1
Awarded
2
Reclaimed

Events

Awarded

event Awarded(
  uint256 indexed id,
  uint256 indexed serviceId,
  address indexed to,
  uint128 bounty,
  uint128 fee
)

Emitted by award

Topic0xd1f61764a5b92bf1f50ac112ca95ca80c27cda9708d9c42e274aa3e995652828

BackerRefunded

event BackerRefunded(
  uint256 indexed id,
  address indexed backer,
  uint128 amount
)

Emitted by reclaimFor

Topic0x37f3d97e938876b1d2675b5f7f22e6ededc922a5b58bd37e8d4838afbafba814

Closed

event Closed(
  uint256 indexed id,
  address indexed caller
)

A request moved to Reclaimed: closed after its deadline with nothing awarded. Every backer, the requester included, is refunded afterwards by its own call.

Emitted by close reclaim

Topic0xc3b744b0ebdbd13b13fb44c794a77b6d5dd52e121e2640b35db2b7265ddcdcba

Dismissed

event Dismissed(
  uint256 indexed id,
  uint256 indexed serviceId
)

Emitted by dismiss

Topic0xbe8c358e7d292343633f192e8a7b930d6a63e21e64060a0a8610dccfc4d94f61

EarningsWithdrawn

event EarningsWithdrawn(
  address indexed account,
  uint256 amount,
  uint256 remaining
)

Emitted by withdrawEarnings

Topic0x90dac969af4a4897610ef8f0cd934c54409861eb7bd2205e552f8f2296ee5d3e

FeeBpsSet

event FeeBpsSet(uint16 feeBps)

Emitted by setFeeBps the constructor

Topic0x9bcf94806ecd549c5fde16e51a1aa08969f40766e486082ffa0776f594ceeba0

FeeSinkSet

event FeeSinkSet(
  address indexed feeSink
)

Emitted by setFeeSink the constructor

Topic0x93f45e69cdabde5c8296469e04ee6765b806aa9c3ef27883e43d1c3d227c4f22

FeesSwept

event FeesSwept(
  address indexed caller,
  address indexed sink,
  uint256 amount,
  bool synced
)

Emitted by sweepFees

Topic0x03cd827e355881bd0c492bdf99e799ba5e7a42854acaf42b7cadbb4a76239af4

OwnershipTransferStarted

event OwnershipTransferStarted(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by transferOwnership

Topic0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700

OwnershipTransferred

event OwnershipTransferred(
  address indexed previousOwner,
  address indexed newOwner
)

Emitted by acceptOwnership the constructor

Topic0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0

Paused

event Paused(address account)

Emitted by pause

Topic0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258

Posted

event Posted(
  uint256 indexed id,
  address indexed requester,
  uint128 bounty,
  uint64 deadline,
  string title,
  string detail
)

Emitted by post

Topic0x2ca950b8cebc58036b82bc202726fbd240ab2fc4ca58c75e65097b01afaa7037

Proposed

event Proposed(
  uint256 indexed id,
  uint256 indexed serviceId,
  address indexed proposer
)

Emitted by propose

Topic0x24b1a087ad3112ce607caf511a625cf8c636c3a16d1d8cbe5b93cb97d95b4a24

Reclaimed

event Reclaimed(
  uint256 indexed id,
  address indexed requester,
  uint128 amount
)

Emitted by reclaim

Topic0xa54c7773ae2325032fb9bd8c4586f11163e13defb6620149dd0b05476ec30f65

ToppedUp

event ToppedUp(
  uint256 indexed id,
  address indexed backer,
  uint128 amount,
  uint128 bounty
)

Emitted by topUp

Topic0x241ee590c037debd05a2aa39b4390f9862c1cbd781ebbb79354a447ed74207a9

Unpaused

event Unpaused(address account)

Emitted by unpause

Topic0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa

Errors

The sentence beside each error is the one this site shows when a transaction would revert with it.

AlreadyProposed(uint256 id, uint256 serviceId)0x44f95243
That service has already proposed on this request.From propose
AlreadyProposedBy(uint256 id, address proposer)0xf0780e78
This wallet has already proposed on this request. One proposal per wallet.From propose
BadDeadline(uint64 deadline)0xe2d0da95
A deadline is between one day and one year from now.From post
BadRange(uint256 from)0xc7714240
Ask for a page that starts at 1 or later.From getRequests
BatchTooLarge(uint256 count, uint256 max)0xbb1cb70b
That is more rows than one call may carry.From getRequests
BountyTooSmall(uint128 bounty, uint128 min)0xbace04b9
The smallest bounty or top up is 1 USDG.From post, topUp
DeadlineNotReached(uint256 id, uint64 deadline)0xad3664a6
A request can be closed or reclaimed once its deadline has passed.From close, reclaim
Empty(string field)0xa47fea01
One of the required fields is empty.From post
EnforcedPause()0xd93c0665
That is paused by the Poncho owner right now.From pause, post, propose, topUp
ExpectedPause()0x8dfc202b
That only runs while the contract is paused.From unpause
FeeSinkNotSet()0xe0c77412
The fee sink is not set yet.From sweepFees
FeeTooHigh(uint16 feeBps, uint16 max)0x3c057d7b
That fee is above the hard cap of 5%.From setFeeBps
InsufficientEarnings(address account, uint256 earnings, uint256 amount)0xb9fc9860
That is more than the earnings you can pull.From withdrawEarnings
NoRequest(uint256 id)0x9e38735c
That request does not exist.From award, close, dismiss, getRequest, propose, reclaim, reclaimFor, topUp
NotOpen(uint256 id, Status status)0x1478b336
That request is closed.From award, close, dismiss, propose, reclaim, topUp
NotProposed(uint256 id, uint256 serviceId)0x9497ed0d
That service did not propose on this request.From award, dismiss
NotReclaimed(uint256 id, Status status)0x47a524c9
Refunds open once the request has been closed after its deadline.From reclaimFor
NotRequester(uint256 id, address requester, address caller)0x3d30e90c
Only the wallet that posted the request can do that.From award, dismiss, reclaim
NotServiceOwner(uint256 serviceId, address owner, address caller)0xe8340ac1
Only the wallet that owns the service can do that.From propose
NothingBacked(uint256 id, address backer)0x7cf5fbee
That address has nothing left to reclaim here.From reclaim, reclaimFor
NothingToSweep()0x351261fc
There are no fees to sweep.From sweepFees
OwnableInvalidOwner(address owner)0x1e4fbdf7
That owner address is not allowed.Inherited, or raised by a library the contract uses.
OwnableUnauthorizedAccount(address account)0x118cdaa7
Only the Poncho owner can do that.From acceptOwnership, pause, renounceOwnership, setFeeBps, setFeeSink, transferOwnership, unpause
ProposalDismissed(uint256 id, uint256 serviceId)0xfeda119b
The requester turned that service down on this request.From propose
ReentrancyGuardReentrantCall()0x3ee5aeb5
That call is not allowed from here.From award, close, dismiss, post, propose, reclaim, reclaimFor, sweepFees, topUp, withdrawEarnings
RenounceDisabled()0x89051165
Ownership cannot be renounced.From renounceOwnership
SafeERC20FailedOperation(address token)0x5274afe7
The token transfer failed.From post, reclaim, reclaimFor, sweepFees, topUp, withdrawEarnings
ServicePaused(uint256 serviceId)0xb62855a8
That service is paused, so it cannot propose.From propose
TooLong(string field, uint256 length, uint256 max)0x6d3b0993
One of the fields is longer than the contract allows.From post
TooManyBackers(uint256 id, uint256 max)0x007cd97e
This request has taken all 128 backers.From topUp
TooManyProposals(uint256 id, uint256 max)0x94558e75
This request has taken all 64 proposals.From propose
TransferShortfall(uint256 expected, uint256 received)0xaea7b7c0
The USDG transfer came up short.From post, topUp
ZeroAddress()0xd92e233d
An address is missing.From setFeeSink
ZeroAmount()0x1f2a2005
Enter an amount above zero.From withdrawEarnings

Connect a wallet

Poncho never holds your keys. Connecting shares your address only.