Credit and deposits
Score thresholds, debt timing, repayment, default, and emergency recovery.
Registration and deposit
Registry.register() transfers the configured DEPOSIT from the agent into the Registry. The deposit remains a refundable liability; it is not payment revenue or a gas budget. Read DEPOSIT and token decimals from the target deployment instead of assuming a fixed amount.
Registration preserves an existing score. Withdrawal and subsequent registration do not reset reputation. Score is a signed integer and can become negative after a default.
Score and credit limit
A recorded prepayment adds 1 point. Repaying the entire outstanding debt adds 1 point. Adding debt alone does not increase the score. Available borrowing headroom is the limit minus current debt; a call requires debt plus price to be no greater than the limit.
getCreditLimit(address) uses the configured DEPOSIT and stored score without checking registration. An exited agent may still display a nonzero theoretical limit, but the gateway and addDebt require current registration. A displayed limit alone is not permission to borrow.
| Score | Contract credit limit |
|---|---|
| Below 3 | 0 |
| 3 through 5 | floor(DEPOSIT / 20), or 5% rounded down |
| 6 or higher | floor(DEPOSIT / 10), or 10% rounded down |
Debt and repayment
The first debt sets dueTime to the block timestamp plus debtDuration. Further calls add debt without extending that due time. Values are token base units, and dueTime is a Unix timestamp in seconds.
CreditLedger.settle() repays the full debt to Registry.treasury(), clears the amount and due time, and triggers the score increment. There is no partial-repayment or interest-accrual method in the current contract.
The current addDebt check enforces registration and the amount ceiling, not an overdue cutoff. Passing the due time makes outstanding debt eligible for default; it does not automatically liquidate the agent or renew its term.
Default and exit
After block.timestamp is strictly greater than dueTime, anyone can call CreditLedger.markDefault(agent) while the required contracts are unpaused. It clears the debt and slashes the full deposit: floor(deposit * 10 / 100) goes to the caller and the remainder goes to treasury. Registration is removed and score decreases by 8.
An agent with no outstanding debt can call Registry.withdrawDeposit(to) to recover its deposit and leave the Registry. Repayment and this user withdrawal remain callable during contract pauses. Destructive default and emergency recovery scenarios are supported by local/fork test evidence, not claimed as live mainnet exercises.
Pause boundaries
| Control | Stops | Still available |
|---|---|---|
| Registry.pause() | Registration, prepayment recording, atomicPrepay, and slash. | Reads, onSettle, and debt-free user withdrawal. |
| CreditLedger.pause() | addDebt and markDefault. | Reads and user settle(). |
| Gateway/facilitator payment pause | New gateway billing and facilitator /settle. | Authorized reads and stored charged resource results where the new API is deployed. |
Recovery authority
Only each contract's owner can pause or unpause it, with Paused/Unpaused events. Owner-authorized upgrades require that target to be paused. The documented mainnet owners are a TimelockController with a 600-second test delay and a single controller, not a multisig.
While Ledger is paused, its owner can emergencyClearDebt, emitting DebtCleared. While Registry is paused, its owner can emergencyWithdrawDeposit to an explicit recipient only after debt is zero, emitting EmergencyDepositWithdrawn. These actions have real trust and loss implications.
Registry.rescueERC20 cannot withdraw active deposits of the payment token; it is limited to the surplus above totalActiveDeposits. Other owner rescue paths and upgrades remain administrative powers. Pre-scheduled Ready pause operations can shorten incident response, but each is consumed on execution and must be replenished before a controlled resume.