From ae560759dc325c5dfea37e0e2914c0710ef54f86 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 22 Sep 2026 13:13:51 +0000 Subject: [PATCH] Give HyperEVM a seven-day market that can take lending offers HyperEVM has one market trusting LenderCommitmentForwarderAlpha - market 3, created outside this repo - and its payment cycle is thirty days. For an EMI market that is not merely a longer default, it is a ceiling on how short a loan can be at all: TellerV2 sizes payments through V2Calculations, EMI lands in NumbersLib.pmt, and pmt opens with require(loanDuration >= cycleDuration) So a seven-day offer published into market 3 cannot be drawn. It publishes, sits in the book looking entirely normal, and reverts for every borrower who tries. Teller Pro's on-demand lending writes seven-day terms everywhere it can and has been forced back to thirty on this chain for exactly that reason. A market of its own is the only fix. The per-market forwarder slot holds one address, so granting Alpha on market 1 - the seven-day pools market - would not add offers, it would take that market's pools off line. That is the trap Arc hit, and why Base runs offers on 22 and pools on 18. The market this task creates is Bullet on a seconds cycle, so the pmt floor does not apply to it at all: one payment at the end, priced off the cycle rather than divided by it. The seven days here is the term we want, not a constraint being worked around. Nothing else in the file changes. The header and the comment above `markets` both said every number there describes market 2 as it already is and is never applied; that stays true of `long` and is not true of the new entry, so both now say which is which. Not deployed. Running it is `yarn hh bootstrap-markets --network hyperevm`, which needs the deployer key and gas on HyperEVM; re-running is safe, since anything already in deployments/hyperevm/market-bootstrap.json is skipped. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01S1HkrFB3R5NcaNt5tLfXr7 --- .../config/chain-bootstrap/hyperevm.ts | 68 ++++++++++++++++--- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/packages/contracts/config/chain-bootstrap/hyperevm.ts b/packages/contracts/config/chain-bootstrap/hyperevm.ts index e18adfe2d..1620ecbca 100644 --- a/packages/contracts/config/chain-bootstrap/hyperevm.ts +++ b/packages/contracts/config/chain-bootstrap/hyperevm.ts @@ -6,14 +6,19 @@ import { ChainBootstrapConfig } from './types' * Everything else in this directory brings a chain online: it creates the * markets, then a pool per collateral. HyperEVM has been live for months with * fourteen pools on market 2, none of them created from this repo. So this - * config exists to add hyperRAM to that market and nothing else, and the + * config started out adding hyperRAM to that market and nothing else, and the * receipt at deployments/hyperevm/market-bootstrap.json is pre-seeded with the - * market that already exists so no fourth one is created. + * market that already exists so no duplicate of it is created. * - * The consequence worth stating: every number under `markets` below describes - * market 2 as it already is, read off chain. They are not applied - a market - * already in the receipt is skipped - so if they are ever edited, the edit - * changes nothing on chain and makes this file wrong. + * It now also creates one market: a seven-day offers market, because the + * chain has none and the thirty-day one it does have cannot carry a + * seven-day loan. See the `shortOffers` entry for why. + * + * The consequence worth stating: the numbers under `markets` below for `long` + * describe market 2 as it already is, read off chain. They are not applied - a + * market already in the receipt is skipped - so if they are ever edited, the + * edit changes nothing on chain and makes this file wrong. `shortOffers` is + * the exception: it does not exist yet, so its numbers are real. * * ## hyperRAM * @@ -93,10 +98,11 @@ const config: ChainBootstrapConfig = { liquidityThresholdPercent: 8000, - // Market 2, which exists. Every field here is a description of it, read on - // chain, and none of them are applied - see the note at the top of the file. - // Its marketplace fee is 200 (2%), not the MARKET_FEE_PERCENT this directory - // uses for markets it creates. + // Two entries, and they are not the same kind of thing. `long` is market 2, + // which exists: every field on it is a description read on chain and none of + // them are applied - see the note at the top of the file. Its marketplace fee + // is 200 (2%), not the MARKET_FEE_PERCENT this directory uses. `shortOffers` + // does not exist and will be created, at that MARKET_FEE_PERCENT. markets: [ { key: 'long', @@ -105,6 +111,48 @@ const config: ChainBootstrapConfig = { paymentDefaultDuration: 5 * 60, bidExpirationTime: 7 * 24 * 60 * 60, }, + { + // The one market in this file that does not already exist, and the + // only entry here whose numbers are applied rather than describing + // something read off chain. + // + // HyperEVM has exactly one market that trusts + // LenderCommitmentForwarderAlpha - market 3, created outside this + // repo - and its payment cycle is thirty days. That is a problem + // specific to EMI markets: TellerV2 sizes payments through + // V2Calculations, which for EMI lands in NumbersLib.pmt, and pmt + // opens with + // + // require(loanDuration >= cycleDuration) + // + // So a seven-day lending offer published into market 3 cannot be + // drawn at all. It publishes, sits in the book looking entirely + // normal, and reverts for every borrower who tries. Teller Pro's + // on-demand lending wants a seven-day term everywhere, and on this + // chain it has been forced back to thirty for exactly this reason. + // + // A market of its own is the only way to fix it. The forwarder slot + // holds one address, so granting Alpha on market 1 (the seven-day + // pools market) would not add offers, it would take that market's + // pools off line - the same trap Arc hit, and why Base runs offers + // on 22 and pools on 18. + // + // Worth noting that this task creates Bullet markets, so the pmt + // floor above does not apply to what it makes: a Bullet loan is one + // payment at the end, priced off the cycle rather than divided by + // it, and never reaches pmt. The seven-day cycle here is what the + // term should be, not a constraint being worked around. + key: 'shortOffers', + label: '7 Day Offers', + purpose: 'offers', + durationSeconds: 7 * 24 * 60 * 60, + // Matching market 2's grace period, which is this chain's own. + paymentDefaultDuration: 5 * 60, + // A day, as on Arc's offers market. An offer carries its own expiry; + // this governs unaccepted bids, and a short one keeps the book from + // filling with stale ones. + bidExpirationTime: 24 * 60 * 60, + }, ], activateMarkets: ['long'],