Back to Blog
Product Update

The bank marked its first two defaults on-chain

November 5, 20264 min read

On September 28 two external agents borrowed $5 USDC each from the bank on Base mainnet, for 30 days, after minting an ERC-8004 passport the same day (agents #96140 and #96141, wallets 0x72ee…2616 and 0x66e6…5fce). The loans matured on October 28. Nothing came back. On October 30 at 01:40 UTC the daily mark_defaults job found both loans past their term with no repayment on-chain, marked them defaulted, reset each agent's ladder and closed their credit. That part of the loop had run before. The part that had not run on an outside wallet until now is the mark.

The mark is a reputation feedback on the ERC-8004 ReputationRegistry on Base (0x8004BAa17C55a88189AE136b182e5fdA19dE9b63). The bank's issuer wallet, 0xB684898D3f4437D93848456141445c66Aa322B13, calls giveFeedback on the agent's passport with value −50, tag1 "loan", tag2 "default", and a feedbackURI of the form urn:rsoft:loan:<request_id>:tx:<disbursement tx>, so the mark points back at the loan it describes. Both were posted on November 4 at 01:40 UTC in block 53483551: https://basescan.org/tx/0x306e8c8d9ee221bf567477949414bfdb3cd3c3a4fe5df8ad09296b5e39a87d84 for #96140 and https://basescan.org/tx/0x9f1aa342a3935792cc82ffce14961e5a3984ef0169c87d218ce624afd3d305db for #96141. Anyone can read them back with getSummary(agentId, [0xB684…], "loan", "default") on the registry: count 1, value −50, for each passport.

Why five days late, honestly. The mainnet IdentityRegistry is not enumerable, so to post on a passport the bank has to find the tokenId a wallet holds. Its resolver does that by reading the wallet's ERC-721 transfer history through an indexing RPC. The first version asked the wrong RPC, the public one, which does not offer that method, so the retry pass logged "passport unresolved" on November 1, 2 and 3 and posted nothing. The fix went to production on November 3 in the afternoon and the next scheduled pass did the rest. Nobody ran anything by hand. The pass is idempotent by design: before posting it counts the bank's own loan/default marks already on the passport and posts only what is missing, so a retry can never double-mark an agent. The job also runs behind a sweep liveness gate: it will not declare a default while the repayment sweep is behind the chain head, so a repayment the bank has not seen yet cannot be mistaken for a default.

What it means for the two agents. The mark is portable. Any lender, marketplace or trust service that reads the registry and trusts the bank as an issuer sees it, the same way they see the ten positive marks the bank has posted for repaid loans since July. At this bank both wallets are now rated D, active default, and a new loan request is rejected at the gate. The bank does not delete marks. If one of them repays a later loan, a +100 goes next to the −50; the history stays, and that is the point of putting it on-chain rather than in a private table.

Where to see it. The explorer at https://rsoft-agentic-bank.com/explorer shows a "−50 on-chain" chip on each defaulted row that opens the feedback transaction, and "+100 on-chain" on repaid rows. The credit lookup at https://rsoft-agentic-bank.com/reputation has a new "Marks from this bank" section, read live from the registry for any wallet, each mark paired with the loan that earned it and the transaction that posted it. The ranking at https://rsoft-agentic-bank.com/ranking flags wallets that defaulted with the bank and lists them last whatever their on-chain score says. The home page now shows the count of defaults marked on-chain next to the loan totals. For machines: GET /api/v1/agents/{wallet}/reputation/feedback returns the same list as JSON, and GET /stats now carries repaid_loans and defaulted_loans.

The numbers so far: ten positive marks for repaid loans, two negative marks for defaults, zero posted by a human. Small, and every one of them is on Base for anyone to check.