docs(quoter-bot): add loan-as-collateral markets tib - #180
Merged
Conversation
TIB-2026-08-27 decides how the ladder quotes both sides of a Midnight loan-as-collateral market (loan asset in the collateral list, constant price-1 oracle) from zero inventory: an opt-in per-market debt config block, a maturity-safe collateral-coverage invariant that makes pre-maturity liquidation impossible by construction, non-reduce-only sells, manual-first collateral management, and penalty-free LLTV=1 post-maturity settlement. Partially supersedes TIB-2026-07-27 (no-debt invariant and the reserved position-health check) and indexes the TIB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 126bffeb2c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…rkets-ad63ab # Conflicts: # docs/decisions/TIB-2026-07-27-midnight-quoter-bot.md
Address the five codex findings: convert credit units to seller assets before summing sell capacity, pin all coverage inputs to one block, fail readiness when the debt block is removed over outstanding debt, require aggregate debt reservations in the signing middleware, and make maturity settlement an actionable operator runbook (LIF=1 gives third parties no incentive to settle). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
haydenshively
approved these changes
Sep 3, 2026
Debt obligations survive whole-market removal via a durable debt-market registry that only clears on a pinned-block debt == 0 read; the breach transition becomes a dedicated make-port operation cancelling all owned lower-side groups in one native multicall with stay-in-breach retry semantics; and over-cap debt is an explicit breach state reported distinctly by position-health, never silent zero headroom. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rename maximumDebtAssets to maximumDebtUnits (the cap is protocol face units, the exact confusion the tib warns against) and express the buffered collateral requirement as an explicit mulDivUp chain with tiny-value and uint128-boundary test vectors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The debt-market registry entry is written in the same atomic ownership-state write as any debt-capable reservation, and GC requires both no remaining debt-capable reservation and a pinned-block debt == 0 read ordered after the confirmed cancellations. Breach becomes a side-scoped reconciliation mode: sell-freeze retried to confirmation, then higher-side-only generation/recenter/resize replenishing stale buys, never touching the generic hard-halt path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
devin-ai-integration
Bot
force-pushed
the
loan-as-collateral-markets-ad63ab
branch
from
September 3, 2026 18:29
342627b to
426ddc0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Loan-as-collateral markets (loan asset in the market's collateral list — e.g. a USDC / cbBTC+USDC market) are the protocol-intended maker pattern for quoting both sides from zero inventory: instead of bootstrapping credit at negative carry, the maker posts the loan asset as collateral and lets sells create debt. TIB-2026-07-27 §3 explicitly reserved the position-health check as mandatory "before any strategy revision can increase collateralized debt" — this TIB is that revision, deciding the design before any code lands.
What
336b924a):isHealthyhas no time term, so collateral sized per publication for the worst case (current debt + every live sell cap converted at its tick price) makes pre-maturity liquidation impossible even if the bot halts; monitoring becomes a tripwire, not a control loop;debtconfig block; absent block = byte-for-byte today's behavior;replace;collateralParams, constant-oracle bytecode pinning (price() == 1e36), per-cycleenterGate.canIncreaseDebtrecheck, disclosedmaxLifsettlement-penalty bound; the market ID content-addresses all params, so allowlisting is the acceptance boundary;withdrawCollateralagainst current debt only, never resting sells);repay+withdrawCollateralis the voluntary runbook);startmust accept an empty bootstrap list), five considered alternatives, phased delivery, and open questions (Morpho API takeability for collateral-backed sells; quoter-signer intent schedule).not-required).Reviewer notes
Docs-only; no code changes. Every
L…reference citesdocs/context/repos/midnight-contracts.txtand was verified against it, including the336b924adelta note (deployedsupplyCollateralreverts on oracle revert).pnpm formathas been run.🤖 Generated with Claude Code
Review round 1 (codex)
All five inline findings were incorporated into the TIB: §3 sums sell-side units (credit + debt headroom) and converts once to seller assets at the worst-case tick; §5 pins every coverage input (debt, collateral, on-chain
consumed) to one block and bans the eventually consistent API as a coverage input; §2/§6 fail readiness when thedebtblock is removed while on-chain debt is outstanding; §10 requires the signing middleware to mirror its buy-side aggregate-reservation model for debt capacity; §9 makes maturity settlement an actionable operator runbook, since LIF = 1 gives third parties no incentive to settle. The branch also mergedmain(TIB-2026-08-25's parallel partial supersession of TIB-2026-07-27, kept alongside this one in date order).Review round 2 (haydenshively)
All four findings incorporated: a durable debt-market registry makes the obligation survive whole-market removal (readiness fails until a pinned-block
debt == 0read clears it, groups still cancellable, maturity alerts keyed off the registry); the breach transition is now a dedicated make-port operation — one native multicall cancelling all owned lower-side groups, buys untouched, stay-in-breach retry on an unconfirmed batch; over-cap debt (debt > maximumDebtUnitsafter a cap reduction or out-of-band activity) is an explicit breach state reported distinctly by position-health, never silent zero headroom — with one noted deviation: a coherent over-cap config starts into breach posture instead of hard-failing readiness, preserving the deleveraging channel; and the cap is renamedmaximumDebtUnitswith the §1 requirement expressed as an explicitmulDivUpchain plus tiny-value/uint128 test vectors.Review round 3 (haydenshively)
Registry lifecycle made atomic with sell ownership — entry written in the same durable ownership-state write as any debt-capable reservation, GC gated on both no-remaining-debt-capable-reservation and a pinned-block
debt == 0read ordered after confirmed cancellations — and breach redefined as a side-scoped reconciliation mode: sell-freeze retried to confirmation, then higher-side-only generation/recenter/resize replenishing filled or stale buys every breached cycle, never publishing a lower-side group and never invoking the generic hard-halt path.