Open Credit · PriorsCreditOracle · OpenCreditVault
Priors as the credit oracle other lenders read
A credit score is infrastructure when someone who did not build it lends on it. PriorsCreditOracle turns an agent’s live Priors record into a tier, a bounded unsecured cap and a rate, readable by any contract in one call. OpenCreditVault is a second lender, deliberately unrelated to the Priors pool: no sponsor, no collateral, no relationship. It asks the oracle and lends on the answer. The Agent Credit Desk prices three products off the Bureau; this page is the lending half of the same claim.
bureau signer 0xa8dA07...f10029 (overlay facts only; it never sets tier, cap or rate) · oracle owner 0xB731...d316 · vault owner 0xB731...d316 (pause only; no admin path to funds)
the claim, filled from chain 4663
Ask the oracle about Agent #494 and it answers Diamond: unsecured credit up to $500.00 at 6% a year.
That is getCredit(494) on 0x17934e...42661c at block 86,143,555 (score 53, 402 Priors loans, 145.7 $d). The claim - “another lender that never met this agent just lent it $X, on Priors’ word alone” - is not true yet for this agent: 0xE14fb6...32411B has not lent it anything, so there is no $X to fill in.
1 · how the vault decided
Agent #494, step by step
- 1What the oracle says nowgetCredit · block 86,143,555tier Diamond (code 5) · score 53 · enrolled true · defaulted false
unsecuredCap $500.00 = min(tierCap $500.00, max(line $9.70, totalBorrowed $3,272)) · rate 6% a year
402 loans taken · 145.7 $d · no Bureau overlay posted (the overlay never changes tier, cap or rate) - 2What the lenders gotLP effectno settlement yet: nothing has been paid into the vault above principal for this loan
before borrow
-
at borrow
-
before settle
-
at settle
-
now
$1.000657
block 86,143,555
USDG 6dp per 1.000000000 oCREDIT · convertToAssets(1e9) by eth_call at the stated block, pinned in the cache once read. The public chain-4663 node serves historical state only for its most recent few thousand blocks (minutes at ~0.1 s blocks); a null means that block left the window before this app first read it, not that the price was zero. The settlement figures come from the event and never expire.
2 · the oracle feed
What PriorsCreditOracle answers right now
reading getCredit for the top agents and pulling a Bureau report for each (a few seconds on a cold cache)…
What getCredit(agentId) enforces: the tier is tierOf(score, loansTaken, dollarDays, enrolled, defaulted) over the live lens record, cumulative thresholds published as constants; the cap a lender may extend is capFor(tier, line, totalBorrowed) = min(tier ceiling, max(live Priors line, lifetime Priors principal)), so a one-loan identity is bounded by what it has actually borrowed. The Bureau overlay (post(fact, sig), EIP-712, strictly newer asOfBlock only, checked against the chain’s own block height chainBlockNumber() from ArbSys, not the parent-chain block.number) adds demonstrated capacity, repaid loans and punctuality to the answer and is shown with its block; it is never an input to tier, cap or rate. The Bureau tier column is the Bureau’s own off-chain policy, shown for comparison - the two ladders are separate policies and need not agree.
3 · the second lender
OpenCreditVault: its book, its loans, its ledger
NAV
$2.50
totalAssets() = idle + live principal + accrued
idle liquidity
$2.50
lendable or withdrawable · idleLiquidity()
live principal
$0
0 active loans in NAV · liveBook()
accrued interest
$0
linear, inside NAV · liveBook()
past grace
$0
carried at zero · liveBook()
principal outstanding
$0
Active loans, overdue included
interest earned
$0.001643
collected · interestEarned()
late fees earned
$0
collected on cures · lateFeesEarned()
bad debt
$0
gross · $0 recovered · net $0
exit price
$1.000657
USDG per 1 oCREDIT redeemed · convertToAssets(1e9)
entry price
$1.000658
USDG per 1 oCREDIT minted · previewMint(1e9) on entryAssets() $2.50
shares outstanding
2.5 oCREDIT
totalSupply() · 9 decimals
loans
1
ever issued · loanCount()
LP return since the first deposit, from the share price - not an APY
0.0657%
annualised over 8.17 days: 2.94%
collected net of write-offs: $0.001643
convertToAssets(1e9) / 1 USDG - 1 at pulledAtBlock: the change in one oCREDIT's exit value since the first deposit minted it at 1 USDG, net of write-offs and of loans carried at zero, including interest accrued on live loans. Annualised linearly over the time since the first Deposit event, and only once that is at least MIN_ANNUALISE_SECONDS (display policy). Backward-looking; not an APY, not a forward yield. Collected net of write-offs = interestEarned + lateFeesEarned - (badDebt - recovered). First deposit: $2.50 by 0xB731...d316 at block 79,253,572 (tx).
loans · newest 1 of 1 · block 86,143,098
| loan | agent | tier at underwriting | principal | rate | started | due | interest paid | recipient | status |
|---|---|---|---|---|---|---|---|---|---|
| #1 | #7616 | Bronze | $2.50 | 24% | 8d ago | 7d ago | $0.001643 | 0x2219...2bCB | repaid |
6 events · blocks 79,251,481 to 86,143,098 · eth_getLogs over the oracle and the vault, newest first
| when | contract | event | agent | loan | counterparty | amount | tx |
|---|---|---|---|---|---|---|---|
| 8d ago | vault | Repaid | #7616 | #1 | 0xB731...d316 | $2.50principal | 0x1d04b862...0267f6 |
| 8d ago | vault | Borrowed | #7616 | #1 | 0x2219...2bCB | $2.50principal | 0x8fce8008...69fcd7 |
| 8d ago | vault | Underwritten | #7616 | #1 | - | $5.00cap answered | 0x8fce8008...69fcd7 |
| 8d ago | vault | Deposit | - | - | 0xB731...d316 | $2.50assets | 0x65d84574...b58d00 |
| 8d ago | oracle | FactPosted | #7616 | - | 0xa8dA...0029 | $5.00overlay capacity | 0xc66d3410...0ef4c8 |
| 8d ago | oracle | BureauSignerChanged | - | - | 0xa8dA...0029 | - | 0x550ce0f3...a56622 |
vault policy · public constants of 0xE14f...411B · block 86,136,098
| GRACE | 3 d | after dueAt; past it a loan is defaultable and carried at zero in NAV |
| LATE_FEE_BPS | 100 bps (1% of principal) | charged on top of interest to cure a written-off loan |
| MIN_PRINCIPAL | $1.00 | smallest loan borrow() accepts |
| MIN_TERM_DAYS · MAX_TERM_DAYS | 1 · 30 d | term range of borrow() |
| MIN_INTEREST_PERIOD | 1 d | interest is charged for at least this long at repayment |
| MAX_OPEN_LOANS_PER_AGENT | 4 | open loans one agent may hold here |
| MAX_ACTIVE_LOANS | 128 | active loans across the vault (bounds the NAV walk) |
| SHARE_DECIMALS_OFFSET | 3 (oCREDIT has 9 decimals) | virtual-share offset against donation griefing |
| YEAR · BPS | 31,536,000 s · 10000 | annualisation base of rateBps |
interest = principal x rateBps x max(elapsed, MIN_INTEREST_PERIOD) / (YEAR x BPS)
totalAssets = idle USDG + principal and linearly accrued interest of Active loans not yet past dueAt + GRACE; loans past that are carried at zero whether or not markDefault was called
entry price (contract rule, policy): deposit / mint are priced at entryAssets = totalAssets + overdue principal + (badDebt - recovered), the owed principal at face; withdraw / redeem at totalAssets. Equal while nothing is overdue or uncured; a deposit placed just before a recovery buys that principal at face, so the recovery goes to the LPs who carried the loss
public constants and immutables of PriorsCreditOracle and OpenCreditVault, read by eth_call; policy, not market data
What borrow(agentId, amount, termDays) enforces: the caller controls the agent (its ERC-8004 owner or its Priors pool delegate) and the USDG always goes to identity.ownerOf(agentId); the oracle’s tier is above Unbanked, the agent carries no Priors default flag and no uncured default here; the amount is at least the minimum principal, keeps the agent’s outstanding within its bounded cap, fits the open-loan and active-loan limits and the idle liquidity; the term is in range. The rate is the oracle’s, frozen at underwriting. repay(loanId) charges simple interest for the time held (at least the minimum interest period); after dueAt + GRACE anyone may markDefault, and a written-off loan can still be cured through repay with a late fee. Every limit is a public constant, listed above as policy once the vault is deployed.
4 · integrate
One call from any contract
import {IPriorsCreditOracle} from "./IPriorsCreditOracle.sol";
IPriorsCreditOracle.CreditFact memory f =
IPriorsCreditOracle(0x17934ec19c01C1C0c758f4dB96b6bbbE0242661c).getCredit(agentId);
// f.tier (0 Unbanked .. 5 Diamond), f.unsecuredCap (USDG 6dp),
// f.rateBps (annual), f.defaulted, f.score - all live from CreditLensV2
require(f.tier > 0 && !f.defaulted, "no unsecured credit");
require(amount <= f.unsecuredCap, "over the oracle's cap");The interface ships with the contracts (contracts/src/open-credit/IPriorsCreditOracle.sol). getTier(agentId) is the one-word version; tierTerms / tierRule / capFor expose the policy.
no key, no SDK
Or read it over HTTP / JSON-RPC
# vault overview, published policy, oracle feed curl -s https://priors-app-xi.vercel.app/api/open-credit # one agent: oracle fact, vault ledger, every loan, the step list curl -s https://priors-app-xi.vercel.app/api/open-credit/agent/494 # straight from the chain (Foundry cast) cast call 0x17934ec19c01C1C0c758f4dB96b6bbbE0242661c "getTier(uint256)(uint8)" 494 \ --rpc-url https://rpc.mainnet.chain.robinhood.com
Every response carries the block it was read at; bigints are strings. While the contracts are not deployed the API answers { deployed: false } with status 200 - the honest state, not an error.
5 · be the next lender or borrower
Wallet console
Wallet console
No EIP-1193 wallet is injected in this browser, so nothing can be signed here. Install a wallet and point it at chain 4663. The vault is 0xE14fb6b2C1c7887c56FE09a5509cB3218E32411B and the oracle 0x17934ec19c01C1C0c758f4dB96b6bbbE0242661c; their functions are the same from any signer.
the same limit, spent · Priors Card
Every identity the oracle gives a limit carries a card: PriorsPay.swipe pays an x402 merchant in the same transaction and the agent settles later. The card and this vault share one unsecuredCap.