$
One pool of USDG. Every agent has a capacity, most of it lent to it by a sponsor. What a sponsor lends out, it can lose. That is the entire trust mechanism.
capacity(a) = stake(a) + earned(a) + delegatedIn(a) // delegatedIn only while sponsor(a) is alive available(a) = capacity(a) − principalOut(a) − delegatedOut(a) vouch(s → a, x): require x ≤ available(s) delegatedOut(s) += x ; delegatedIn(a) += x // a non-root sponsor may only delegate from earned(s) borrow(a, P): require minLoan ≤ P ≤ available(a) principalOut(a) += P ; fee = P · feeBps · term / 30d repay(a, P+fee): fee → lenders 60% · sponsor(a) 25% · reserve 15% earned(a) += min(P · growthBps, epochRoom, maxEarned − earned(a))
Four transitions. The last one is the one that gives the score its meaning.
liable = min(P, delegatedIn(a)) // sponsor is on the hook up to what it pledged if sponsor(a) is root: slash = min(liable, stake(sponsor)) stake(sponsor) −= slash ; poolLiquidity += slash else if sponsor(a) is alive: issue recourse loan(sponsor, liable, 14d) // its own default if unpaid score(sponsor) −= 75 per vouched defaulter else: liable = 0 // dead sponsor, nothing to take uncovered = P − liable reserve −= min(uncovered, reserve) // first-loss capital pays next badDebt += max(0, uncovered − reserve) // provably 0 while earned ≤ reserve
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 × term over repaid loans
+ min(200, 20 · qualifiedRepaid) // loans with term ≥ 7 d
+ min(150, delegatedIn / $5) // someone's money at risk for you
+ min(150, 2 · daysEnrolled)
+ min(100, 50 · recourseHonored) // paid for a child's default
− 75 · childrenDefaulted
// one-day loans churned for cents move nothing; capital held for weeks doesChecked on every state transition by a stateful fuzzer driving deposits, vouches, borrows, repayments, defaults and time. All hold.
badDebt ≤ totalEarned ≤ reserve
⇒ lenders never lose principalbalance(USDG) = poolLiquidity + totalStake + reserve + unclaimedSponsorFees
∀a: principalOut(a) + delegatedOut(a)
≤ capacity(a)
no one lends what they don't holdRead from getParams() on the deployed pool. Owner-adjustable within bounds; every change emits ParamsUpdated.
| param | value | meaning |
|---|
Launched on Pons, Robinhood Chain's launchpad. Its creator fees land in a treasury contract that does two things by rule: half to the first-loss reserve, half staked under the treasury's own ERC-8004 identity as a root sponsor. From that stake it gives any new agent its first $5 line and raises clean records to $50, capped per epoch. Its agents' sponsor fees go to the buyback wallet. Its stake gets slashed when they default. Its tree is in the grove, next to everyone else's.
Pons escrow ──creator fees (USDG)──▶ TreasurySponsor.sweep() // anyone ├── 50% ─▶ CreditPool.fundReserve() // first loss └── 50% ─▶ CreditPool.addStake(treasury) firstLine(agent) never-enrolled ERC-8004 id ─▶ vouch $5 // anyone, once per id raise(agent) 3 qualified loans · 14 d · clean ─▶ line $50 // anyone Σ vouched ≤ $100 per 7 d epoch // a sybil's ceiling collect() 25% of its agents' fees ─▶ buyback wallet default stake slashed · branch burns · in public
Everything an agent, a sponsor or a lender can do. The score is one view call; the API in the repo serves the same number over x402, and sdk/priors.mjs wraps the lot in six methods.
Nothing on this page is stored anywhere but the chain. Add ?rpc=&pool= to render any deployment.