priors
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Basarisiz
- exec() — Shell command execution in bin/priors-v2.mjs
- process.env — Environment variable access in bin/priors-v2.mjs
- crypto private key — Private key handling in bin/priors-v2.mjs
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
On-chain credit pool for ERC-8004 AI agents on Robinhood Chain: agents borrow USDG, repay it and earn a public credit score. Contracts, SDK, CLI, MCP server (@priors/mcp), x402 helpers (@priors/x402) and an agent skill.
Priors
Reputation for AI agents that is earned, public and recomputable: every point is real money held at risk for real time, and anyone can rebuild the number from the events.
Reviews are cheap to fake. Priors keeps a public record built from on-chain repayments, and Score v2 counts only debt someone else put at risk. It is not unfakeable: the score's own page lists what each attack costs and what still gets through.
- What it is: an on-chain credit pool on Robinhood Chain where ERC-8004
AI agents borrow USDG, repay it, and build a public credit record and score anyone can check. This repo has the
contracts, the SDK and CLI, an MCP server, x402 payment helpers and an agent skill. - Who it is for: builders of agents that pay for things (x402, USDG), and anyone deciding whether to trust, pay or
lend to an agent. - Connect the hosted MCP (read-only, no key, no transaction):
claude mcp add --transport http priors https://mcp.priors.trade/mcp, or addhttps://mcp.priors.trade/mcpto any
MCP client (other clients). - See an agent use it: agent001, an open-source agent with its own
wallet and Priors credit line. - Hire an agent by the minute: agent002, worker agents that sell their
time by the minute, paid in USDG over x402 or in $PRIORS.
priors.trade · a prior is what you believe about an agent before you deal with it. This
one is backed by money.
A small on-chain credit pool lends unsecured USDG ($5 to $500) to agents registered on
ERC-8004. Every line is backed, dollar for dollar, by someone who put
money behind that agent. Every repayment and every default is a public event. From those events you get a
credit-backed trust score anyone can query before trusting an agent, and a public record of which agents pay
their debts back.
Reviews are cheap to fake. Repaid debt isn't.
Status: Priors v2 is live on Robinhood Chain
Pool v2 (
CreditPoolV2) and treasury v4 are live on Robinhood Chain mainnet (chain 4663) since block
71,702,460, and the seat vault (SeatVaultV3) since 2026-09-25. Addresses come fromdeployments/4663.v2.json, sonpx priors-v2 statusand the SDK resolve them with no configuration. The v1 pool is paused; every v1
repayment record was imported into v2, so agents kept their history. A second seat vault for bigger lines, the
growth seat vault (SeatVaultV4, $50 lines), is live since 2026-09-29.What v2 changes. v1 lent earned credit that nobody backed, and every hard v1 finding lived there. v2 drops
it: every line is 100% backed by a backer's locked pool shares, a default burns that backer's shares worth the
principal and the fee, and lenders never take a loan loss. Lines need the agent owner's signed consent, agents
can change sponsor between loans, and the pool's owner is the PoolSteward, which only a 48-hour timelock can drive.Four ways onto the ledger. A treasury invite (a $5 line from treasury v4, which is funded by $PRIORS creator
fees), a seat (someone puts about five lines' worth of $PRIORS behind your agent and the growth seat vault
backs a $50 line, after 10 repaid loans), a backer who stakes USDG and vouches for you directly, or, since
2026-09-28, a stock line (you deposit
Robinhood stock tokens and the stock vault backs a line against them). Lenders deposit USDG and earn 50% of every
fee.What was found before launch, and fixed. A self-backing loop that took lender yield (fixed with a fee lock),
a utilization-cap freeze (cap set to 100%), a farmable keeper bounty (set to 0), and three seat-vault issues
(offers bound to the owner, idle seats expire, a history gate plus a seat priced far above the line it opens).docs/SECURITY-v2.mdlists every finding with its test and what remains.What that does not buy: v2 has had several internal adversarial reviews and a second-model review of the
fixes, but no third-party audit. No path to lender principal was found, and that is still not a proof.
Launch sizes stay small for exactly that reason. Read it, run it, integrate against it; size your exposure like
someone who knows an audit hasn't happened.Take part: priors.trade has a Participate page (deposits, seats, roots),
/agent and /invite.docs/PARTICIPATE.mdis the same for code.
Give your agent a credit history on mainnet
git clone --recurse-submodules https://github.com/priors-agents/priors && cd priors
npm install
export PRIORS_KEY=0x… # the key that owns (or will own) the agent; env or .env only
npx priors-v2 join # registers an ERC-8004 identity for this key, prints its id
# ask for an invite for that id at https://priors.trade/invite, then:
npx priors-v2 join --invite <code> # treasury v4 opens a $5 line (you sign the pool consent)
npx priors-v2 borrow 5 --days 7 # $5 lands in your wallet
# ... the agent does its work ...
npx priors-v2 repay --all # principal + fee
npx priors-v2 status # line, loans, record
Run the npx commands inside the clone: there they run this repository's own CLI. Outside it, npx priors is an
unrelated npm package and priors-v2 on npm is only a placeholder that prints these instructions, so never run
them with PRIORS_KEY set anywhere else.
The wallet needs a little native gas, enough USDG to pay the fee (about $0.012 on $5 for 7 days) and, for a
self-service invite, the 5 USDG bond (step 2 below). A brand-new agent cannot take a seat:npx priors-v2 join --seat <staker> takes a staker's seat offer only once the agent has repaid 10 loans (new seats go
to the growth seat vault; SeatVaultV3's 10 seats were all taken as of 2026-09-29). Without an invite, a first line comes
from a backer or a stock line.
Or watch it on a throwaway local chain first
git clone --recurse-submodules https://github.com/priors-agents/priors && cd priors
npm install
npm run quickstart
That starts a local chain, deploys the v1 contracts with mocks, and walks one fresh ERC-8004 identity through
the entire record — register, take the treasury's $5 line, borrow, hold, repay, score. The local devnet has not
moved to v2 yet; the flow and the score have the same shape, the backing rules differ (v1's "earned capacity"
below does not exist on v2):
1. identity
ERC-8004 agentId 2, owned by 0xEe7f…eeFf
2. first line
line $5 from sponsor #1 — nobody approved this, it is a rule
3. borrow, hold, repay
quote $5 for 7d: fee $0.011666, qualifies
loanId 1 — $5 is in 0xEe7f…eeFf now
… did work …
4. the record
score 38/1000 · repaid 1 (1 qualified) · 35 dollar-days · fees paid $0.011666
earned capacity $2.5 of its own, line now $7.5
Requires Foundry and Node 20+.
Records survive migrations
The v1 walkthrough was run for real on Robinhood Chain with real USDG, start to finish, through the CLI in
this repo, and its records have now moved twice.
Agent #437 is the interesting one, because its record survived the migration to the fixed
contract. It repaid twice on the original pool; those two loans were carried across byimportRecords, and it has since borrowed and repaid again on the new one:
| step | transaction |
|---|---|
| borrow $5 for 8 days, on the new pool | 0xff8c3e1f… |
| repay principal + fee | 0x0cfc083c… |
npx priors report 437 read the result back off the v1 pool: 3 loans repaid, $15 of volume,
$0.036665 of fees paid, no defaults. At the v2 cutover every v1 record was imported again
(importFromV1), and on v2 agent #437 still shows its 3 repaid loans — the point of carrying
history rather than restarting it. Agent #443 came through the same way.
A record and a credit line are separate things, and a migration carries only the record: capacity
is not imported, so after a cutover an agent shows its full history with a $0 line and no
sponsor until it asks the treasury for one (firstLine, which only the identity's own controller
can call). That is why a freshly migrated agent reads as sponsor #0 for a while. On v2 it asks treasury v4 (an
invite), a staker (a seat) or a backer for a new line.
There is no demo mode in any of that — same contracts, same ERC-8004 registry, same USDG.
Hand it to your coding agent instead
This repo ships the procedure as an agent skill, so you don't have to read any of it:
# Claude Code
mkdir -p ~/.claude/skills && cp -r skills/priors ~/.claude/skills/priors
Then say: "give my agent a credit history on Priors". The skill knows the steps, which chain and pool it is
on, what to do when the treasury's epoch cap is spent, and that it must not claim an agent is registered when it
isn't. Codex and other harnesses read AGENTS.md at the repo root, which carries the same
instructions.
Claude Code plugin
The skill and the hosted MCP server in one install. In Claude Code:
/plugin marketplace add priors-agents/priors
/plugin install priors@priors-agents
The skill runs as /priors:priors, and the read-only server connects as plugin:priors:priors-read, with no key. To
pay, borrow and repay with the agent's own wallet, add the local server too: skills/README.md
has the command, which keeps the key in your environment.
Or connect it over MCP
Read-only, hosted, no key: add https://mcp.priors.trade/mcp (Streamable HTTP) to any MCP client.
claude mcp add --transport http priors https://mcp.priors.trade/mcp # Claude Code
codex mcp add priors --url https://mcp.priors.trade/mcp # Codex (terminal, IDE, ChatGPT desktop)
In Claude (web, desktop, phone), this link
opens the Add custom connector form with Priors filled in. VS Code installs it fromvscode:mcp/install?{"name":"priors","type":"http","url":"https://mcp.priors.trade/mcp"} (URL-encoded) orcode --add-mcp '{"name":"priors","type":"http","url":"https://mcp.priors.trade/mcp"}', and Cursor fromcursor://anysphere.cursor-deeplink/mcp/install?name=priors&config= plus the base64 of {"url":"https://mcp.priors.trade/mcp"}.
ChatGPT takes it in developer mode (Settings, Security and login), on its plugins page, with no authentication.
It answers an agent's record and score, the pool's figures, recent loans and the facilitator's services, and it
cannot sign or send anything. It is also an MCP App: in hosts that render MCP Apps (Claude, ChatGPT, VS Code, Cursor,
Goose) its answers come with a Priors view, and request_borrow / request_repay prepare a borrow or a repayment as
two links where the agent's owner confirms it: Go mode (go.priors.trade), with their own account, or the agent console
on priors.trade, with the wallet that owns the agent. To pay x402 URLs, borrow and repay with the agent's own wallet, run the local server inpackages/mcp (the key stays in your environment). Both packages are on npm:npx -y @priors/mcp runs the local server, and npm i @priors/x402 installs the payer. From a clone,npm install at the root links them instead. The local server is also on the official MCP Registry asio.github.priors-agents/priors, and the hosted one as io.github.priors-agents/priors-read. Since 0.5.0 the wallet
can also keep idle USDG in savings (a USDG vault on Morpho: the agent's own money, with the vault's risks; seepackages/x402), and a borrow on a SeatVaultV5 line refreshes it first. Autopay (repaying each loan on
time from the agent's wallet) is in the packages and refuses to run until AutoRepay v2 is deployed. 0.2.11 carries
0.5.0's security fixes for those staying on the 0.2 line.
Or pay per call
The same record is a paid x402 v2 endpoint: https://api.priors.trade/v1/report/{id} and /v1/score/{id}, 0.03 USDG
each on Robinhood Chain, settled through https://facilitator.priors.trade. An unpaid call answers 402 with the
requirements in its PAYMENT-REQUIRED header; packages/x402 pays it (createPayer({ signer }).pay(url)).
Merchants can sign up for the facilitator themselves at https://x402.priors.trade/merchants. A merchant can also
check who is paying before serving them. recordGate in @priors/x402 reads the payer's Priors record before the
facilitator sees the payment, and can refuse defaulters, ask for repaid loans or price by record. A refused payment
moves nothing (packages/x402).
The four steps (v2)
| 1 | identity | register(uri) on the ERC-8004 registry, once. Your NFT is your identity. Already have an id? Skip this (set PRIORS_AGENT_ID if it predates v2 or was transferred to you). The pool never sees your keys, only the id. |
| 2 | a line | Treasury invite: at priors.trade/invite you post a 5 USDG bond in InviteBond from the wallet that owns the agent, prove you own it to the Telegram bot, and the bot signs treasury v4's invite for your id on the spot; you redeem it with your pool consent → $5 (at most $25 of new treasury lines a week). The bond comes back once the agent has repaid 3 qualified loans with none open, or after 4 days if it never gets a line; a default sends it to the Safe, so taking a first line and walking away nets nothing. Seat: a staker offers a seat of $PRIORS on your id and you accept it → $50 on the growth seat vault, loans of at most 7 days (your agent needs 10 repaid loans first). Backer: a root vouches any size with your signed consent. Stock line: you deposit accepted Robinhood stock tokens and the stock vault backs a line against them (see "Stock lines" below). |
| 3 | borrow, hold, repay | quoteFee → about $0.011666 for $5 over 7 days. borrow → USDG in your wallet. Do work. repay → principal + fee. Under 7 days repays fine but does not count: dollar-days are the score. |
| 4 | grow | Treasury v4 raise(agentId) → $25, after 3 qualified loans, 14 days, score ≥ 100 and a clean record. Beyond that, lines grow by finding a bigger backer: v2 has no unbacked "earned" credit. |
npx priors-v2 join [--invite <code> | --seat <staker>] # identity, then a line
npx priors-v2 borrow <amount> [--days N]
npx priors-v2 repay [--all]
npx priors-v2 status
npx priors score <agentId> # v1 CLI, still reads the paused v1 pool's history
npx priors report <agentId>
Or from JavaScript, on ethers v6, inside the clone (the priors/… imports resolve to this repository there; it is not
published on npm under that name):
import { resolveV2 } from "priors/env"; // deployments/<chainId>.v2.json, RPC_URL, PRIORS_KEY
const { priors } = await resolveV2();
await priors.redeemInvite(agentId, inviteCode); // priors-invite:<id>:<expiry>:<signature>
const { loanId } = await priors.borrow(agentId, 5, 7 * 86400);
await priors.repay(loanId, { agentId });
await priors.status(agentId);
// x402: pay per call, borrowing only the shortfall from the line (docs/FLOAT.md)
await priors.pay("https://merchant.example/api", { agentId, maxBorrow: 5_000000n });
docs/PARTICIPATE.md covers every role (lender, staker, backer, agent);docs/FLOAT.md covers x402 payments on credit and the public facilitator athttps://facilitator.priors.trade; docs/AGENTS.md is the guide for agent builders.
A whole agent instead: agent001 holds its own wallet, joins Priors,
borrows and repays before the due date by itself, sells a service over x402, and talks from a terminal or Telegram. Its
money moves go through @priors/mcp. agent001 sandbox runs the whole loop on a local fork with play money. It also
carries a Priors skill for OpenClaw and Hermes Agent (skills/priors;
in Hermes, hermes skills install priors-agents/agent001/skills/priors): check an agent's record before paying it, and
pay, borrow and repay with the MCP tools.
Stock lines
Since 2026-09-28 the stock vault (StockVault, root #6424) backs a line with the agent's own Robinhood stock tokens.
The agent's owner deposits one of the 35 accepted tokens (listed with their Chainlink feeds indeployments/stock-assets.4663.json) and the vault vouches a line of that
token's loan-to-value: 25-50% of the deposit's value, plus up to 15 points for a record of repaying treasury credit,
at most $250. Loans on it are ordinary pool loans, with the same fee, terms and default rules. Every new loan is
checked against the collateral's value now, so a falling price shrinks what can be drawn, and new credit waits during
a lending hold (a sharp price move, a multiplier change such as a split, a paused or blocked token). Closing gives
every token back, at once with no loan open, otherwise with the last repayment; a line unused for 30 days (7 if
never drawn) can be closed by anyone. A default seizes the whole deposit.
import { resolveV2 } from "priors/env";
const { priors } = await resolveV2(); // the vault's address comes from deployments/4663.v2.json
await priors.stockAssets(); // each token's price, whether the vault lends now, its LTV
await priors.openStockLine(agentId, spyToken, "0.05"); // deposit 0.05 SPY and open the line (signs the consent)
const { loanId } = await priors.borrow(agentId, 5, 7 * 86400);
await priors.repay(loanId, { agentId });
await priors.closeStockLine(agentId); // every token back to the depositor
status(agentId) shows the tokens behind a stock line. @priors/mcp (stock_assets, stock_position) and@priors/x402's credit helpers read the vault too, since 0.2.0; 0.2.1 carries the
security fixes of the private reports. A stock line counts as the borrower's own money in Priors
Score v2 (weights 2.0.1). The tokens are Robinhood's, under its own terms (including where they may be held), and
their issuer can pause, block, burn or upgrade them. The vault is the one upgradeable Priors contract: what its owner,
the Safe, can and cannot do is in docs/SECURITY-v2.md.
What ends it
Miss a due date by more than three days and anyone can mark the loan defaulted. The record is marked defaulted
forever, the identity can never borrow or back anyone again, and the owner's address is marked too. The sponsor
pays: a backer's (or the treasury's) locked shares are burnt for the principal and the fee; on a seat, half the
staker's $PRIORS is burnt. Your branch burns in the grove on priors.trade, in public, and
stays burnt.
There is no appeal. That is why the score means something.
How it works
- Every line is 100% backed. Capacity comes only from a backer's USDG, locked as pool shares. Locked shares
earn lender yield like any other and back the lines their root vouches, 1:1. A default burns the backer's shares
worth principal and fee, so the share price never falls and lenders never take a loan loss. - Consent and handoff. A line needs the agent owner's EIP-712 consent, so nobody is sponsored against their
will. With no loan open an agent can move to another sponsor, so no sponsor is stuck forever. - Four kinds of backer. Treasury v4 (root #6228) is funded by $PRIORS creator fees and vouches by rule:
$5 against an invite, $25 once seasoned, at most $100 of new lines per week, idle lines reclaimed after 30 days.
The seat vault (SeatVaultV3, root #6234) backs a $5 line behind an agent with 3 repaid loans that a staker puts a seat
of $PRIORS on; its 10 seats were all taken as of 2026-09-29, so new seats go to the growth seat vault (below). Stakers earn
the sponsor share of that agent's fees and lose half the seat on a default. The stock vault (StockVault, root
#6424) backs a line against the agent's own stock tokens and seizes them on a default. Anyone can run a root with
$10+ of stake and vouch with consent, at a premium of up to 2% per 30 days. The growth seat vault (SeatVaultV4,
root #6466) is live since 2026-09-29: the same seats for a $50 line, for agents with 10 repaid loans, on loans of
at most 7 days (docs/PRIORS-GROWTH-SEATS.md). - One money loop. Loan fees split 50 / 25 / 25 between lenders, the sponsor, and the reserve.
- A score that is a pure function of the record.
score(agentId)andcreditReport(agentId)onCreditLensV2, the same formula as v1, and every input is an event you can recompute yourself. Score v1 is
dollar-days: principal × how long you actually held it (capped at the contracted term), summed over repaid loans
— up to 400 points. Plus qualified loans (term ≥ 7 days, 20 points each, up to 200), backing (up to 150), age (up
to 150). Your own default is 0, always. The cheapest path to a high score is the honest one: borrow a meaningful
amount, hold it for weeks, repay. - Priors Score v2, off chain and open. Live since 2026-09-27 at
https://priors.trade/api/score-v2, in the paid
API and in both MCP servers: it counts only risk someone else took, lateness, x402 income from payers that aren't
the agent's own, and trust rungs that need time. Engine, weights and tests are insdk/andscripts/; how it
works and what stops gaming it:docs/SCORE-v2.md. The on-chain score above is unchanged. - Check an agent before you deal with it.
https://priors.trade/api/check?agent=<id>or?address=<0x…>: free,
no key, CORS open. It returns the agent's repayment record and score, and a README badge athttps://priors.trade/api/badge/<id>.svg. Seedocs/CHECK-API.md. - Read the score on chain, with its evidence. Priors posts each agent's v2 score to the ERC-8004 reputation
registry; since 2026-10-05 each note carries its own file (the line at a block, on-time repayments with their
transactions, the pool's payment to the agent), hashed on chain.node scripts/verify-attestation.mjs <agentId>
checks one from the chain alone:docs/ATTESTATION-v2.md.
docs/DESIGN.md has the v1 math and attacks; docs/SECURITY-v2.md the
v2 findings.
The parameters, as the contracts set them
| Loan size | $5 – $500 |
| Term | 1 – 30 days |
| Fee | 1% per 30 days, pro rata, plus the sponsor's premium (0 on treasury and seat lines) |
| Fee split | 50% lenders · 25% sponsor · 25% reserve |
| Lender hold period | 7 days. Withdrawing sooner leaves 0.5% behind for the lenders who stayed |
| Grace before anyone can default you | 3 days |
| Counts as a qualified loan at | 7 days |
maxUtilizationBps · keeperBounty |
10000 · 0 |
| Treasury v4 | first line $5 · raise to $25 · $100 of new lines per 7-day epoch · idle after 30 days |
Seats (SeatVaultV3, root #6234) |
seat ≈ $25 of $PRIORS (12,000 on 2026-09-25, resized with the price by the SeatSizer) · line $5 · 50% burnt on default · agent needs 3 repaid loans · seat expires after 30 idle days · $50 of new lines per 7-day epoch |
Growth seats (SeatVaultV4, root #6466; live since 2026-09-29) |
seat ≈ 5 lines of $PRIORS (120,000 at deployment, resized by its own SeatSizer within [110,000, 20,000,000]) · line $50 · 50% burnt on default · agent needs 10 repaid loans · loans of at most 7 days · 20 open seats · seat expires after 30 idle days · $1,000 of new lines per 7-day epoch · protocol seats closed |
Stock lines (StockVault, root #6424) |
35 stock tokens · line 25-50% of the deposit's value by token, plus up to 15 points for a record of repaid treasury credit, never above 70% · at most $250 a line · $1,000 of new lines per 7-day epoch · $1,000 of open lines per token ($500 on CRCL, CRWV, NBIS, RGTI, SNDK, USAR) · whole deposit seized on default · idle after 30 days (7 if never drawn) |
| Minimum root stake | $10 |
| Pool owner | PoolSteward since 2026-10-06 (no owner, not upgradeable), which only the 48 h TimelockController can call (the Safe proposes and executes, no admin), within a fixed policy: sponsor ≤ 25%, reserve ≤ 40%, lenders ≥ 35%, fee ≤ 2% per 30 days; the Safe is guardian (pause ≤ 14 days, exits never pause) |
Robinhood Chain
The target chain is Robinhood Chain mainnet (id 4663).
| Address | |
|---|---|
| CreditPoolV2 (live) | 0x281210097f0de7A8FB6F87310AF0f089c9C8DE21 |
| CreditLensV2 (score and report views) | 0x9d7035722bd42C551f82FEB9FDDd17453AEF3D9B |
TreasurySponsorV4 (live, root #6228, invite-gated) |
0x0c5091235A25bBFD3F5a009cBe04120D0CBAD573 |
SeatVaultV3 (live since 2026-09-25, root #6234) |
0x59D155C42A9263fA7596867b992bB3e84dF680a9 |
SeatVaultV2 (retired and paused, root #6229; replaced by V3 for audit V-2) |
0x6D934C07a33E7285cE691A9B258cdB53F18e6B5F |
| PoolSteward (owns the pool since 2026-10-06; only the timelock can call it) | 0x6D9D4135417E0AB2aafc69Fc842525Af279a5Da8 |
| TimelockController (drives the PoolSteward, 48 h) | 0x5d984C274035F81BB327d532897a902C5125F87c |
| SeatSizer (owns the seat vault since 2026-09-26; resizes the seat from the $PRIORS price, within bounds) | 0xd24B6484f4E68d72Fd2d3AF7bD036560B2ed5E61 |
SeatVaultV4, the growth seat vault (live since 2026-09-29, root #6466) |
0xb1c3a04496238D62E3c93118C297163855e22192 |
| SeatSizer of the growth seat vault (owns it; the Safe owns the sizer) | 0x97C4e594D458f8BBE961d5384Bbd8a9Cc2D18777 |
StockVault (live since 2026-09-28, root #6424; lines against stock tokens; a Transparent proxy, StockVaultProxy) |
0xbEcd07EC689988e16b870C121756C4c2C8cb02B6 |
| StockVault implementation (behind the proxy; since 2026-10-04) | 0xC16f7230b79Fb7dB3b1761A23e9d56365300B2A4 |
| StockVault ProxyAdmin (the only way to upgrade the vault; owned by the 48 h timelock since 2026-10-07, by the Safe before) | 0x5174A18550a295cd25aF59416a56B7e4c38C8Afc |
| Safe (2-of-3; proposes to the timelock, owns treasury v4 and both SeatSizers, so every other seat vault power, and the stock vault's settings) | 0x20c6816B2419616238772591965E6E9AbE493fD5 |
| RevenueRouter (the steward's sweep and the vaults' fees go here) | 0xb2E217C5841a968C48Eee41DCbF7D2a03cCA4F43 |
| BuyAndBack (engine 1) | 0xEe40675aBEC90E52211526845433C10c80fD569E |
| PriorsLiquidity (engine 2) | 0xbEC159832D05749557F3f972c4823979C8dC8451 |
| SwapLimiter (the engines' depth guard) | 0x4535b1d92ebBe8176463dE4b58Ca9B66A231eb0E |
| KeeperHelper (SeatSizerV4's keeper since 2026-10-06; the keeper key's one entry point) | 0x3Ba233d2ac1C6233C5fA954C2DaaD83fcCFE5372 |
| InviteBond (the bond an automatic invite needs; no admin) | 0x8BE478c754D9124D11e78dB20F5bf4dA45403275 |
| ERC-8004 Identity Registry | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| USDG (Robinhood's 6-decimal dollar, the pool asset) | 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 |
| $PRIORS token (Pons V2) | 0xeDBf91223639800BCd5756815CAf908Df3b890bE |
| x402 facilitator | https://facilitator.priors.trade (merchant sign-up: https://x402.priors.trade/merchants) |
| Hosted MCP (read-only) | https://mcp.priors.trade/mcp |
| Paid API (x402 v2, 0.03 USDG) | https://api.priors.trade |
RPC (official; the only one that serves eth_getLogs) |
https://rpc.mainnet.chain.robinhood.com |
| RPC backups, for plain calls | https://robinhood-rpc.publicnode.com, https://rpc.ordofi.network |
| Explorer | https://robinhoodchain.blockscout.com |
| CreditPool v1 (paused, superseded by v2; history imported) | 0x0259889e6EBab1a18CeE7e62Bc5B9648FB6C44e5 |
TreasurySponsor v3 (v1 pool, superseded by v4, sponsor #486) |
0x59f212317b42D308E81EaF8C078fc8189E2a77Df |
TreasurySponsor v2 (v1 pool, superseded, sponsor #461) |
0x9338d18b5E7faC5ce06a6AD1Af33Db68fE0b4daC |
| ReserveFunder (v1) | 0x32349B1Ad07513B5Fa6dCC3dbDC0B5ed17FcB72d |
| CreditPool (older v1 pools, paused, do not use) | 0x4B9fb2dE6BE54aF037683A75F3C82c81C3EEd122, 0xd970472b2904D5923882af034cea4067AF0AaC95 |
Addresses resolve from deployments/4663.v2.json (v2) and deployments/4663.json (v1, kept for history and
marked paused), so nothing above needs copying by hand. The superseded contracts are listed only so an old link is
recognisable as dead rather than mysterious.
Why lenders have a hold period
The lender slice of a fee lands on the share price the moment a loan is repaid, so whoever holds shares
at that instant collects it. An audit showed both ways that was abused: a bot depositing in front of a
repayment and leaving straight after took $2.70 of a $3 lender fee, leaving $0.30 for the lender who
had carried thirty days of default risk — and a borrower could wrap its own repayment in a deposit and a
withdrawal, in one transaction, and recover 54% of its own fee.
Leaving inside 7 days now leaves 0.5% behind, which stays in the pool for the lenders who did not leave.
That is enough to make a zero-duration position lose money: the borrower's sandwich costs $549.54 against
the $505.00 it owed. It is a constant in the contract, not a parameter, in v1 and v2 alike — an
owner-tunable exit fee would be a lever to confiscate deposits, and the owner cannot reach lender principal
here. Hold past 7 days and it is zero.
RPC_URL accepts a comma-separated list and tries it in order — the first entry first, the next only
when that one fails or refuses to serve the request:
RPC_URL=https://rpc.mainnet.chain.robinhood.com,https://robinhood-rpc.publicnode.com,https://rpc.ordofi.network
Worth doing: the official endpoint rate-limits under load, and a 429 there is otherwise the end of the
read. The backups take plain calls happily but cannot serve event history — publicnode answers 403Archive requests require a personal token and ordofi answers -32005 the network is busy — so anything
reading logs still needs the official endpoint reachable. The SDK knows the difference: a node refusing
to serve moves to the next entry, while a revert is returned as-is, because a revert is the chain's
answer and identical everywhere.
Repository
src/CreditPoolV2.sol v2 pool: lenders, backers (roots), consent, handoff, fee lock, 100% backing
src/libraries/PoolV2Lib.sol v2 pool's linked library (hooks, consent digest)
src/CreditLensV2.sol v1-shaped score and credit-report views on the v2 pool
src/TreasurySponsorV4.sol the $PRIORS treasury as a v2 root: invite + consent opens a line, rules size it
src/SeatVaultV3.sol $PRIORS seats: a staker's tokens behind an agent, the vault backs its line (live)
src/SeatVaultV4.sol growth seats: V3 plus the slash split, protocol seats, a loan-term cap (live)
src/SeatSizer.sol owns a seat vault: keeps the seat at ~5 lines of $PRIORS from the pool price (live)
src/SeatVaultV2.sol the previous seat vault (retired; V3 closes audit V-2)
src/InviteBond.sol the bond behind an automatic invite: back after seasoning, to the Safe on default
src/StockVault.sol lines against Robinhood stock tokens: per-token LTV, lending holds, seizure on default (live)
src/StockVaultProxy.sol the stock vault's Transparent proxy; its ProxyAdmin (the timelock's since 2026-10-07) alone upgrades it
src/PoolSteward.sol the pool's owner since 2026-10-06: the timelock's calls against a fixed policy, the daily sweep
src/RevenueRouter.sol where the sweep and the vaults' fees go, and their split
src/BuyAndBack.sol engine 1: buys $PRIORS on its Pons pool
src/PriorsLiquidity.sol engine 2: $PRIORS liquidity
src/SwapLimiter.sol the engines' depth guard (src/libraries/PoolDepth.sol, EngineMath.sol)
src/KeeperHelper.sol the keeper key's one entry point: SeatSizerV4's price and the limiter's depth snapshot
src/GuardianPause.sol the guardian pause the engines share
src/CreditPool.sol v1 pool (paused; its records were imported into v2)
src/TreasurySponsor.sol v1 treasury (v3)
src/ReserveFunder.sol v1 creator-fee sweep into the reserve
src/libraries/ScoreLib.sol the trust score (shared by v1 and the v2 lens)
src/mocks/ MockUSDC (6 decimals), MockIdentityRegistry, MockPonsFeeEscrow
test/ 754 tests: v2 units, invariants, audit PoCs and fixes (audit-v2/, audit-final/,
review-v2/, audit-v4/, audit-r2/, audit-sizer/), the stock vault's (StockVault*), the growth seat
vault's (SeatVaultV4*), and the v1 suite
script/DeployV2.s.sol deploys the v2 set under a 48 h timelock, writes deployments/<chainId>.v2.json
script/Deploy.s.sol v1 deploy (mocks on dev chains), writes deployments/<chainId>.json
sdk/priors-v2.mjs the v2 client on ethers v6, ABIs included
sdk/stock-vault.mjs stock-vault reads: accepted tokens, prices, holds, a line's collateral
sdk/float.mjs x402 pay() that borrows only the shortfall; sdk/x402.mjs has the payload constants
sdk/priors.mjs the v1 client
sdk/env.mjs resolves chain, deployment record (v1 and v2) and signer
packages/x402/ @priors/x402: x402 v2 USDG preset for Robinhood Chain, facilitator config, a payer that
borrows the gap, the merchant's record gate, savings and Autopay helpers
packages/mcp/ @priors/mcp: local MCP server with the agent's wallet (pay_url, borrow, repay, savings,
Autopay, reads)
bin/priors-v2.mjs the v2 CLI (`npx priors-v2`)
bin/priors.mjs the v1 CLI (`npx priors`), for v1 history and the local devnet
scripts/devnet.mjs local v1 chain, deployed and bootstrapped so firstLine() actually works
scripts/quickstart.mjs devnet + one agent through the entire record
skills/priors/SKILL.md the agent skill
skills/.claude-plugin/ skills/ is also the Claude Code plugin `priors`: the skill and the hosted MCP (skills/.mcp.json)
.claude-plugin/ the Claude Code marketplace `priors-agents` that lists it
docs/PARTICIPATE.md lenders, stakers, backers and agents on v2
docs/FLOAT.md credit as float: x402 payments on a line
docs/SECURITY-v2.md every known v2 finding, its fix or residual, and its test
docs/AGENTS.md guide for agent builders
docs/CHECK-API.md the free check API and badge: an agent's record by id or address
docs/ATTESTATION-v2.md the registry note's file and how to verify it (scripts/verify-attestation.mjs)
docs/DESIGN.md the v1 math, the attacks, the parameters
SECURITY.md how to report a vulnerability, what is in scope, what is already fixed
BOUNTY.md what a finding pays, what is in scope on chain, and the safe harbour
Found something? SECURITY.md — use this repo's private vulnerability reporting, and
please do not put details in a public issue. BOUNTY.md says what it is worth; the ceiling is
small and we say so up front rather than after you have spent a week.
Working on it
forge test # 754 tests, all green (fork-only tests skip without FORK_RPC)
npm test # SDK, CLI and publish-guard checks (needs Foundry for the v1 end-to-end run)
npm run test:v2 # the v2 SDK and x402 client, network-free
npm run devnet # local chain + deployed, bootstrapped v1 pool
npm run quickstart # devnet + the full agent flow
bash scripts/check-public.sh # fails if a credential ever reached a tracked file
CreditPoolV2 compiles with via-IR at optimizer_runs = 1 to fit the 24 KB limit (a per-file restriction infoundry.toml); everything else compiles as before. Contracts are non-upgradeable, except the stock vault: a
source change only reaches users through a new deployment, or, for StockVault, an upgrade through its ProxyAdmin,
which the 48 h timelock owns since 2026-10-07 (the Safe schedules it in public). src/StockVault.sol stays byte-identical to the source verified on chain, so forge fmt skips it.
Honest risks
- Demand is early. Agents mostly need money for inference and API calls. Volumes are real but small.
- Backers carry the credit risk. On v2 that is the point: a default costs its backer, not the lenders. Back
agents you would lend to yourself. - Seats are priced in a volatile token. A seat deters a stolen line only while half of it is worth far more
than the line. If $PRIORS collapses, the seat size has to move (seedocs/SECURITY-v2.md, X-3). - This is not an audit. v2 has had internal adversarial reviews, not a third-party audit. v1 shipped with a
lender-loss defect the randomized invariants did not catch. Assume there is another one.
v1: what happened before
The v1 pool ran on Robinhood Chain until the v2 cutover, and is now paused. This is its record, as
it was written while v1 was live; it is kept because it is the history v2 was built on.
v1 status: what we found, and what we did about it
A review found a way for lenders to lose principal:
markDefault()released an agent's entire delegated
backing on its first default, so a second default from the same agent found nothing left to charge. We wrote
the counterexample as a test, committed it failing, and left it public while it was still broken.It is fixed. A default now consumes only the liable slice of the delegation per loan; the rest keeps backing
that agent's other open loans and is released when the last one closes, and earned credit is written off against
bad debt and retired at settlement. The test that proved the bug is still in the suite, and it passes:forge test --match-test test_multipleDefaultsKeepLendersWholeWithoutEarnedExposure -vv
test/DefaultAccounting.t.soladds the cases that make the fix mean something: partial defaults, repayment
after default, multiple children, sub-sponsor recourse per default, a dead sponsor, root defaults, and the
reserve lock.forge testis 97 passed, 0 failed, invariants included.What that does not buy: no independent review of the economics has happened, and randomized invariants
passed right through the original bug — a fuzzer that never defaults the same agent twice reports green forever.
Launch caps stay small for exactly that reason. Read it, run it, integrate against it; size your exposure like
someone who knows an audit hasn't happened.The pool is live on Robinhood Chain mainnet (chain 4663), seeded small on purpose: 150 USDG of lender
liquidity, 75 in the first-loss reserve, 65 staked by the treasury. Addresses come fromdeployments/<chainId>.json, sonpx priors doctorresolves it with no configuration.npm run quickstart
still builds you a throwaway local chain in about thirty seconds if you would rather not touch mainnet.A second defect was found after launch, and has now been fixed and redeployed. A root sponsor could
vouch outstake + earned; when the delegation defaulted,markDefaultclamped the root's liability to its
stake and charged the shortfall to the reserve — but never retired the root'searned. The same earned credit
then backed a defaulted delegation and remained the root's own borrowing capacity: the reserve paid twice,reserve >= totalEarnedbroke, and lenders lost principal. Worth being precise about what was not wrong:vouch()letting a root delegate more than its earned. A root's stake is cash, so that delegation is backed;
requiringdelegatedOut <= earnedfor roots would break the treasury, which vouches every line out of stake
withearned = 0. The permission was right — the accounting on default was incomplete.
test/ReviewPoC_RootEarnedDoubleSpend.t.solis the original proof-of-concept, now inverted into the
regression guard: it runs the attack move for move and asserts containment. Revert the fix and it fails
naming the broken invariant. The pool was migrated to the fixed bytecode, carrying every agent's
repayment record across — seeimportRecordsandtest/HistoryImport.t.sol— and theminStakelockout
that had stood in for the fix is lifted, so third-party root sponsors work again.The old pool is paused and abandoned. $10 of stake is stranded in it forever, behind two credit lines
that were already given:unvouchisonlyController(sponsor)and the TreasurySponsor exposes none, so a
line cannot be taken back. That is a design property, not an accident, and it is the whole reason onboarding
is finite.Practical consequence: onboarding is finite. The treasury vouches $5 per agent out of its own 65 USDG of
stake, so the beta seats thirteen agents in total. Capacity grows only when $PRIORS creator fees are swept
into the treasury — by hand during the beta. Don't trust that count once it is a day old: priors.trade shows
how many first lines are left, read live from the chain, and so doesnpx priors report 445
(available÷ $5).
License
MIT
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi