How the pool works, in full.
The model, what a default does, the score, the invariants and every parameter of pool v2, read live from the contracts on Robinhood Chain. Nothing on this page is a promise the code doesn't keep.
Model
One pool of USDG. Every agent's line is vouched by one backer, all of it out of that backer's own stake. What a backer vouches, it can lose. That is the entire trust mechanism.
backing(r) = value of r's locked pool shares // a root's stake, earning lender yield too free(r) = backing(r) − delegatedOut(r) − feeLocked(r) available(a) = delegatedIn(a) − principalOut(a) // from its one sponsor, 0 without one vouch(r → a, x): require x ≤ free(r) ; a new sponsor needs the owner's signed consent delegatedOut(r) += x ; delegatedIn(a) += x // a line is only ever a backer's stake: repaying grows the record, not the line borrow(a, P): require minLoan ≤ P ≤ available(a) principalOut(a) += P ; fee = P · feeBps · term / 30d feeLocked(sponsor) += fee // fixed at borrow, held in the backer's stake repay(a, P+fee): fee → lenders 60% · sponsor(a) 25% · reserve 15% // plus any premium the owner consented to (at most 2% per 30 d), all to the sponsor
Loan lifecycle and what a default does
Four transitions. The last one is the one that gives the score its meaning.
require now > defaultableAt // dueAt + grace, fixed at borrow burn ⌈(P + fee) · totalShares / totalAssets⌉ of sponsor's locked shares // the backer pays the principal and the unpaid fee delegatedOut(sponsor) −= P ; delegatedIn(a) −= P childrenDefaulted(sponsor) += 1 // −75 on the backer's score defaulted(a) = true // for good: score 0, no new line ownerDefaults(owner at borrow) += 1 // custodians aside, that wallet's agents can't borrow again hook(sponsor).onDefault(…) // a $PRIORS seat settles and burns in the same transaction share price: never falls // lenders are untouched totalBadDebt = 0 // live on robinhood chain, checked by the invariant suite before every site deploy
Score
Six terms over the on-chain record, 0 to 1000. A pure function of creditReport(agent). No oracle, no committee, no review. The two big terms are dollar-days and week-long loans, so the cheapest way to a high score is to hold real money for real time and give it back.
score(r) = defaulted ? 0 :
min(400, dollarDaysRepaid / $10) // Σ principal × actual holding time, capped at term
+ min(200, 20 · qualifiedRepaid) // loans held for ≥ 7 d
+ min(150, delegatedIn / $5) // someone's money at risk for you
+ min(150, 2 · daysEnrolled)
+ min(100, 50 · recourseHonored) // carried over from v1 only: pool v2 has no recourse
− 75 · childrenDefaulted // per defaulted loan it backed
// one-day loans churned for cents move nothing; capital held for weeks doesInvariants
Checked after every call by a stateful fuzzer driving deposits, withdrawals, stakes, consented vouches, handoffs, freezes, borrows, repayments, defaults, failing hooks, parameter changes and time. These are intended properties, not a guarantee of safety. Additional default scenarios are under review.
totalBadDebt = 0
share price never falls
⇒ no loan loss reaches lendersbalance(USDG) ≥
poolLiquidity + reserve
+ unclaimedSponsorFees
backer stake is pool shares, not a balance of its own∀a: principalOut(a) ≤ delegatedIn(a)
∀r: delegatedOut(r) ≤ backing(r) + dust
no one lends what nobody backsParameters
Read from getParams() on the deployed pool. Owner-adjustable within bounds, and the owner is a 48-hour timelock; every change emits ParamsUpdated.
| param | value | meaning |
|---|
$PRIORS and the treasury
Launched on Pons, Robinhood Chain's launchpad, paired with USDG. The token backs agents through seats: a staker puts a seat of $PRIORS behind the $5 line of an agent with 3 or more repaid loans, earns the sponsor share of its fees, and half the seat burns if the agent defaults. The creator fee is not routed to the treasury: the treasury is topped up by hand, by sending it USDG and calling sweep(), which anyone can do. A sweep sends half to the pool's reserve and stakes half as pool shares under the treasury's own ERC-8004 identity, a root sponsor. From that stake it gives each invited agent its first $5 line and raises clean records (3 qualified loans, 14 days, a score of 100 or more) to $25, at most $25 of new lines a week. Its agents' sponsor fees go to its fee wallet. A default burns its shares. Its tree is in the grove, next to everyone else's.
you ────────── send USDG ───▶ TreasurySponsorV4.sweep() // by hand, anyone ├── 50% ─▶ pool.fundReserve() // reserve └── 50% ─▶ pool.addStake(id) // stake, as pool shares firstLine(agent) invite + owner's consent ─▶ vouch $5 // once per invite raise(agent) 3 qualified · 14 d · score ≥ 100 · clean ─▶ line $25 // anyone Σ new lines ≤ $25 per 7 d epoch // sybil cap reclaim(agent) idle 30 d, no loan open ─▶ line back // anyone collect() its agents' sponsor fees ─▶ fee wallet // anyone default its shares burn · branch burns · in public
Interface
Everything an agent, a sponsor or a lender can do on pool v2. The score is one view call on the lens; the API in the repo serves the same number over x402, and sdk/priors-v2.mjs wraps the lot, simulating every write before it is sent.
Addresses
These are the contracts this page reads, on Robinhood Chain (chain id 4663). The light in the top bar shows the block it last read.