@1delta/margin-fetcher 0.0.411 → 0.0.413
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1727 -15
- package/dist/index.js +5376 -399
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PublicClient, Address, Hex } from 'viem';
|
|
2
2
|
import { Lender } from '@1delta/lender-registry';
|
|
3
|
-
export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
3
|
+
export { hasCrossMarginRisk, isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
4
4
|
import { DebitData, LenderDebitData, LstAcceptedInput } from '@1delta/calldata-sdk';
|
|
5
5
|
import { RelayProxyConfig } from '@1delta/proxy-fetch';
|
|
6
|
-
import { TermMarketConfig, LiquityBranchConfig, LiquityConfigChain, RiverMarketConfig, RiverConfigChain, RiverChainData, InverseMarketConfig, InverseConfigChain, InverseChainData, UsddMarketConfig, UsddConfigChain, UsddChainData, TellerPoolConfig, MorphoTypeVaultEntry } from '@1delta/data-sdk';
|
|
6
|
+
import { TermMarketConfig, LiquityBranchConfig, LiquityConfigChain, RiverMarketConfig, RiverConfigChain, RiverChainData, InverseMarketConfig, InverseConfigChain, InverseChainData, ResupplyConfigChain, LlamaLendMarketConfig, LlamaLendConfigChain, LlamaLendChainData, UsddMarketConfig, UsddConfigChain, UsddChainData, FrankencoinMarketConfig, FrankencoinConfigChain, FrankencoinChainData, TellerPoolConfig, MorphoTypeVaultEntry } from '@1delta/data-sdk';
|
|
7
7
|
export { MorphoLensAbi } from '@1delta/abis';
|
|
8
8
|
|
|
9
9
|
interface GenericCurrency {
|
|
@@ -787,6 +787,38 @@ declare function createRawRpcCalls(preparedCalls: PreparedCall[], batchSize?: nu
|
|
|
787
787
|
declare function createMulticallRpcCall(preparedCalls: PreparedCall[], multicallAddress: string, batchSize?: number, blockTag?: string, allowFailure?: boolean): MulticallRpcBatch[];
|
|
788
788
|
|
|
789
789
|
type Call = GeneralCall;
|
|
790
|
+
/**
|
|
791
|
+
* Sentinel written into the result array for a call that returned NO data —
|
|
792
|
+
* a revert, an RPC error, or a whole `aggregate3` chunk that was rejected
|
|
793
|
+
* (rate limit, subrequest cap, dropped connection: viem marks every call in a
|
|
794
|
+
* rejected chunk as `status: 'failure'`).
|
|
795
|
+
*
|
|
796
|
+
* It is NOT a zero value. Parsers must skip these slots — coercing one to `0`
|
|
797
|
+
* turns a failed read into a phantom "no balance" position and, worse, makes a
|
|
798
|
+
* real deposit or debt silently disappear from a user's portfolio.
|
|
799
|
+
*/
|
|
800
|
+
declare const MULTICALL_FAILURE = "0x";
|
|
801
|
+
/** True when a multicall slot holds no usable data (see {@link MULTICALL_FAILURE}). */
|
|
802
|
+
declare const isFailedCall: (value: unknown) => boolean;
|
|
803
|
+
/** Reported for each endpoint that failed to serve a batch. */
|
|
804
|
+
interface EndpointFailure {
|
|
805
|
+
chainId: string;
|
|
806
|
+
/** Endpoint URL, or `rpc#<id>` when the transport does not expose one. */
|
|
807
|
+
url: string;
|
|
808
|
+
rpcId: number;
|
|
809
|
+
/** `transport` — the request itself died. `slots` — it answered with nothing but failures. */
|
|
810
|
+
kind: 'transport' | 'slots';
|
|
811
|
+
}
|
|
812
|
+
interface MulticallEndpointOptions {
|
|
813
|
+
/**
|
|
814
|
+
* Endpoint URLs already attempted for this call set. Failover consults it so
|
|
815
|
+
* a retry lands on an endpoint that has NOT already failed — see
|
|
816
|
+
* {@link resolveEndpoint}.
|
|
817
|
+
*/
|
|
818
|
+
tried?: Set<string>;
|
|
819
|
+
/** Invoked for every endpoint that fails, so callers can demote it. */
|
|
820
|
+
onEndpointFailure?: (info: EndpointFailure) => void;
|
|
821
|
+
}
|
|
790
822
|
declare function prepareMulticallInputs(abi: any[], calls: Call[]): PreparedCall[];
|
|
791
823
|
|
|
792
824
|
interface PreparedUserDataRpcCalls {
|
|
@@ -1049,33 +1081,106 @@ type UserData = {
|
|
|
1049
1081
|
* not as the user's full position.
|
|
1050
1082
|
*/
|
|
1051
1083
|
incomplete?: boolean;
|
|
1084
|
+
/**
|
|
1085
|
+
* Set when this entry did NOT come from the current read: the live read failed
|
|
1086
|
+
* and a previously COMPLETE snapshot was served in its place. The position was
|
|
1087
|
+
* accurate as of `staleAgeMs` ago; it is not a partial read (those are
|
|
1088
|
+
* `incomplete`) and it is never served for a lender that read successfully.
|
|
1089
|
+
*/
|
|
1090
|
+
stale?: boolean;
|
|
1091
|
+
/** Age of the served snapshot in ms. Only set alongside `stale`. */
|
|
1092
|
+
staleAgeMs?: number;
|
|
1052
1093
|
};
|
|
1053
1094
|
|
|
1054
|
-
/**
|
|
1095
|
+
/**
|
|
1096
|
+
* How a lender's slice reacts to a failed read.
|
|
1097
|
+
*
|
|
1098
|
+
* Note what this is NOT keyed on: "is the position cross-margin". EVERY position
|
|
1099
|
+
* with debt is corrupted by a lost read — an isolated Morpho market computes its
|
|
1100
|
+
* health from a collateral read and a debt read, so losing either fabricates the
|
|
1101
|
+
* same nonsense a lost Aave reserve does. The question here is narrower and
|
|
1102
|
+
* purely mechanical: **what is the smallest thing we can void?** A failed slot
|
|
1103
|
+
* carries no market label, so the only unit we can void is the lender key.
|
|
1104
|
+
*
|
|
1105
|
+
* - `strict` — void the whole slice on any lost read. Correct when the slice
|
|
1106
|
+
* resolves to ONE risk computation, which is true both for a single-market
|
|
1107
|
+
* lender and for a multi-market lender that is nevertheless cross-margin
|
|
1108
|
+
* (Exactly scores every market under one per-chain Auditor). Nothing smaller
|
|
1109
|
+
* can be voided, and publishing the remainder would publish a fiction.
|
|
1110
|
+
* - `lenient` — publish, flag `incomplete`, and let per-record invariant
|
|
1111
|
+
* validation catch the corrupted one. Correct ONLY when the slice fans out to
|
|
1112
|
+
* many INDEPENDENT isolated positions, where voiding the key would discard
|
|
1113
|
+
* hundreds of intact markets to hide one — a cure worse than the disease.
|
|
1114
|
+
*
|
|
1115
|
+
* So leniency requires BOTH properties: many independent positions AND no shared
|
|
1116
|
+
* risk computation across them.
|
|
1117
|
+
*/
|
|
1118
|
+
type ReadFailurePolicy = 'strict' | 'lenient';
|
|
1119
|
+
declare const getReadFailurePolicy: (lender: string) => ReadFailurePolicy;
|
|
1120
|
+
/** Why a lender's slice did not convert cleanly. */
|
|
1121
|
+
type IncompleteReason =
|
|
1122
|
+
/** Every read in the slice failed. */
|
|
1123
|
+
'all-reads-failed'
|
|
1124
|
+
/** Reads failed on a strict lender — the whole risk set was voided. */
|
|
1125
|
+
| 'partial-read-cross-margin'
|
|
1126
|
+
/** Reads failed on a lenient lender — surviving markets were published. */
|
|
1127
|
+
| 'partial-read'
|
|
1128
|
+
/** The converter threw. */
|
|
1129
|
+
| 'converter-error'
|
|
1130
|
+
/** The converted entry asserted something that cannot be true. */
|
|
1131
|
+
| 'invariant-violation';
|
|
1132
|
+
/** Reported per lender whose multicall slice did not convert cleanly. */
|
|
1055
1133
|
interface IncompleteLenderRead {
|
|
1056
1134
|
lender: string;
|
|
1057
1135
|
/** Number of slots in the lender's slice that returned no data. */
|
|
1058
1136
|
failedCalls: number;
|
|
1137
|
+
/**
|
|
1138
|
+
* Subset of `failedCalls` that could plausibly succeed on a re-read — i.e.
|
|
1139
|
+
* excluding calls known to have reverted. Zero means re-fetching this lender
|
|
1140
|
+
* is pointless: the markets in question always revert for this account.
|
|
1141
|
+
* Equals `failedCalls` when no `permanentFailures` set was supplied.
|
|
1142
|
+
*/
|
|
1143
|
+
retryableFailedCalls: number;
|
|
1059
1144
|
/** Size of the lender's slice. */
|
|
1060
1145
|
totalCalls: number;
|
|
1061
|
-
/** True when
|
|
1146
|
+
/** True when nothing was published for this lender. */
|
|
1062
1147
|
dropped: boolean;
|
|
1148
|
+
/** What went wrong. */
|
|
1149
|
+
reason: IncompleteReason;
|
|
1150
|
+
/** Extra context for logs (converter message, violation details). */
|
|
1151
|
+
detail?: string;
|
|
1063
1152
|
}
|
|
1064
1153
|
interface ConvertLenderUserDataOptions {
|
|
1065
|
-
/** Invoked once per lender
|
|
1154
|
+
/** Invoked once per lender that did not convert cleanly — for logging / surfacing. */
|
|
1066
1155
|
onIncomplete?: (info: IncompleteLenderRead) => void;
|
|
1156
|
+
/**
|
|
1157
|
+
* Indices (into `rawResults`) of calls that failed deterministically, as
|
|
1158
|
+
* collected by `getLenderUserDataResult`. Used only to compute
|
|
1159
|
+
* `retryableFailedCalls`.
|
|
1160
|
+
*/
|
|
1161
|
+
permanentFailures?: Set<number>;
|
|
1067
1162
|
}
|
|
1068
1163
|
/**
|
|
1069
1164
|
* Converts the raw results into the desired format
|
|
1070
1165
|
*
|
|
1071
1166
|
* Slots that hold the multicall failure sentinel are NOT data: a failed read
|
|
1072
|
-
* says nothing about the user's position.
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
1076
|
-
*
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1167
|
+
* says nothing about the user's position. Coercing one to zero is how a
|
|
1168
|
+
* rate-limited RPC ends up rendering phantom $0 rows and understated balances,
|
|
1169
|
+
* so failures are handled explicitly, in three gates:
|
|
1170
|
+
*
|
|
1171
|
+
* 1. **Failure policy** (see {@link ReadFailurePolicy}). Every read failing
|
|
1172
|
+
* drops the lender under either policy. Beyond that, a `strict`
|
|
1173
|
+
* (cross-margin) lender drops on ANY failure because its aggregates are only
|
|
1174
|
+
* meaningful over the complete set, while a `lenient` (multi-market) lender
|
|
1175
|
+
* publishes the markets that did read and is flagged `incomplete`.
|
|
1176
|
+
* 2. **Converter errors** are reported rather than swallowed — a throwing
|
|
1177
|
+
* converter used to leave a lender silently absent, indistinguishable from a
|
|
1178
|
+
* user with no position there.
|
|
1179
|
+
* 3. **Invariant validation** (see `validate.ts`) rejects sub-accounts that
|
|
1180
|
+
* cannot be true regardless of how the reads went — a `NaN` anywhere in the
|
|
1181
|
+
* aggregates, or (alongside failed reads) debt with no collateral behind it.
|
|
1182
|
+
*
|
|
1183
|
+
* Anything published after that is either complete or explicitly marked as not.
|
|
1079
1184
|
*
|
|
1080
1185
|
* @param chainId - The chain ID
|
|
1081
1186
|
* @param queriesRaw - The queries to fetch data for
|
|
@@ -1088,6 +1193,53 @@ declare const convertLenderUserDataResult: (chainId: string, queriesRaw: LenderU
|
|
|
1088
1193
|
[lender: string]: UserData;
|
|
1089
1194
|
};
|
|
1090
1195
|
|
|
1196
|
+
/**
|
|
1197
|
+
* Why this exists SEPARATELY from the failure sentinels
|
|
1198
|
+
* -----------------------------------------------------
|
|
1199
|
+
* The sentinel path (`isFailedCall`) catches reads that announced themselves as
|
|
1200
|
+
* failures. This catches the ones that did not: a decodable-but-wrong response,
|
|
1201
|
+
* a market whose metadata went missing so its price resolved to `undefined`, a
|
|
1202
|
+
* converter that divided by a zero it should never have seen. Those produce the
|
|
1203
|
+
* SAME user-visible artefact as a dropped read — a debt with no collateral, a
|
|
1204
|
+
* `NaN` health factor — while every slot reports success.
|
|
1205
|
+
*
|
|
1206
|
+
* So this is the last gate before a position is published: it asserts what must
|
|
1207
|
+
* be true of any real lending position, independent of how the data was
|
|
1208
|
+
* obtained.
|
|
1209
|
+
*/
|
|
1210
|
+
/** One failed assertion about a sub-account's published shape. */
|
|
1211
|
+
interface InvariantViolation {
|
|
1212
|
+
/** Sub-account this fired on (`accountId`). */
|
|
1213
|
+
accountId: string;
|
|
1214
|
+
/** Machine-readable check name. */
|
|
1215
|
+
code: 'non-finite' | 'debt-without-collateral' | 'invalid-mode';
|
|
1216
|
+
/** Human-readable detail for logs. */
|
|
1217
|
+
detail: string;
|
|
1218
|
+
/**
|
|
1219
|
+
* `true` when the violation is only conclusive because the read was also
|
|
1220
|
+
* known-incomplete (see {@link validateUserData}).
|
|
1221
|
+
*/
|
|
1222
|
+
requiresFailedReads: boolean;
|
|
1223
|
+
}
|
|
1224
|
+
interface ValidationResult {
|
|
1225
|
+
/** Sub-accounts that passed. Empty means the whole entry must be dropped. */
|
|
1226
|
+
kept: UserDataForSubAccount[];
|
|
1227
|
+
/** Every violation found, including ones on kept sub-accounts. */
|
|
1228
|
+
violations: InvariantViolation[];
|
|
1229
|
+
/** Sub-account ids dropped as corrupt. */
|
|
1230
|
+
dropped: string[];
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Validates a converted entry and drops the sub-accounts that cannot be true.
|
|
1234
|
+
*
|
|
1235
|
+
* `hadFailedReads` gates the checks whose violation is ambiguous on its own:
|
|
1236
|
+
* with a known-incomplete read, `debt-without-collateral` is the signature of a
|
|
1237
|
+
* dropped collateral slot and the sub-account is corrupt; with a clean read it
|
|
1238
|
+
* is a genuine (if grim) position and is kept. Unconditional checks — anything
|
|
1239
|
+
* non-finite — fire either way, because no read produces those legitimately.
|
|
1240
|
+
*/
|
|
1241
|
+
declare function validateUserData(userData: UserData, hadFailedReads: boolean): ValidationResult;
|
|
1242
|
+
|
|
1091
1243
|
interface ExposureInfo {
|
|
1092
1244
|
asset: GenericCurrency;
|
|
1093
1245
|
collateralFactor: number;
|
|
@@ -1127,9 +1279,17 @@ declare function unflattenLenderData(pools: PoolWithMeta[]): LenderData;
|
|
|
1127
1279
|
* @param logs - show multicall error logs, default is false
|
|
1128
1280
|
* @param concurrency - number of distinct RPC endpoints to shard batches
|
|
1129
1281
|
* across in parallel; <= 1 keeps the legacy single-endpoint path
|
|
1282
|
+
* @param permanentFailures - optional collector filled with the indices of
|
|
1283
|
+
* calls that failed DETERMINISTICALLY (revert / no code / unknown selector)
|
|
1284
|
+
* rather than because of the RPC. Pass it to
|
|
1285
|
+
* {@link convertLenderUserDataResult} so a caller can tell "this market
|
|
1286
|
+
* always reverts" from "this read was lost" and only re-fetch the latter.
|
|
1287
|
+
* @param onEndpointFailure - optional hook invoked for every RPC endpoint that
|
|
1288
|
+
* fails to serve a batch. Only the caller knows where to persist that (KV,
|
|
1289
|
+
* metrics), and without it every request rediscovers the same bad endpoint.
|
|
1130
1290
|
* @returns The raw results from the multicall, "0x" for failures
|
|
1131
1291
|
*/
|
|
1132
|
-
declare const getLenderUserDataResult: (chainId: string, queriesRaw: LenderUserQuery[], getEvmClient: GetEvmClientFunction, allowFailure?: boolean, batchSize?: number, retries?: number, logs?: boolean, concurrency?: number) => Promise<any[]>;
|
|
1292
|
+
declare const getLenderUserDataResult: (chainId: string, queriesRaw: LenderUserQuery[], getEvmClient: GetEvmClientFunction, allowFailure?: boolean, batchSize?: number, retries?: number, logs?: boolean, concurrency?: number, permanentFailures?: Set<number>, onEndpointFailure?: (info: EndpointFailure) => void) => Promise<any[]>;
|
|
1133
1293
|
/**
|
|
1134
1294
|
* Prepares the RPC calls for fetching user data without executing them
|
|
1135
1295
|
* Uses multicall3 aggregate3 to batch all calls into a single RPC call
|
|
@@ -1484,6 +1644,21 @@ interface LenderDataEntry extends Omit<LenderSummary, 'subAccounts'> {
|
|
|
1484
1644
|
account: string;
|
|
1485
1645
|
lenderInfo?: LenderInfo;
|
|
1486
1646
|
data: UserDataForSubAccount[];
|
|
1647
|
+
/**
|
|
1648
|
+
* Set when some of this lender's on-chain reads could not be completed. The
|
|
1649
|
+
* positions listed are real but the set is a LOWER BOUND — anything derived
|
|
1650
|
+
* from the whole picture (NAV, net APR, health factor) is unreliable and must
|
|
1651
|
+
* not be rendered as fact.
|
|
1652
|
+
*/
|
|
1653
|
+
incomplete?: boolean;
|
|
1654
|
+
/**
|
|
1655
|
+
* Set when this entry was served from the last COMPLETE snapshot because the
|
|
1656
|
+
* live read failed. Internally consistent — unlike `incomplete` — but as of
|
|
1657
|
+
* `staleAgeMs` ago rather than now.
|
|
1658
|
+
*/
|
|
1659
|
+
stale?: boolean;
|
|
1660
|
+
/** Age of the served snapshot in ms. Only set alongside `stale`. */
|
|
1661
|
+
staleAgeMs?: number;
|
|
1487
1662
|
}
|
|
1488
1663
|
/**
|
|
1489
1664
|
* Input type for buildSummaries - user data result from convertLenderUserDataResult
|
|
@@ -2957,6 +3132,14 @@ interface InverseMarketRaw {
|
|
|
2957
3132
|
borrowPaused: boolean | null;
|
|
2958
3133
|
/** Borrows already taken today against `dailyLimit` — API only. */
|
|
2959
3134
|
dailyBorrows: number | null;
|
|
3135
|
+
/**
|
|
3136
|
+
* `Market.replenishmentIncentiveBps` (1000 = 10%) — the replenisher
|
|
3137
|
+
* bot's cut of a force-replenish, per market. It is carved OUT of the
|
|
3138
|
+
* `replenishmentPriceBps` cost and paid in DOLA from the market's own
|
|
3139
|
+
* liquidity; the borrower's debt grows by the FULL cost either way, so
|
|
3140
|
+
* this is a protocol/bot split, not an extra borrower charge.
|
|
3141
|
+
*/
|
|
3142
|
+
replenishmentIncentiveBps: number | null;
|
|
2960
3143
|
}
|
|
2961
3144
|
/** Raw public-data batch for the FiRM deployment (one chain). */
|
|
2962
3145
|
interface InverseMarketsRaw {
|
|
@@ -3020,6 +3203,184 @@ declare function convertInverseMarketsToResponse(raw: InverseMarketsRaw, chainId
|
|
|
3020
3203
|
[m: string]: MorphoGeneralPublicResponse;
|
|
3021
3204
|
};
|
|
3022
3205
|
|
|
3206
|
+
/**
|
|
3207
|
+
* The immutable half of a Resupply pair. Cached across refreshes because none
|
|
3208
|
+
* of it can change: `collateral` and `underlying` are set in the pair's
|
|
3209
|
+
* constructor and there is no setter (`setConvexPool` only moves where the
|
|
3210
|
+
* SHARES are staked, never what the collateral token is).
|
|
3211
|
+
*/
|
|
3212
|
+
interface ResupplyPairIdentity {
|
|
3213
|
+
pair: string;
|
|
3214
|
+
/** e.g. `Resupply Pair (CurveLend: crvUSD/sfrxUSD) - 1`. */
|
|
3215
|
+
name: string;
|
|
3216
|
+
/** The ERC-4626 share of the WRAPPED market — the accounting unit. */
|
|
3217
|
+
collateral: string;
|
|
3218
|
+
/** What the user actually deposits and withdraws: crvUSD or frxUSD. */
|
|
3219
|
+
underlying: string;
|
|
3220
|
+
collateralDecimals: number;
|
|
3221
|
+
underlyingDecimals: number;
|
|
3222
|
+
}
|
|
3223
|
+
/**
|
|
3224
|
+
* One Resupply pair after the state batch. Raw bigints; `null` = failed
|
|
3225
|
+
* allowFailure read.
|
|
3226
|
+
*/
|
|
3227
|
+
interface ResupplyPairRaw {
|
|
3228
|
+
identity: ResupplyPairIdentity;
|
|
3229
|
+
/** 1e5-scaled (95000 = 95%). */
|
|
3230
|
+
maxLTV: bigint | null;
|
|
3231
|
+
/** Debt ceiling. ZERO ⇒ paused/retired — this is the liveness signal. */
|
|
3232
|
+
borrowLimit: bigint | null;
|
|
3233
|
+
/** 1e5-scaled penalty on top of the debt at liquidation. */
|
|
3234
|
+
liquidationFee: bigint | null;
|
|
3235
|
+
/** 1e5-scaled fee added to minted debt (0 on every live pair). */
|
|
3236
|
+
mintFee: bigint | null;
|
|
3237
|
+
/** Hard per-position floor (1,000 reUSD). */
|
|
3238
|
+
minimumBorrowAmount: bigint | null;
|
|
3239
|
+
/** Face reUSD debt, interest previewed. */
|
|
3240
|
+
totalBorrowAmount: bigint | null;
|
|
3241
|
+
totalBorrowShares: bigint | null;
|
|
3242
|
+
/** Collateral SHARES held by the pair. */
|
|
3243
|
+
totalCollateral: bigint | null;
|
|
3244
|
+
/** 1e18-scaled per SECOND, from `currentRateInfo` (last checkpoint). */
|
|
3245
|
+
ratePerSec: bigint | null;
|
|
3246
|
+
/** Same, but recomputed live by the Utilities lens — preferred. */
|
|
3247
|
+
liveRatePerSec: bigint | null;
|
|
3248
|
+
/** The WRAPPED market's supply rate per second, 1e18-scaled. */
|
|
3249
|
+
underlyingSupplyRatePerSec: bigint | null;
|
|
3250
|
+
/** `convertToAssets(1e18)` on the collateral vault — UNDERLYING per share.
|
|
3251
|
+
* ~1e15 for Curve Lend vaults, ~1e18 for Fraxlend pairs. */
|
|
3252
|
+
collateralPrice: bigint | null;
|
|
3253
|
+
/** Cached `1e36 / collateralPrice` from the pair (stale between writes). */
|
|
3254
|
+
exchangeRate: bigint | null;
|
|
3255
|
+
}
|
|
3256
|
+
interface ResupplyMarketsRaw {
|
|
3257
|
+
lender: string;
|
|
3258
|
+
config?: ResupplyConfigChain;
|
|
3259
|
+
pairs: ResupplyPairRaw[];
|
|
3260
|
+
}
|
|
3261
|
+
|
|
3262
|
+
/**
|
|
3263
|
+
* Fetch every Resupply market on a chain — FULLY ON-CHAIN, no API and no
|
|
3264
|
+
* published market roster.
|
|
3265
|
+
*
|
|
3266
|
+
* Discovery is `ResupplyRegistry.getAllPairAddresses()`. That is deliberate:
|
|
3267
|
+
* governance adds pairs (7 appeared between the docs' published list and
|
|
3268
|
+
* 2026-08) and retires them by zeroing `borrowLimit`, so a static file would
|
|
3269
|
+
* both miss new markets and advertise frozen ones as borrowable. The registry
|
|
3270
|
+
* is permissionless to read and is the same source the protocol's own
|
|
3271
|
+
* periphery uses.
|
|
3272
|
+
*
|
|
3273
|
+
* Three rounds cold, two warm:
|
|
3274
|
+
* 1. registry → pair addresses (intersected with `pairAllowlist` if set);
|
|
3275
|
+
* 2. identity (`name`/`collateral`/`underlying` + both tokens' decimals) for
|
|
3276
|
+
* pairs not already cached — immutable, so this is once per pair ever;
|
|
3277
|
+
* 3. state: terms, accounting, rates and the collateral vault's share price.
|
|
3278
|
+
*
|
|
3279
|
+
* The rate is read from the `Utilities` lens rather than `currentRateInfo`,
|
|
3280
|
+
* which is only a checkpoint from the last write — on a quiet pair that can be
|
|
3281
|
+
* hours stale, and the off-peg amplifier moves with the reUSD price. The
|
|
3282
|
+
* checkpoint is kept as a fallback.
|
|
3283
|
+
*/
|
|
3284
|
+
declare function fetchResupplyMarkets(lender: string, chainId: string): Promise<ResupplyMarketsRaw>;
|
|
3285
|
+
|
|
3286
|
+
/**
|
|
3287
|
+
* The external lending market a Resupply pair wraps.
|
|
3288
|
+
*
|
|
3289
|
+
* Every Resupply pair's collateral IS another lender's supply position, so a
|
|
3290
|
+
* position here carries that market's risk on top of Resupply's own. This
|
|
3291
|
+
* resolves the link where we can: the collateral vault is matched against the
|
|
3292
|
+
* LlamaLend roster by ADDRESS (LlamaLend indexes markets by Controller, so the
|
|
3293
|
+
* lookup goes through `llamaLendMarketByVault`).
|
|
3294
|
+
*
|
|
3295
|
+
* Verified 2026-08-04: 16 of the 21 registered pairs match a LlamaLend market
|
|
3296
|
+
* exactly, and the generation agrees independently — Resupply's own
|
|
3297
|
+
* `CurveLend:` names map to LlamaLend `version: 1` and `CurveLendV2:` to
|
|
3298
|
+
* `version: 2`. The other 5 are Fraxlend pairs, which we do not integrate as a
|
|
3299
|
+
* lender, so they resolve to `provider: 'fraxlend'` with no market key.
|
|
3300
|
+
*/
|
|
3301
|
+
interface ResupplyWrappedMarket {
|
|
3302
|
+
/** Which protocol the collateral position lives in. */
|
|
3303
|
+
provider: 'llamalend' | 'fraxlend' | 'unknown';
|
|
3304
|
+
/** The ERC-4626 the pair custodies — always known (it IS the collateral). */
|
|
3305
|
+
vault: string;
|
|
3306
|
+
/** `LLAMALEND_<CONTROLLER_ADDR>` when we integrate that market, else absent.
|
|
3307
|
+
* This is the key to look the wrapped market up in our own data. */
|
|
3308
|
+
lender?: string;
|
|
3309
|
+
/** LlamaLend Controller (the borrow surface of the wrapped market). */
|
|
3310
|
+
controller?: string;
|
|
3311
|
+
/** LlamaLend LLAMMA. Carried because a leverage route through Resupply must
|
|
3312
|
+
* never touch it — the wrapped Controller asserts its band state. */
|
|
3313
|
+
amm?: string;
|
|
3314
|
+
/** 1 = `oneway`, 2 = `oneway-v2`. Matches Resupply's CurveLend/CurveLendV2. */
|
|
3315
|
+
version?: 1 | 2;
|
|
3316
|
+
/** What the wrapped market lends against, e.g. `sfrxUSD`. */
|
|
3317
|
+
collateralSymbol?: string;
|
|
3318
|
+
}
|
|
3319
|
+
/**
|
|
3320
|
+
* Synthesized per-pair lender key, e.g. `RESUPPLY_1_C5184CCC…`. The chain id
|
|
3321
|
+
* rides in the key (Fluid/River/Frankencoin convention) even though Resupply
|
|
3322
|
+
* is Ethereum-only today.
|
|
3323
|
+
*/
|
|
3324
|
+
declare function resupplyLenderKey(lender: string, chainId: string | number, pair: string): string;
|
|
3325
|
+
/** Recover `{ lender, chainId, pair }` from a per-pair key. */
|
|
3326
|
+
declare function resupplyKeyParts(key: string): {
|
|
3327
|
+
lender: string;
|
|
3328
|
+
chainId: string;
|
|
3329
|
+
pair: string;
|
|
3330
|
+
} | undefined;
|
|
3331
|
+
/**
|
|
3332
|
+
* Map one Resupply deployment's on-chain batch into the shared
|
|
3333
|
+
* `MorphoGeneralPublicResponse` shape, keyed `RESUPPLY_<chainId>_<PAIR>`.
|
|
3334
|
+
*
|
|
3335
|
+
* Four modelling decisions worth knowing (all from RESUPPLY_PLAN.md):
|
|
3336
|
+
*
|
|
3337
|
+
* - **The collateral we publish is the UNDERLYING (crvUSD / frxUSD), not the
|
|
3338
|
+
* ERC-4626 share.** The share is an internal accounting unit that no token
|
|
3339
|
+
* list carries and no price feed covers, and both user-facing entry points
|
|
3340
|
+
* (`addCollateral` / `removeCollateral`) are denominated in the underlying.
|
|
3341
|
+
* Share amounts are converted with the vault's own
|
|
3342
|
+
* `convertToAssets(1e18)` — the exact number Resupply's oracle uses. NB
|
|
3343
|
+
* that price is ~**1e15** for Curve Lend vaults, so the share count is
|
|
3344
|
+
* ~1000x the underlying; a bare 1e18 divide is wrong by three orders of
|
|
3345
|
+
* magnitude.
|
|
3346
|
+
* - **The collateral carries the wrapped market's yield.** A Resupply deposit
|
|
3347
|
+
* is a Curve Lend / Fraxlend supply position, so `getUnderlyingSupplyRate`
|
|
3348
|
+
* is published as the collateral row's `intrinsicYield`. Without it the
|
|
3349
|
+
* position looks like it pays nothing, when in fact the whole product is
|
|
3350
|
+
* the spread between that and the ~half-of-it borrow rate.
|
|
3351
|
+
* - **`borrowLimit == 0` means PAUSED.** `pause()` zeroes it and there is no
|
|
3352
|
+
* `isPaused`; 9 of 21 pairs sat at zero at integration. Such a pair is
|
|
3353
|
+
* reported frozen and non-borrowable, but deposits/withdrawals stay open so
|
|
3354
|
+
* users can exit.
|
|
3355
|
+
* - **There is no supply side** — reUSD is minted — so `totalDeposits` on the
|
|
3356
|
+
* loan row is 0 and `depositRate` is 0. The earn leg is sreUSD, which
|
|
3357
|
+
* belongs to the savings provider.
|
|
3358
|
+
*/
|
|
3359
|
+
declare function convertResupplyMarketsToResponse(raw: ResupplyMarketsRaw, chainId: string, prices?: {
|
|
3360
|
+
[asset: string]: number;
|
|
3361
|
+
}, _additionalYields?: AdditionalYields, tokens?: GenericTokenList): {
|
|
3362
|
+
[m: string]: MorphoGeneralPublicResponse;
|
|
3363
|
+
};
|
|
3364
|
+
|
|
3365
|
+
/** Per-position Resupply detail attached to the debt row (raw strings). */
|
|
3366
|
+
interface ResupplyPositionInfo {
|
|
3367
|
+
/** Internal borrow shares. NOT an amount — see `debt` for reUSD units. */
|
|
3368
|
+
borrowShares: string;
|
|
3369
|
+
/** Collateral in VAULT SHARES (the pair's own accounting unit). */
|
|
3370
|
+
collateralShares: string;
|
|
3371
|
+
/** `convertToAssets(1e18)` on the collateral vault at read time — the
|
|
3372
|
+
* factor that turned those shares into the reported underlying. ~1e15 for
|
|
3373
|
+
* Curve Lend vaults. */
|
|
3374
|
+
collateralSharePrice: string;
|
|
3375
|
+
/** The pair contract — the market id and every write target. */
|
|
3376
|
+
pair: string;
|
|
3377
|
+
/** The collateral vault (Curve Lend / Fraxlend 4626 share token). */
|
|
3378
|
+
collateralVault: string;
|
|
3379
|
+
}
|
|
3380
|
+
|
|
3381
|
+
/** Test seam — drops the roster + discovery caches. */
|
|
3382
|
+
declare function __resetResupplyUserCaches(): void;
|
|
3383
|
+
|
|
3023
3384
|
/** Off-chain `Market.predictEscrow(user)`. */
|
|
3024
3385
|
declare function predictInverseEscrow(market: Address, escrowImplementation: Address, user: Address): Address;
|
|
3025
3386
|
|
|
@@ -3036,6 +3397,184 @@ interface InversePositionInfo {
|
|
|
3036
3397
|
dbrDeficit: string;
|
|
3037
3398
|
/** DBR signed balance (raw, may be negative). */
|
|
3038
3399
|
dbrSignedBalance: string;
|
|
3400
|
+
/** `DBR.debts(user)` (raw DOLA) — debt across ALL FiRM markets, which is
|
|
3401
|
+
* what burns DBR at 1 per DOLA-year. Chain-wide, repeated on every row. */
|
|
3402
|
+
dbrTotalDebt: string;
|
|
3403
|
+
/** Seconds until `dbrBalance` is exhausted at that burn ('0' if no debt). */
|
|
3404
|
+
dbrRunwaySeconds: string;
|
|
3405
|
+
/** Unix seconds of the projected depletion — past that point anyone can
|
|
3406
|
+
* force-replenish the account, charging the replenished DBR to its DOLA
|
|
3407
|
+
* debt at `replenishmentPriceBps`, and withdrawals freeze. Absent when
|
|
3408
|
+
* there is no debt. */
|
|
3409
|
+
dbrDepletionTimestamp?: string;
|
|
3410
|
+
}
|
|
3411
|
+
|
|
3412
|
+
/**
|
|
3413
|
+
* Per-market snapshot of a LlamaLend market. Amounts are HUMAN units (the
|
|
3414
|
+
* Curve API serves human numbers; the on-chain fallback normalizes to match).
|
|
3415
|
+
* Rates are DECIMALS (0.0391 = 3.91% APR), nominal — never the compounded
|
|
3416
|
+
* `borrowApy` the API also carries.
|
|
3417
|
+
*
|
|
3418
|
+
* `null` marks a value the active source could not provide; the converter
|
|
3419
|
+
* degrades per field rather than dropping the market.
|
|
3420
|
+
*/
|
|
3421
|
+
interface LlamaLendMarketRaw {
|
|
3422
|
+
market: LlamaLendMarketConfig;
|
|
3423
|
+
/** Controller.total_debt — borrowed-token units (human). */
|
|
3424
|
+
totalDebt: number | null;
|
|
3425
|
+
/** Vault.totalAssets — borrowed-token units (human). */
|
|
3426
|
+
totalSupplied: number | null;
|
|
3427
|
+
/**
|
|
3428
|
+
* Borrowable right now. v2: `Controller.available_balance()`. v1:
|
|
3429
|
+
* `borrowedToken.balanceOf(controller)`. This is also the withdrawal
|
|
3430
|
+
* ceiling for lenders — the vault cannot pay out what is lent.
|
|
3431
|
+
*/
|
|
3432
|
+
availableToBorrow: number | null;
|
|
3433
|
+
/** Nominal borrow APR as a decimal. */
|
|
3434
|
+
borrowApr: number | null;
|
|
3435
|
+
/** Nominal lend APR as a decimal. */
|
|
3436
|
+
lendApr: number | null;
|
|
3437
|
+
/** Collateral price in borrowed-token terms, from the AMM's EMA oracle. */
|
|
3438
|
+
collateralPrice: number | null;
|
|
3439
|
+
/** USD price of the collateral, API only (the chain read has no USD leg). */
|
|
3440
|
+
collateralPriceUsd: number | null;
|
|
3441
|
+
/** USD price of the borrowed token, API only. */
|
|
3442
|
+
borrowedPriceUsd: number | null;
|
|
3443
|
+
/**
|
|
3444
|
+
* Effective collateral factor at the market's `defaultBands`, derived from
|
|
3445
|
+
* `max_borrowable(1 unit, N)` divided by the oracle price.
|
|
3446
|
+
*
|
|
3447
|
+
* There is NO market-constant LTV in LlamaLend — the number moves with the
|
|
3448
|
+
* band count. Measured on sreUSD/crvUSD: 0.991 at N=4 down to 0.886 at
|
|
3449
|
+
* N=50. Reporting the N=4 maximum would flatter every risk comparison
|
|
3450
|
+
* against Aave/Morpho, so the default N is what gets reported and the rest
|
|
3451
|
+
* of the curve travels alongside in `bandLtv`.
|
|
3452
|
+
*/
|
|
3453
|
+
collateralFactor: number | null;
|
|
3454
|
+
/** `{ [N]: collateralFactor }` — the trade-off curve for the UI and sizer. */
|
|
3455
|
+
bandLtv: {
|
|
3456
|
+
[bands: string]: number;
|
|
3457
|
+
} | null;
|
|
3458
|
+
/**
|
|
3459
|
+
* v2 borrow cap in borrowed-token units (human). `0` DISABLES borrowing —
|
|
3460
|
+
* a fresh v2 market looks live but is not. `null` on v1 (uncapped).
|
|
3461
|
+
*/
|
|
3462
|
+
borrowCap: number | null;
|
|
3463
|
+
/** Whether new borrows are possible at all right now. */
|
|
3464
|
+
borrowingEnabled: boolean;
|
|
3465
|
+
/** Vault.maxDeposit — `0` disables deposits (v2 `max_supply`). */
|
|
3466
|
+
maxDeposit: number | null;
|
|
3467
|
+
/** Number of open loans, for the liquidations surface. */
|
|
3468
|
+
nLoans: number | null;
|
|
3469
|
+
/**
|
|
3470
|
+
* Soft-liquidation state of the market as a whole: the AMM's active band.
|
|
3471
|
+
* Not a per-user value, but it tells the UI whether the market is currently
|
|
3472
|
+
* converting anyone's collateral.
|
|
3473
|
+
*/
|
|
3474
|
+
activeBand: number | null;
|
|
3475
|
+
}
|
|
3476
|
+
/** Raw public-data batch for one LlamaLend chain (both generations together). */
|
|
3477
|
+
interface LlamaLendMarketsRaw {
|
|
3478
|
+
/** The bare lender key, `LLAMALEND`. */
|
|
3479
|
+
lender: string;
|
|
3480
|
+
config: LlamaLendConfigChain | undefined;
|
|
3481
|
+
chainData: LlamaLendChainData | undefined;
|
|
3482
|
+
markets: LlamaLendMarketRaw[];
|
|
3483
|
+
/** Which source filled the market rows. */
|
|
3484
|
+
source: 'api' | 'chain' | 'none';
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
declare function fetchLlamaLendMarkets(lender: string, chainId: string): Promise<LlamaLendMarketsRaw>;
|
|
3488
|
+
|
|
3489
|
+
/**
|
|
3490
|
+
* Synthesized per-market lender key, e.g.
|
|
3491
|
+
* `LLAMALEND_4F79FE450A2BAF833E8F50340BD230F5A3ECAFE9` (= the sreUSD/crvUSD
|
|
3492
|
+
* market). Keyed by the CONTROLLER, which is what every write and every user
|
|
3493
|
+
* read targets — the vault is a lookup off it. Address-suffixed
|
|
3494
|
+
* (Teller/Exactly/Inverse convention); the chain id is not part of the key
|
|
3495
|
+
* because chain scoping happens at the marketUid level.
|
|
3496
|
+
*
|
|
3497
|
+
* Both generations share this key space on purpose: to a user they are one
|
|
3498
|
+
* protocol, and the Curve API returns them in one list. The `version` field on
|
|
3499
|
+
* the market row is what encoders branch on.
|
|
3500
|
+
*/
|
|
3501
|
+
declare function llamaLendLenderKey(lender: string, controller: string): string;
|
|
3502
|
+
/** Recover `{ lender, controller }` from a per-market key (or undefined). */
|
|
3503
|
+
declare function llamaLendKeyParts(key: string): {
|
|
3504
|
+
lender: string;
|
|
3505
|
+
controller: string;
|
|
3506
|
+
} | undefined;
|
|
3507
|
+
/**
|
|
3508
|
+
* Map the LlamaLend batch into the shared `MorphoGeneralPublicResponse` shape,
|
|
3509
|
+
* keyed by `LLAMALEND_<CONTROLLER_ADDR>` — one key per market.
|
|
3510
|
+
*
|
|
3511
|
+
* Per market, two entries in the isolated-pair layout:
|
|
3512
|
+
*
|
|
3513
|
+
* - COLLATERAL entry — deposit-only. `collateralFactor` is the LTV AT THE
|
|
3514
|
+
* MARKET'S DEFAULT BAND COUNT, because LlamaLend has no market-constant
|
|
3515
|
+
* LTV: it is a function of `N` and moves 0.886..0.991 on a single market.
|
|
3516
|
+
* The whole curve rides along in `params.market.llamalend.bandLtv` so the
|
|
3517
|
+
* UI can show the trade-off and the leverage sizer can use the real number
|
|
3518
|
+
* for the `N` the user actually picks.
|
|
3519
|
+
* - LOAN entry — the borrowed token. Supply side is the ERC-4626 vault, so
|
|
3520
|
+
* unlike Inverse this one HAS `totalDeposits`.
|
|
3521
|
+
*
|
|
3522
|
+
* SOFT LIQUIDATION is the thing this shape cannot express natively, so it is
|
|
3523
|
+
* carried explicitly in the descriptor. `liquidationPenalty` here is the HARD
|
|
3524
|
+
* liquidation bonus only — it applies below the entire band range. Inside the
|
|
3525
|
+
* range a position is converted gradually through the market's own AMM with no
|
|
3526
|
+
* penalty at all, and a consumer that renders `liquidationPenalty` as "what
|
|
3527
|
+
* you lose when the price hits X" is describing the wrong event.
|
|
3528
|
+
*/
|
|
3529
|
+
declare function convertLlamaLendMarketsToResponse(raw: LlamaLendMarketsRaw, chainId: string, prices?: {
|
|
3530
|
+
[asset: string]: number;
|
|
3531
|
+
}, additionalYields?: AdditionalYields, tokens?: GenericTokenList): {
|
|
3532
|
+
[m: string]: MorphoGeneralPublicResponse;
|
|
3533
|
+
};
|
|
3534
|
+
|
|
3535
|
+
/**
|
|
3536
|
+
* Per-position LlamaLend detail attached to the debt row (raw strings unless
|
|
3537
|
+
* noted).
|
|
3538
|
+
*
|
|
3539
|
+
* The two fields a consumer must not ignore:
|
|
3540
|
+
*
|
|
3541
|
+
* - `softLiquidating` / `priceUpper` / `priceLower` — a LlamaLend position
|
|
3542
|
+
* does not have a liquidation price. It has a band RANGE, and it starts
|
|
3543
|
+
* converting collateral into the borrowed token as soon as the oracle
|
|
3544
|
+
* enters that range. Rendering a single number here misrepresents the
|
|
3545
|
+
* protocol.
|
|
3546
|
+
* - `bandCollateralInBorrowed` — the borrowed-token leg the LLAMMA has
|
|
3547
|
+
* already produced from the user's collateral. It sits inside the position,
|
|
3548
|
+
* offsets debt, and is NOT a wallet balance.
|
|
3549
|
+
*/
|
|
3550
|
+
interface LlamaLendPositionInfo {
|
|
3551
|
+
/** Signed health, WAD. `< 0` ⇒ hard-liquidatable. */
|
|
3552
|
+
health: string;
|
|
3553
|
+
/** Upper bound of the soft-liquidation band range, WAD. */
|
|
3554
|
+
priceUpper: string;
|
|
3555
|
+
/** Lower bound of the soft-liquidation band range, WAD. */
|
|
3556
|
+
priceLower: string;
|
|
3557
|
+
/** Band indices `[n1, n2]` the collateral currently occupies. */
|
|
3558
|
+
bands: [number, number] | undefined;
|
|
3559
|
+
/** Band count `N` chosen at loan creation — IMMUTABLE for the loan's life. */
|
|
3560
|
+
bandCount: number;
|
|
3561
|
+
/**
|
|
3562
|
+
* Borrowed-token amount held inside the user's bands (raw). Non-zero means
|
|
3563
|
+
* the position IS or HAS BEEN in soft liquidation.
|
|
3564
|
+
*/
|
|
3565
|
+
bandCollateralInBorrowed: string;
|
|
3566
|
+
/** True when the LLAMMA currently holds a borrowed-token leg for this user. */
|
|
3567
|
+
softLiquidating: boolean;
|
|
3568
|
+
/**
|
|
3569
|
+
* Whether the probed spender holds the Controller's boolean grant for this
|
|
3570
|
+
* market. FAILS CLOSED — older-blueprint controllers have no `approval`
|
|
3571
|
+
* method, the call fails, and this reads `false`, which is correct.
|
|
3572
|
+
*/
|
|
3573
|
+
delegated: boolean;
|
|
3574
|
+
/** Whether the market's Controller supports delegation at all. */
|
|
3575
|
+
supportsDelegation: boolean;
|
|
3576
|
+
/** Market generation — the leverage/encoder ABIs differ. */
|
|
3577
|
+
version: 1 | 2;
|
|
3039
3578
|
}
|
|
3040
3579
|
|
|
3041
3580
|
/**
|
|
@@ -3140,6 +3679,115 @@ interface UsddPositionInfo {
|
|
|
3140
3679
|
ilk: string;
|
|
3141
3680
|
}
|
|
3142
3681
|
|
|
3682
|
+
/**
|
|
3683
|
+
* One Frankencoin market (= one ORIGINAL position) after the on-chain batch.
|
|
3684
|
+
* Raw bigints; `null` = failed allowFailure read.
|
|
3685
|
+
*/
|
|
3686
|
+
interface FrankencoinMarketRaw {
|
|
3687
|
+
market: FrankencoinMarketConfig;
|
|
3688
|
+
/** Owner-declared liquidation price, 36-dec scaled vs collateral decimals. */
|
|
3689
|
+
price: bigint | null;
|
|
3690
|
+
/** FACE debt on the original itself (clones carry their own). */
|
|
3691
|
+
minted: bigint | null;
|
|
3692
|
+
/** ZCHF the original + its clones may still draw — market borrow capacity. */
|
|
3693
|
+
availableForClones: bigint | null;
|
|
3694
|
+
/** Collateral custodied by the ORIGINAL position contract. */
|
|
3695
|
+
collateralBalance: bigint | null;
|
|
3696
|
+
/** Hub lead rate + risk premium, ppm. */
|
|
3697
|
+
annualInterestPPM: bigint | null;
|
|
3698
|
+
/** Upfront fee for minting now (pro-rata to expiry), ppm. */
|
|
3699
|
+
currentFeePPM: bigint | null;
|
|
3700
|
+
/** Withheld into the equity reserve at mint, ppm. */
|
|
3701
|
+
reserveContribution: bigint | null;
|
|
3702
|
+
/** Non-zero while a Dutch-auction challenge is running. */
|
|
3703
|
+
challengedAmount: bigint | null;
|
|
3704
|
+
expiration: bigint | null;
|
|
3705
|
+
isClosed: boolean | null;
|
|
3706
|
+
}
|
|
3707
|
+
interface FrankencoinMarketsRaw {
|
|
3708
|
+
lender: string;
|
|
3709
|
+
config?: FrankencoinConfigChain;
|
|
3710
|
+
chainData?: FrankencoinChainData;
|
|
3711
|
+
markets: FrankencoinMarketRaw[];
|
|
3712
|
+
}
|
|
3713
|
+
|
|
3714
|
+
/**
|
|
3715
|
+
* Fetch all market data of ONE Frankencoin deployment — FULLY ON-CHAIN via
|
|
3716
|
+
* one retrying multicall over the curated ORIGINAL-position roster from
|
|
3717
|
+
* lender-metadata (`frankencoinConfig` / `frankencoinMarkets`, generated by
|
|
3718
|
+
* its `update:frankencoin` job, which filters to V2 + open + a priceable
|
|
3719
|
+
* collateral allowlist).
|
|
3720
|
+
*
|
|
3721
|
+
* Only originals are read here: they carry the terms AND the market-level
|
|
3722
|
+
* borrow capacity (`availableForClones`). Clones are USER positions and are
|
|
3723
|
+
* resolved per-account in the user-data path.
|
|
3724
|
+
*
|
|
3725
|
+
* NB `price` is the owner-DECLARED liquidation price, not an oracle quote —
|
|
3726
|
+
* see the converter for how that is surfaced.
|
|
3727
|
+
*/
|
|
3728
|
+
declare function fetchFrankencoinMarkets(lender: string, chainId: string): Promise<FrankencoinMarketsRaw>;
|
|
3729
|
+
|
|
3730
|
+
/**
|
|
3731
|
+
* Synthesized per-market lender key, e.g.
|
|
3732
|
+
* `FRANKENCOIN_1_5F2C10F7…` — one per ORIGINAL position. The chain id is part
|
|
3733
|
+
* of the key (Fluid/River convention) even though Frankencoin is
|
|
3734
|
+
* Ethereum-only today, so an L2 hub would not collide.
|
|
3735
|
+
*/
|
|
3736
|
+
declare function frankencoinLenderKey(lender: string, chainId: string | number, position: string): string;
|
|
3737
|
+
/** Recover `{ lender, chainId, position }` from a per-market key. */
|
|
3738
|
+
declare function frankencoinKeyParts(key: string): {
|
|
3739
|
+
lender: string;
|
|
3740
|
+
chainId: string;
|
|
3741
|
+
position: string;
|
|
3742
|
+
} | undefined;
|
|
3743
|
+
/**
|
|
3744
|
+
* Map one Frankencoin deployment's on-chain batch into the shared
|
|
3745
|
+
* `MorphoGeneralPublicResponse` shape, keyed `FRANKENCOIN_<chainId>_<ORIGINAL>`.
|
|
3746
|
+
*
|
|
3747
|
+
* Three modelling decisions worth knowing (all from FRANKENCOIN_PLAN.md):
|
|
3748
|
+
*
|
|
3749
|
+
* - **The liquidation price is owner-DECLARED, not an oracle.** `price` is
|
|
3750
|
+
* 36-dec scaled against the collateral's decimals and is policed by a
|
|
3751
|
+
* Dutch-auction challenge game. We surface it as the LIQUIDATION price
|
|
3752
|
+
* (it defines `collateralFactor = 1`, i.e. minting is allowed up to
|
|
3753
|
+
* `coll × price`) but value collateral with OUR price feeds. The
|
|
3754
|
+
* divergence between the two is the risk signal, and it is carried
|
|
3755
|
+
* verbatim in `params.market.frankencoin.declaredPrice` so a consumer can
|
|
3756
|
+
* compute it. Never present the resulting health as a protocol invariant.
|
|
3757
|
+
* - **Debt ≠ proceeds.** `minted` is FACE debt including the withheld
|
|
3758
|
+
* `reserveContribution` (10–40 %) plus the upfront pro-rata fee. Both
|
|
3759
|
+
* ppm figures ride along in the descriptor so a quote layer can convert.
|
|
3760
|
+
* - **Positions expire.** `expiration` is surfaced and an expired market is
|
|
3761
|
+
* reported halted (its collateral is subject to forced sale).
|
|
3762
|
+
*
|
|
3763
|
+
* Per market: a COLLATERAL entry (the original's own collateral) and a LOAN
|
|
3764
|
+
* entry (ZCHF). There is no protocol supply side — ZCHF is minted, and the
|
|
3765
|
+
* earn leg is the separate savings module carried by the savings provider —
|
|
3766
|
+
* so `totalDeposits` on the loan row is 0.
|
|
3767
|
+
*/
|
|
3768
|
+
declare function convertFrankencoinMarketsToResponse(raw: FrankencoinMarketsRaw, chainId: string, prices?: {
|
|
3769
|
+
[asset: string]: number;
|
|
3770
|
+
}, _additionalYields?: AdditionalYields, tokens?: GenericTokenList): {
|
|
3771
|
+
[m: string]: MorphoGeneralPublicResponse;
|
|
3772
|
+
};
|
|
3773
|
+
|
|
3774
|
+
/** Per-position detail attached to the debt row (raw strings). */
|
|
3775
|
+
interface FrankencoinPositionInfo {
|
|
3776
|
+
/** The position contract — the sub-account id and every write op's target. */
|
|
3777
|
+
position: string;
|
|
3778
|
+
/** The ORIGINAL this position was cloned from (its market). */
|
|
3779
|
+
original: string;
|
|
3780
|
+
/** Owner-declared liquidation price (raw, 36-dec scaled). */
|
|
3781
|
+
declaredPrice: string;
|
|
3782
|
+
/** Unix seconds; a position past this is subject to forced sale. */
|
|
3783
|
+
expiration: string;
|
|
3784
|
+
/** Non-zero while a Dutch-auction challenge is running against it. */
|
|
3785
|
+
challengedAmount: string;
|
|
3786
|
+
/** ppm withheld into the equity reserve — needed to quote a close, since
|
|
3787
|
+
* repaying burns with reserve credit and costs LESS than `minted`. */
|
|
3788
|
+
reserveContributionPPM: string;
|
|
3789
|
+
}
|
|
3790
|
+
|
|
3143
3791
|
/**
|
|
3144
3792
|
* Raw on-chain read for ONE Teller `LenderCommitmentGroup` pool. All amounts are
|
|
3145
3793
|
* raw token base units; `minRateBps` is the pool's min borrow APR in BASIS
|
|
@@ -7618,8 +8266,18 @@ declare function parseRawRpcBatchResponses(batches: RawRpcBatch[], batchResponse
|
|
|
7618
8266
|
* Parses multicall3 aggregate3 responses
|
|
7619
8267
|
* The response contains an array of {success, returnData} tuples
|
|
7620
8268
|
* Each returnData needs to be decoded using the original call's ABI
|
|
8269
|
+
*
|
|
8270
|
+
* `permanentFailures`, when supplied, is filled with the indices of calls that
|
|
8271
|
+
* failed DETERMINISTICALLY. This path can tell them apart with certainty, which
|
|
8272
|
+
* the viem path can only infer: if the batch response itself came back, the
|
|
8273
|
+
* transport worked, so a `success: false` entry inside it is a revert — the
|
|
8274
|
+
* chain's answer, not a lost read. Only a batch-level error is a lost read.
|
|
8275
|
+
*
|
|
8276
|
+
* The distinction matters downstream: a cross-margin lender voids its whole set
|
|
8277
|
+
* on a lost read, and without this a single always-reverting market would void
|
|
8278
|
+
* a perfectly good position on every request.
|
|
7621
8279
|
*/
|
|
7622
|
-
declare function parseMulticallRpcResponses(responses: RawRpcResponse[], batches: MulticallRpcBatch[], allowFailure?: boolean): any[];
|
|
8280
|
+
declare function parseMulticallRpcResponses(responses: RawRpcResponse[], batches: MulticallRpcBatch[], allowFailure?: boolean, permanentFailures?: Set<number>): any[];
|
|
7623
8281
|
|
|
7624
8282
|
type TokenEntry = {
|
|
7625
8283
|
chainId: string;
|
|
@@ -7712,4 +8370,1058 @@ interface FetchTokenBalancesOptions {
|
|
|
7712
8370
|
*/
|
|
7713
8371
|
declare function fetchTokenBalances(chainId: string, account: string, tokens: string[], options?: FetchTokenBalancesOptions): Promise<TokenBalanceResult>;
|
|
7714
8372
|
|
|
7715
|
-
export { type AaveMetadata, type AaveV2Public, type AaveV2UserReserveResponse, type AaveV3Public, type AaveV3UserReserveResponse, type AdditionalYields, ApiBookSource, type AprData, type BalanceData, type BaseLendingPosition, type BasicReserveResponse, type ChainDiagnostic, type ChainLinkResponse, type ChainQuery, type ChainSummary, type CompoundV2Metadata, type CompoundV3Public, type CompoundV3UserReserveResponse, type ConfigEntry, type CoreValidators, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, type Denomination, type DepthMap, EMPTY_BALANCE, type EModeAssets, type EModeData, type EModeResult, EXACTLY_LENDER_KEY, type EulerEarnVault, type EulerEarnVaults, type EulerV2Metadata, type ExactlyFixedPool, type ExactlyFixedPosition, type ExactlyMarketAccount, type ExactlyMarketsRaw, type ExactlyUserFixedPosition, type ExtraValidationCall, type FeedObservation, type FeedStat, type FeedStatsMap, type FeedTimestampMap, type FetchListaVaultsFromChainOptions, type FetchMorphoVaultsFromChainOptions, type FetchOraclePricesOptions, type FetchTokenBalancesOptions, type FlattenPriorityConfig, type FluidFToken, type FluidFTokens, type FullLenderRewardsMap, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, type GenericCurrency, type GenericTokenList, type GetVaultPublicDataAllOptions, type GmxExecutionFees, type GmxPendingDeposit, type GmxPendingWithdrawal, type GmxReadContracts, type GmxUserBalance, type GmxUserPositions, type GmxUserPositionsOptions, type GmxVault, type GmxVaultKind, type GmxVaults, type GmxVaultsFetchOptions, type GroupAccumulator, HYPERCORE_VAULT_REGISTRY, type HypercoreLockStatus, type HypercoreUserPositionsOptions, type HypercoreVault, type HypercoreVaultPosition, type HypercoreVaultRegistryEntry, type HypercoreVaults, type HypercoreVaultsFetchOptions, IDLE_MARKET_ID, INTERFACE_IDS, type InitMetadata, type InitPublic, type InitUserReserveResponse, type InterfaceKind, type InverseMarketRaw, type InverseMarketsRaw, type InversePositionInfo, LAGOON_API_URL, LAGOON_CHAIN_IDS, type LagoonApiVault, type LagoonSyncMode, type LagoonVault, type LagoonVaults, type LenderConfigData, type LenderConfigMap, type LenderCrossPoolMeta, type LenderData, type LenderDataEntry, type LenderInfo, type LenderInfoMap, type LenderPublicBase, type LenderRewardsMap, type LenderSummary, type LenderToLenderCrossPoolMeta, type LenderTotalAmounts, type LenderUserQuery, type LenderUserResponse, type LenderYieldComplete, type LenderYields$1 as LenderYields, LendingMode, type LiquityBranchRaw, type LiquityDiscoveredTrove, type LiquityDiscovery, type LiquityMarketsRaw, type LiquitySpInfo, type LiquityTroveInfo, type ListaMarketOverrides, type LoopPostTradeMetrics, type LstDelegation, type LstDelegationKind, type LstValidator, type LstWithdrawalFetchOptions, type LstWithdrawalRegistryEntry, type LstWithdrawalRequest, type LstWithdrawalRequestsByLst, type LstWithdrawalStatus, MORPHO_LENS, MaxParamThresholds, type MergedUserData, type MidnightBook, type MidnightBookLevel, type MidnightBookSource, type ModeBase, type MorphoMarketOverrides, type MorphoSubgraphProxyConfig, type MorphoUserMarketBalance, type MorphoUserReserveResponse, type MorphoVault, type MorphoVaults, type MulticallRpcBatch, type NumberMap, type OracleDiagnostics, type OraclePriceEntry, type OraclePricesResult, type OutlierGuardConfig, type ParsedBalanceData, type ParsedResponse, type ParsedUserBalance, type PermissionParams, type PoolData, type PoolWithMeta, type PortfolioSummary, type PortfolioTotals, type PostTradeMetrics, type PreparedCall, type PreparedMergedMulticallParams, type PreparedMergedRpcCalls, type PreparedTokenBalanceRpcCalls, type PreparedUserDataRpcCalls, type PriceDerivation, type PriceSelection, type ProtocolParams, type ProviderOptions, type RawRpcBatch, type RawRpcCall, type RawRpcResponse, type RiverMarketRaw, type RiverMarketsRaw, type RiverPositionInfo, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, type SelectPricesOptions, type SiloVault, type SiloVaults, type StCeloValidatorGroup, type StaleFeedEntry, type StructuredOraclePrices, type SubAccountSummary, type SumerPositionInput, type SummaryAprData, type SummaryBalanceData, TELLER_CALLS_PER_BID, TERMMAX_CALLS_PER_ACCOUNT, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, type TellerDiscoveredBid, type TellerDiscovery, type TellerMarketsRaw, type TellerPoolRaw, type TermAuctionOrder, type TermAuctionOrders, type TermBookSource, type TermBookTop, type TermListing, type TermMarketRaw, TermMaxApiSource, type TermMaxBookTop, type TermMaxCurveSegment, type TermMaxDataSource, type TermMaxDiscovery, type TermMaxFeeConfig, type TermMaxMarketConfig, type TermMaxMarketRaw, type TermMaxOrderState, TermSubgraphSource, type TokenApprovalMeta, type TokenApprovalParams, type TokenBalanceEntry, type TokenBalanceQuery, type TokenBalanceResult, type TokenEntry, type TokenList, type TokenListInput, type TrackerDiagnostic, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, type USDPriceMap, type UpshiftApiAsset, type UpshiftApiVault, type UpshiftVault, type UpshiftVaults, type UsddMarketRaw, type UsddMarketsRaw, type UsddPositionInfo, type UserApr, type UserConfig, type UserData, type UserDataResult, type UserLendingPosition, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, type VaultAprResult, type VaultClassification, type VaultClassificationFields, type VaultLookupEntry, type VaultMarketExposure, type VaultProvider, type VaultPublicDataAll, type VaultPublicDataResult, type VaultYieldSeries, type VaultYieldSnapshot, type YDaemonVault, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, type YearnVault, type YearnVaultKind, type YearnVaults, type YieldProfile, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, collectFeedObservations, computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta, computeZapTradeDeltas, consensusReference, convertExactlyMarketsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, detectInterfaceKinds, encodeBalanceFetcherCalldata, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feedKeyOf, feedStatKey, fetchDolomiteAccountNumbers, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendlePrices, fetchRiverMarkets, fetchSiloVaults, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getResolvedDolomiteAccountNumbers, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getVaultPublicDataAll, getVaultWithdrawalRequests, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasUpshiftVaults, hasYearnVaults, inverseKeyParts, inverseLenderKey, isStablecoinSymbol, isYearnV3, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTermMaxLtv, parseTokenBalanceResult, positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveDerivation, resolveStCeloDepositGroup, riverKeyParts, riverLenderKey, selectAssetGroupPrices, stampVaultClassification, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, tickToAprNumber, tickToPrice, unflattenLenderData, updateFeedStats, usddIlkBytes32, usddKeyParts, usddLenderKey };
|
|
8373
|
+
/**
|
|
8374
|
+
* Term sheets — a structured, per-`marketUid` description of every lend and
|
|
8375
|
+
* borrow offer we serve.
|
|
8376
|
+
*
|
|
8377
|
+
* One shape for pool lenders, fixed-term lenders, CDPs and vaults, so an
|
|
8378
|
+
* integrator reads ONE object instead of ~15 protocol-specific fields plus a
|
|
8379
|
+
* per-lender mental model. See [TERM_SHEET_PLAN.md](../../../../TERM_SHEET_PLAN.md)
|
|
8380
|
+
* for the design rationale and the per-lender coverage matrix.
|
|
8381
|
+
*
|
|
8382
|
+
* ## Conventions that hold everywhere in this file
|
|
8383
|
+
*
|
|
8384
|
+
* - **Rates are nominal APR in PERCENT** (`3.85` = 3.85 %/yr), never a
|
|
8385
|
+
* fraction and never an APY. This is the package-wide convention.
|
|
8386
|
+
* - **Factors are fractions** (`0.85` = 85 % LTV) — matching `LenderConfigData`.
|
|
8387
|
+
* - **Durations are SECONDS**, timestamps are **unix seconds**.
|
|
8388
|
+
* - **Raw amounts are decimal strings** in base units; human amounts are
|
|
8389
|
+
* `number`.
|
|
8390
|
+
* - Every string union is deliberately OPEN (`| (string & {})`) so a new
|
|
8391
|
+
* lender can introduce a member without breaking a consumer's exhaustive
|
|
8392
|
+
* switch. Consumers MUST have a `default` branch and fall back to
|
|
8393
|
+
* `info.headline`.
|
|
8394
|
+
*/
|
|
8395
|
+
/** Nominal APR in percent (`3.85` = 3.85 %/yr). Never a fraction, never APY. */
|
|
8396
|
+
type AprPercent = number;
|
|
8397
|
+
/**
|
|
8398
|
+
* Open-enum helper. `Open<'a' | 'b'>` keeps autocomplete for the known members
|
|
8399
|
+
* while still accepting any string, so adding a member later is an ADDITIVE
|
|
8400
|
+
* change rather than a breaking one.
|
|
8401
|
+
*/
|
|
8402
|
+
type Open<T extends string> = T | (string & {});
|
|
8403
|
+
/** Compact token reference — enough to render without a second lookup. */
|
|
8404
|
+
interface TermAssetRef {
|
|
8405
|
+
chainId: string;
|
|
8406
|
+
/** Lowercased contract address. */
|
|
8407
|
+
address: string;
|
|
8408
|
+
symbol?: string;
|
|
8409
|
+
name?: string;
|
|
8410
|
+
decimals?: number;
|
|
8411
|
+
assetGroup?: string;
|
|
8412
|
+
logoURI?: string;
|
|
8413
|
+
}
|
|
8414
|
+
/**
|
|
8415
|
+
* Machine tags for filtering/faceting. DERIVED from the structured fields in
|
|
8416
|
+
* `tags.ts` — never hand-written per lender, so they cannot drift from the
|
|
8417
|
+
* numbers they summarize.
|
|
8418
|
+
*/
|
|
8419
|
+
type TermTag = Open<'fixed-rate' | 'variable-rate' | 'user-set-rate' | 'zero-interest' | 'prepaid-interest' | 'nav-accrual' | 'has-maturity' | 'perpetual' | 'rolling-duration' | 'static-debt' | 'accruing-debt' | 'time-liquidation' | 'price-liquidation' | 'redeemable' | 'no-liquidation' | 'full-collateral-seizure' | 'early-exit-free' | 'early-exit-penalty' | 'early-exit-discount' | 'exit-instant' | 'exit-capped' | 'exit-cooldown' | 'exit-queued' | 'exit-market-sale' | 'exit-may-be-impossible' | 'permissioned' | 'capped' | 'cap-full' | 'first-loss' | 'socialized-loss' | 'physical-delivery' | 'undercollateralized' | 'nav-attested' | 'immutable' | 'no-timelock' | 'eoa-controlled' | 'points-rewards' | 'oracle-flagged' | 'no-oracle'>;
|
|
8420
|
+
/** Human-facing copy for one side of a term sheet. */
|
|
8421
|
+
interface TermInfo {
|
|
8422
|
+
/**
|
|
8423
|
+
* ≤ ~100 chars, templated from live numbers, ready to render.
|
|
8424
|
+
* `"Fixed 4.12 % until 3 Sep 2026 · repay any time at face value"`.
|
|
8425
|
+
*
|
|
8426
|
+
* ALWAYS populated — it is the graceful-degradation path for a consumer
|
|
8427
|
+
* that does not recognise a newer enum member.
|
|
8428
|
+
*/
|
|
8429
|
+
headline: string;
|
|
8430
|
+
/** 1–3 sentences. Invariant prose lives on the profile; this interpolates
|
|
8431
|
+
* the market's own values. */
|
|
8432
|
+
description: string;
|
|
8433
|
+
/** Ready-to-display consequences, most important first. */
|
|
8434
|
+
implications?: string[];
|
|
8435
|
+
tags: TermTag[];
|
|
8436
|
+
}
|
|
8437
|
+
type RateKind = Open<
|
|
8438
|
+
/** Utilization IRM (Aave, Compound, Morpho, Silo, Euler, Fluid…). */
|
|
8439
|
+
'variable-curve'
|
|
8440
|
+
/** Governance-set with no curve (USDD stability fee, Spark `vsr`). */
|
|
8441
|
+
| 'variable-managed'
|
|
8442
|
+
/** Borrower picks the rate (Liquity family). */
|
|
8443
|
+
| 'user-set'
|
|
8444
|
+
/** Locked for a maturity (Exactly, Midnight, Term, TermMax, Teller, Lista). */
|
|
8445
|
+
| 'fixed-term'
|
|
8446
|
+
/** Locked, no maturity. Reserved — nothing uses it today. */
|
|
8447
|
+
| 'fixed-open'
|
|
8448
|
+
/** No ongoing rate at all (River); cost is a one-off fee. */
|
|
8449
|
+
| 'zero-interest'
|
|
8450
|
+
/** Interest prepaid in a separate token (Inverse DBR). */
|
|
8451
|
+
| 'prepaid'
|
|
8452
|
+
/** Share price tracks an attested NAV (Re, Apyx, USPC). */
|
|
8453
|
+
| 'nav-accrual'
|
|
8454
|
+
/** Pure collateral leg — no yield. */
|
|
8455
|
+
| 'none'>;
|
|
8456
|
+
/** One reward program. Identity matters: points are not a bankable APR. */
|
|
8457
|
+
interface RewardTerm {
|
|
8458
|
+
/** Absent for points programs — that absence IS the signal. */
|
|
8459
|
+
asset?: TermAssetRef;
|
|
8460
|
+
kind: Open<'token' | 'points' | 'unknown'>;
|
|
8461
|
+
apr: AprPercent;
|
|
8462
|
+
side: 'supply' | 'borrow';
|
|
8463
|
+
/** How it is realized — decides whether the APR is actually bankable. */
|
|
8464
|
+
claim: Open<'accrual' | 'merkl' | 'manual' | 'none'>;
|
|
8465
|
+
/** Program end, where known. An APR with two weeks left is not an APR. */
|
|
8466
|
+
endsAt?: number;
|
|
8467
|
+
/**
|
|
8468
|
+
* `true` ⇒ not priceable (points). MUST be shown separately and is
|
|
8469
|
+
* deliberately EXCLUDED from `RateTerms.aprTotal`.
|
|
8470
|
+
*/
|
|
8471
|
+
indicative?: boolean;
|
|
8472
|
+
}
|
|
8473
|
+
/** One entry in a fixed-term rate menu. Mirrors `MarketTermEntry`. */
|
|
8474
|
+
interface RateMenuEntry {
|
|
8475
|
+
/** LENDER-SPECIFIC: Exactly/TermMax = unix maturity, Teller = duration
|
|
8476
|
+
* seconds, Lista = broker product id, Midnight/Term = `0`. */
|
|
8477
|
+
termId: number;
|
|
8478
|
+
durationSecs: number;
|
|
8479
|
+
durationDays: number;
|
|
8480
|
+
/** Borrow APR at this term. */
|
|
8481
|
+
apr: AprPercent;
|
|
8482
|
+
/** Lend APR at this term, where the lender quotes both sides. */
|
|
8483
|
+
depositApr?: AprPercent;
|
|
8484
|
+
/** Borrowable liquidity at this term, human units. */
|
|
8485
|
+
available?: number;
|
|
8486
|
+
}
|
|
8487
|
+
interface RateTerms {
|
|
8488
|
+
kind: RateKind;
|
|
8489
|
+
/** Base rate only — no rewards, no intrinsic yield. */
|
|
8490
|
+
apr: AprPercent;
|
|
8491
|
+
components: {
|
|
8492
|
+
base: AprPercent;
|
|
8493
|
+
/** Priceable rewards only. */
|
|
8494
|
+
rewards?: AprPercent;
|
|
8495
|
+
/** Underlying/LST yield the asset earns by itself. */
|
|
8496
|
+
intrinsic?: AprPercent;
|
|
8497
|
+
};
|
|
8498
|
+
/** `base + priceable rewards + intrinsic` — the headline number. */
|
|
8499
|
+
aprTotal: AprPercent;
|
|
8500
|
+
/** Carried explicitly even though it has one value today: a silent
|
|
8501
|
+
* APR→APY change would be the classic undetectable break. */
|
|
8502
|
+
basis: 'apr-nominal';
|
|
8503
|
+
compounding: Open<'per-second' | 'per-block' | 'none' | 'unknown'>;
|
|
8504
|
+
source: Open<'utilization-curve' | 'orderbook' | 'auction' | 'governance' | 'borrower' | 'oracle' | 'api' | 'derived'>;
|
|
8505
|
+
/** Is the rate locked for the life of the position? */
|
|
8506
|
+
isLocked: boolean;
|
|
8507
|
+
/** Protocol-enforced bounds (Liquity min/max, Morpho rateCap/rateFloor). */
|
|
8508
|
+
minApr?: AprPercent;
|
|
8509
|
+
maxApr?: AprPercent;
|
|
8510
|
+
/** Per-program reward detail — token identity, claim path, end date. */
|
|
8511
|
+
rewards?: RewardTerm[];
|
|
8512
|
+
/** Rate menu when the market offers several terms at once. */
|
|
8513
|
+
menu?: RateMenuEntry[];
|
|
8514
|
+
/** Size the quote is valid for, when the rate is depth-dependent. */
|
|
8515
|
+
quote?: {
|
|
8516
|
+
assets: number;
|
|
8517
|
+
basis: Open<'marginal' | 'average'>;
|
|
8518
|
+
};
|
|
8519
|
+
lastChangedAt?: number;
|
|
8520
|
+
}
|
|
8521
|
+
interface MaturityTerms {
|
|
8522
|
+
kind: Open<'perpetual' | 'fixed-date' | 'rolling-duration'>;
|
|
8523
|
+
/** unix seconds; `kind: 'fixed-date'`. */
|
|
8524
|
+
maturity?: number;
|
|
8525
|
+
/** ISO-8601 mirror so consumers need not re-format. */
|
|
8526
|
+
maturityIso?: string;
|
|
8527
|
+
/** Snapshot — derive live from `maturity` for a countdown. */
|
|
8528
|
+
secondsToMaturity?: number;
|
|
8529
|
+
/** `kind: 'rolling-duration'` (Teller, Lista broker). */
|
|
8530
|
+
minDurationSecs?: number;
|
|
8531
|
+
maxDurationSecs?: number;
|
|
8532
|
+
/**
|
|
8533
|
+
* What happens at/after maturity if NOBODY acts. The field that most
|
|
8534
|
+
* surprises users — outcomes range from "interest simply stops" to
|
|
8535
|
+
* "liquidated within five minutes, losing all collateral".
|
|
8536
|
+
*/
|
|
8537
|
+
atMaturity?: Open<'stops-earning' | 'penalty-accrues' | 'liquidatable' | 'default-seizure' | 'physical-delivery' | 'refinanced' | 'auto-roll' | 'none'>;
|
|
8538
|
+
/** Grace window before `atMaturity` bites (Teller ~300 s, TermMax 7200 s). */
|
|
8539
|
+
graceSecs?: number;
|
|
8540
|
+
}
|
|
8541
|
+
type FeeWhen = Open<'entry' | 'ongoing' | 'exit' | 'late' | 'liquidation' | 'performance'>;
|
|
8542
|
+
/**
|
|
8543
|
+
* One charge, in a shape general enough that a NEW fee is data rather than a
|
|
8544
|
+
* schema change. Replaces the current scatter: `originationFee`,
|
|
8545
|
+
* `withdrawFeeBps`, `rates.fee`, `fixedTerm.fees.*`, `river.mintFeeRate`,
|
|
8546
|
+
* `liquity.gasCompensation`.
|
|
8547
|
+
*/
|
|
8548
|
+
interface FeeTerm {
|
|
8549
|
+
/** Stable slug — the join key for UI copy and filtering. */
|
|
8550
|
+
id: Open<'origination' | 'late-penalty' | 'early-repay-penalty' | 'early-repay-discount' | 'continuous' | 'settlement' | 'instant-exit' | 'performance' | 'reserve-factor' | 'gas-compensation' | 'redemption' | 'claim' | 'liquidation-bonus'>;
|
|
8551
|
+
/** Human label — lets an unknown `id` still render correctly. */
|
|
8552
|
+
label: string;
|
|
8553
|
+
when: FeeWhen;
|
|
8554
|
+
unit: Open<'apr-percent' | 'percent' | 'bps' | 'absolute'>;
|
|
8555
|
+
basis: Open<'principal' | 'face-value' | 'yield' | 'collateral' | 'shares' | 'debt-repaid'>;
|
|
8556
|
+
/**
|
|
8557
|
+
* A NEGATIVE value is legal and means a REBATE (Exactly's early-repay
|
|
8558
|
+
* discount). Sign is load-bearing — never take an absolute value.
|
|
8559
|
+
*/
|
|
8560
|
+
value: number;
|
|
8561
|
+
payee?: Open<'protocol' | 'lenders' | 'liquidator' | 'curator' | 'gas-refund'>;
|
|
8562
|
+
/** Governance-mutable ⇒ this is a snapshot; re-verify before quoting. */
|
|
8563
|
+
mutable?: boolean;
|
|
8564
|
+
/** Only resolvable at action time (Exactly discount, TermMax curve price). */
|
|
8565
|
+
indicative?: boolean;
|
|
8566
|
+
/** Decaying/scheduled fees (Apyx: 3.40 % → 0 over 20 days). */
|
|
8567
|
+
schedule?: {
|
|
8568
|
+
afterSecs: number;
|
|
8569
|
+
value: number;
|
|
8570
|
+
}[];
|
|
8571
|
+
description?: string;
|
|
8572
|
+
}
|
|
8573
|
+
/** Superset of `SavingsWithdrawalMode` + `LstWithdrawalMode`, plus the two
|
|
8574
|
+
* lending-side exits neither covers. */
|
|
8575
|
+
type SupplyExitMode = Open<'instant' | 'instant-capped' | 'instant-or-queued' | 'fee-or-queued' | 'fixed-cooldown' | 'queued' | 'request-based'
|
|
8576
|
+
/** Sell the instrument on a book (Term, TermMax, Midnight). */
|
|
8577
|
+
| 'market-sale'
|
|
8578
|
+
/** No early exit at all. */
|
|
8579
|
+
| 'at-maturity' | 'off-chain' | 'dex-only'>;
|
|
8580
|
+
interface SupplyExitTerms {
|
|
8581
|
+
mode: SupplyExitMode;
|
|
8582
|
+
/** Coarse alias — identical semantics to `VaultClassificationFields.redemptionType`. */
|
|
8583
|
+
settlement: Open<'sync' | 'async'>;
|
|
8584
|
+
cooldownSecs?: number;
|
|
8585
|
+
/** Claim-window constraints (Apyx: blocked 3 d, free at 20 d). */
|
|
8586
|
+
claimWindow?: {
|
|
8587
|
+
earliestSecs?: number;
|
|
8588
|
+
freeAfterSecs?: number;
|
|
8589
|
+
};
|
|
8590
|
+
/** What can actually leave right now. */
|
|
8591
|
+
liquidity?: {
|
|
8592
|
+
assets: number;
|
|
8593
|
+
assetsUsd?: number;
|
|
8594
|
+
ratio?: number;
|
|
8595
|
+
};
|
|
8596
|
+
partialAllowed: boolean;
|
|
8597
|
+
/**
|
|
8598
|
+
* Does exiting early cost an UNKNOWN amount?
|
|
8599
|
+
* `none` par · `haircut-formula` deterministic discount ·
|
|
8600
|
+
* `market-price` you sell into a book · `may-be-impossible` the book can be
|
|
8601
|
+
* empty.
|
|
8602
|
+
*/
|
|
8603
|
+
priceRisk: Open<'none' | 'haircut-formula' | 'market-price' | 'may-be-impossible'>;
|
|
8604
|
+
cancellable?: boolean;
|
|
8605
|
+
/** The `when: 'exit' | 'performance'` subset of the side's fees. */
|
|
8606
|
+
fees: FeeTerm[];
|
|
8607
|
+
}
|
|
8608
|
+
interface BorrowExitTerms {
|
|
8609
|
+
/** Three signs exist across our lenders: `discount` is a REBATE (Exactly). */
|
|
8610
|
+
earlyRepay: Open<'free' | 'discount' | 'penalty' | 'market-price' | 'not-allowed'>;
|
|
8611
|
+
atMaturityCost: Open<'face' | 'accrued'>;
|
|
8612
|
+
lateBehaviour: Open<'penalty-accrues' | 'liquidatable' | 'default-seizure' | 'refinanced' | 'none'>;
|
|
8613
|
+
partialAllowed: boolean;
|
|
8614
|
+
/** Dust floor — Liquity `minDebt`, Morpho/Lista `minLoan`. Raw base units. */
|
|
8615
|
+
minDebt?: string;
|
|
8616
|
+
/** Over-repay REVERTS (Midnight `uint128` underflow) — a real footgun. */
|
|
8617
|
+
overRepayReverts?: boolean;
|
|
8618
|
+
fees: FeeTerm[];
|
|
8619
|
+
}
|
|
8620
|
+
interface LiquidationTerms {
|
|
8621
|
+
trigger: Open<'price' | 'time' | 'price-and-time' | 'redemption' | 'none'>;
|
|
8622
|
+
/** Max LTV at open. */
|
|
8623
|
+
ltv?: number;
|
|
8624
|
+
/** Threshold at which liquidation becomes possible. */
|
|
8625
|
+
liquidationLtv?: number;
|
|
8626
|
+
/** Fraction of repaid debt paid to the liquidator on top of par. */
|
|
8627
|
+
penalty: number;
|
|
8628
|
+
closeFactor: number;
|
|
8629
|
+
targetHealthFactor?: number;
|
|
8630
|
+
/**
|
|
8631
|
+
* `full-collateral` is the Teller case: the liquidator takes the ENTIRE
|
|
8632
|
+
* escrow, not a proportional slice — ~2× the debt at 50 % LTV.
|
|
8633
|
+
*/
|
|
8634
|
+
seizure: Open<'proportional' | 'full-collateral'>;
|
|
8635
|
+
/** Liquity/River: collateral redeemable at par while perfectly healthy. */
|
|
8636
|
+
redeemable?: boolean;
|
|
8637
|
+
gracePeriodSecs?: number;
|
|
8638
|
+
}
|
|
8639
|
+
interface CounterpartyTerms {
|
|
8640
|
+
kind: Open<'pool' | 'orderbook' | 'auction' | 'broker' | 'cdp' | 'p2p' | 'vault-strategy' | 'off-chain-credit'>;
|
|
8641
|
+
address?: string;
|
|
8642
|
+
/** The trust question, one field. */
|
|
8643
|
+
solvency: Open<'overcollateralized' | 'tranched-senior' | 'tranched-junior' | 'undercollateralized' | 'nav-attested'>;
|
|
8644
|
+
socializedLoss?: boolean;
|
|
8645
|
+
curator?: string;
|
|
8646
|
+
}
|
|
8647
|
+
/** Origination window for auction-gated markets (Term Finance). */
|
|
8648
|
+
interface AuctionWindow {
|
|
8649
|
+
status: Open<'upcoming' | 'open' | 'revealing' | 'closed'>;
|
|
8650
|
+
canBorrow: boolean;
|
|
8651
|
+
canLend: boolean;
|
|
8652
|
+
secondsUntilClose?: number;
|
|
8653
|
+
id?: string;
|
|
8654
|
+
startTime?: number;
|
|
8655
|
+
revealTime?: number;
|
|
8656
|
+
endTime?: number;
|
|
8657
|
+
minBorrowAmount?: string;
|
|
8658
|
+
minLendAmount?: string;
|
|
8659
|
+
}
|
|
8660
|
+
/** What must be granted BEFORE an action can even be built. */
|
|
8661
|
+
type PermissionKind = Open<'token-approval' | 'lender-delegation' | 'manager-authorization' | 'eip712-permit' | 'nft-approval' | 'operator-set'
|
|
8662
|
+
/** Contract callers must be governance-approved (Inverse, Fraxlend). */
|
|
8663
|
+
| 'caller-allowlist'>;
|
|
8664
|
+
interface AvailabilityTerms {
|
|
8665
|
+
/** Gate CTAs on THIS and nothing else — it already folds in caps, freezes,
|
|
8666
|
+
* auction windows and gating. */
|
|
8667
|
+
canOpen: boolean;
|
|
8668
|
+
canClose: boolean;
|
|
8669
|
+
/** Machine-readable reason when `canOpen` is false. */
|
|
8670
|
+
blockedBy?: Open<'frozen' | 'paused' | 'cap-full' | 'auction-closed' | 'no-liquidity' | 'not-whitelisted' | 'shutdown' | 'disabled'>;
|
|
8671
|
+
gating: Open<'permissionless' | 'whitelist' | 'attestation' | 'kyc' | 'allowlist-contract'>;
|
|
8672
|
+
/** Absent ⇒ no window applies. NOT the same as `closed`. */
|
|
8673
|
+
window?: AuctionWindow;
|
|
8674
|
+
/** Raw base units. */
|
|
8675
|
+
minSize?: string;
|
|
8676
|
+
cap?: string;
|
|
8677
|
+
/** 0..1 — how full the cap is. */
|
|
8678
|
+
capUtilization?: number;
|
|
8679
|
+
requires?: PermissionKind[];
|
|
8680
|
+
}
|
|
8681
|
+
interface PositionConstraints {
|
|
8682
|
+
/** Aave isolation mode: capped debt, no collateral mixing. */
|
|
8683
|
+
isolation?: {
|
|
8684
|
+
enabled: boolean;
|
|
8685
|
+
debtCeiling?: string;
|
|
8686
|
+
ceilingUtilization?: number;
|
|
8687
|
+
};
|
|
8688
|
+
/** Borrowing this asset forbids borrowing any other in the same account. */
|
|
8689
|
+
siloedBorrowing?: boolean;
|
|
8690
|
+
crossMargin: boolean;
|
|
8691
|
+
/**
|
|
8692
|
+
* How a position is ADDRESSED. `loanId` already means five different things
|
|
8693
|
+
* across our lenders and `termId` six — making the model explicit is
|
|
8694
|
+
* cheaper than making every integrator rediscover it.
|
|
8695
|
+
*/
|
|
8696
|
+
positionModel: Open<'account' | 'sub-account' | 'nft' | 'cdp-id' | 'loan-id' | 'escrow'>;
|
|
8697
|
+
/** One line saying what the id in `loanId`/`posId` actually IS here. */
|
|
8698
|
+
positionIdMeaning?: string;
|
|
8699
|
+
maxPositions?: number;
|
|
8700
|
+
/**
|
|
8701
|
+
* What this fetch actually SAW, as opposed to what the lender family
|
|
8702
|
+
* implies. Kept separate from `crossMargin` / `positionModel` on purpose:
|
|
8703
|
+
* those are family-level truths from the registry, these are per-fetch
|
|
8704
|
+
* observations, and collapsing the two would let a thin chain (a lender
|
|
8705
|
+
* listing one asset today) masquerade as a structural property.
|
|
8706
|
+
*
|
|
8707
|
+
* Useful precisely where they DISAGREE — e.g. Fluid is registered isolated
|
|
8708
|
+
* because its T1 vaults dominate, but its T2–T4 "smart" vaults genuinely
|
|
8709
|
+
* pool two collaterals; a `collateralAssetCount > 1` on a Fluid row is the
|
|
8710
|
+
* signal that this particular vault is one of them.
|
|
8711
|
+
*/
|
|
8712
|
+
observed?: {
|
|
8713
|
+
/** Distinct collateral assets this market actually accepts, this fetch. */
|
|
8714
|
+
collateralAssetCount: number;
|
|
8715
|
+
/** Markets seen under this lender key on this chain, this fetch. */
|
|
8716
|
+
marketCount: number;
|
|
8717
|
+
/** Does the lender key fan out to many markets (registry answer)? */
|
|
8718
|
+
multiMarketKey: boolean;
|
|
8719
|
+
};
|
|
8720
|
+
}
|
|
8721
|
+
type AdminKind = Open<'EOA' | 'SAFE' | 'TIMELOCK' | 'GOVERNOR' | 'GOVERNANCE' | 'CUSTOM' | 'UNKNOWN'>;
|
|
8722
|
+
type GovernancePower = Open<'pause-deposits' | 'pause-withdrawals' | 'pause-borrows' | 'freeze-market' | 'change-ltv' | 'change-rate' | 'change-fees' | 'set-caps' | 'add-collateral' | 'swap-oracle' | 'upgrade-implementation' | 'blacklist' | 'seize-funds' | 'reprice-pending-redemptions'>;
|
|
8723
|
+
interface GovernanceTerms {
|
|
8724
|
+
mutability: Open<'immutable' | 'governed' | 'unknown'>;
|
|
8725
|
+
/** The governance root, after hopping proxy admins / timelock admins. */
|
|
8726
|
+
controller?: string;
|
|
8727
|
+
controllerKind?: AdminKind;
|
|
8728
|
+
safe?: {
|
|
8729
|
+
threshold: number;
|
|
8730
|
+
owners: number;
|
|
8731
|
+
};
|
|
8732
|
+
/**
|
|
8733
|
+
* Enforced delay in SECONDS between a parameter change being queued and it
|
|
8734
|
+
* taking effect — the holder's NOTICE PERIOD. `0`, or any `controllerKind`
|
|
8735
|
+
* that is not `TIMELOCK`, means a parameter can change in the very next
|
|
8736
|
+
* block with no warning.
|
|
8737
|
+
*
|
|
8738
|
+
* **This is NOT a withdrawal lock.** `SupplyExitTerms.cooldownSecs` is how
|
|
8739
|
+
* long YOUR money is stuck; this is how long you have to react to someone
|
|
8740
|
+
* else changing the deal. Never merge or sum the two.
|
|
8741
|
+
*/
|
|
8742
|
+
timelockSecs?: number;
|
|
8743
|
+
timelockSource?: Open<'on-chain' | 'screened' | 'metadata'>;
|
|
8744
|
+
/**
|
|
8745
|
+
* The controller IS a timelock but its delay could not be read. Distinct
|
|
8746
|
+
* from `timelockSecs: undefined` on a non-timelock root, which genuinely
|
|
8747
|
+
* means "no notice period" — conflating the two would raise a false alarm
|
|
8748
|
+
* on the safest governance shape.
|
|
8749
|
+
*/
|
|
8750
|
+
timelockUnknown?: boolean;
|
|
8751
|
+
tier?: Open<'low' | 'medium' | 'high' | 'unknown'>;
|
|
8752
|
+
score?: number;
|
|
8753
|
+
powers?: GovernancePower[];
|
|
8754
|
+
roles?: {
|
|
8755
|
+
owner?: string;
|
|
8756
|
+
curator?: string;
|
|
8757
|
+
guardian?: string;
|
|
8758
|
+
feeRecipient?: string;
|
|
8759
|
+
};
|
|
8760
|
+
/** Governance screens refresh far slower than rates — own timestamp. */
|
|
8761
|
+
asOfScreen?: number;
|
|
8762
|
+
}
|
|
8763
|
+
type OracleBand = Open<'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'>;
|
|
8764
|
+
interface OracleTerms {
|
|
8765
|
+
/**
|
|
8766
|
+
* `none` is MEANINGFUL, not missing data: Teller liquidates on TIME and has
|
|
8767
|
+
* no oracle and no health factor anywhere in its trigger.
|
|
8768
|
+
*/
|
|
8769
|
+
kind: Open<'price-feed' | 'nav-attested' | 'none'>;
|
|
8770
|
+
/**
|
|
8771
|
+
* THE oracle for this `marketUid` — SINGULAR, lowercased. Verified across
|
|
8772
|
+
* the full oracle classification: 8,993 marketUids, 0 with more than one
|
|
8773
|
+
* address. Singularity holds because `marketUid` granularity is already
|
|
8774
|
+
* per-asset; the array in the legacy `oracleInfo.feeds[]` is an artifact of
|
|
8775
|
+
* hanging off the lender/params level instead.
|
|
8776
|
+
*
|
|
8777
|
+
* For a composite/cross adapter this is the ADAPTER — the address whose
|
|
8778
|
+
* failure or replacement moves this market's price.
|
|
8779
|
+
*/
|
|
8780
|
+
address?: string;
|
|
8781
|
+
/** Underlying feeds when the adapter composes several and the classifier
|
|
8782
|
+
* decomposed them. `address` stays the single source of truth. */
|
|
8783
|
+
components?: string[];
|
|
8784
|
+
provider?: string;
|
|
8785
|
+
/** Decoded reported pair, e.g. `"ETH / USD"`. */
|
|
8786
|
+
priceDescription?: string;
|
|
8787
|
+
/** What it SHOULD report, e.g. `"WETH / USD"`. */
|
|
8788
|
+
intendedPair?: string;
|
|
8789
|
+
correctAsset?: boolean | null;
|
|
8790
|
+
correctNumeraire?: boolean | null;
|
|
8791
|
+
fixedRate?: boolean;
|
|
8792
|
+
score?: number;
|
|
8793
|
+
band?: OracleBand;
|
|
8794
|
+
flags?: string[];
|
|
8795
|
+
/** Can the oracle be swapped/upgraded, and by whom. On an otherwise
|
|
8796
|
+
* IMMUTABLE market this is the ONLY mutable trust vector. */
|
|
8797
|
+
mutability?: {
|
|
8798
|
+
mutable: boolean;
|
|
8799
|
+
kind: Open<'IMMUTABLE' | 'PROXY' | 'AUTHORITY' | 'UNKNOWN'>;
|
|
8800
|
+
controller?: string;
|
|
8801
|
+
controllerKind?: AdminKind;
|
|
8802
|
+
timelockSecs?: number;
|
|
8803
|
+
};
|
|
8804
|
+
heartbeatSecs?: number;
|
|
8805
|
+
lastUpdateAt?: number;
|
|
8806
|
+
}
|
|
8807
|
+
interface AssetQuality {
|
|
8808
|
+
/** 1 (best) … 5 (worst). */
|
|
8809
|
+
riskScore?: number;
|
|
8810
|
+
source?: Open<'whitelist' | 'default' | 'curated'>;
|
|
8811
|
+
/** On-chain USD liquidity available to absorb a liquidation — the number
|
|
8812
|
+
* that decides whether the LLTV is actually enforceable. */
|
|
8813
|
+
liquidityUsd?: number;
|
|
8814
|
+
/** The TOKEN CONTRACT's own governance, distinct from the market's. An
|
|
8815
|
+
* upgradeable, pausable collateral is a supplier risk even on an
|
|
8816
|
+
* immutable market. */
|
|
8817
|
+
governanceScore?: number;
|
|
8818
|
+
governanceLevel?: Open<'green' | 'amber' | 'red'>;
|
|
8819
|
+
upgradeable?: boolean;
|
|
8820
|
+
canPause?: boolean;
|
|
8821
|
+
adminKind?: AdminKind;
|
|
8822
|
+
}
|
|
8823
|
+
interface ExposureEntry {
|
|
8824
|
+
asset: TermAssetRef;
|
|
8825
|
+
/** That asset's OWN row in this lender — join key to its full term sheet. */
|
|
8826
|
+
marketUid?: string;
|
|
8827
|
+
via: Open<'collateral' | 'vault-allocation' | 'strategy' | 'idle'>;
|
|
8828
|
+
assets?: number;
|
|
8829
|
+
assetsUsd?: number;
|
|
8830
|
+
/** 0..100. ABSENT when `weightBasis === 'unweighted'`. */
|
|
8831
|
+
weightPct?: number;
|
|
8832
|
+
ltv?: number;
|
|
8833
|
+
liquidationLtv?: number;
|
|
8834
|
+
liquidationPenalty?: number;
|
|
8835
|
+
/** The collateral's OWN oracle. Your deposit's safety depends on the oracle
|
|
8836
|
+
* pricing SOMEONE ELSE'S collateral. */
|
|
8837
|
+
oracle?: OracleTerms;
|
|
8838
|
+
quality?: AssetQuality;
|
|
8839
|
+
}
|
|
8840
|
+
interface ExposureTerms {
|
|
8841
|
+
count: number;
|
|
8842
|
+
/**
|
|
8843
|
+
* How `weightPct` was obtained, and therefore how much to trust it.
|
|
8844
|
+
* `unweighted` = POOLED lenders: Aave/Compound do not record which
|
|
8845
|
+
* collateral backs which borrow on-chain, so the list is the ACCEPTED SET,
|
|
8846
|
+
* not a measured split. Do not render a pie chart from it.
|
|
8847
|
+
*/
|
|
8848
|
+
weightBasis: Open<'debt' | 'allocation' | 'unweighted'>;
|
|
8849
|
+
worstRiskScore?: number;
|
|
8850
|
+
worstOracleBand?: OracleBand;
|
|
8851
|
+
/** Largest single exposure's `weightPct` — the concentration signal. Only
|
|
8852
|
+
* meaningful when `weightBasis !== 'unweighted'`. */
|
|
8853
|
+
topWeightPct?: number;
|
|
8854
|
+
items: ExposureEntry[];
|
|
8855
|
+
}
|
|
8856
|
+
interface UtilizationTerms {
|
|
8857
|
+
/** borrowed / supplied, 0..1 — the IRM input for this market. */
|
|
8858
|
+
utilization: number;
|
|
8859
|
+
/**
|
|
8860
|
+
* The basis the ratio is computed over. NOT always this row: rates for
|
|
8861
|
+
* shared-liquidity protocols are set on a larger pool, and a simulation
|
|
8862
|
+
* must shift THAT, not the row totals.
|
|
8863
|
+
*/
|
|
8864
|
+
basis: Open<'market' | 'hub' | 'liquidity-layer' | 'pool'>;
|
|
8865
|
+
irmTotalDeposits?: number;
|
|
8866
|
+
irmTotalDebt?: number;
|
|
8867
|
+
/** Where the curve steepens — headroom before the rate jumps. */
|
|
8868
|
+
targetUtilization?: number;
|
|
8869
|
+
kinkUtilization?: number;
|
|
8870
|
+
/** 0..1. `1` = cap full and the side is closed. */
|
|
8871
|
+
supplyCapUtilization?: number;
|
|
8872
|
+
borrowCapUtilization?: number;
|
|
8873
|
+
/** Fluid: share of collateral locked below the withdrawal limit. */
|
|
8874
|
+
lockupRatio?: number;
|
|
8875
|
+
}
|
|
8876
|
+
/**
|
|
8877
|
+
* A non-default risk category, expressed as a DELTA against the resolved
|
|
8878
|
+
* default. `config` is a MAP keyed by category (Aave e-modes, Dolomite
|
|
8879
|
+
* categories, Euler configs, Silo) — a single flat LTV silently reports the
|
|
8880
|
+
* default and hides the rest, which on an Aave ETH-correlated e-mode is the
|
|
8881
|
+
* difference between 80 % and 93 %.
|
|
8882
|
+
*/
|
|
8883
|
+
interface ModeVariant {
|
|
8884
|
+
/** The `config` map key. `'0'` is the default on every lender. */
|
|
8885
|
+
modeId: string;
|
|
8886
|
+
label?: string;
|
|
8887
|
+
isDefault: boolean;
|
|
8888
|
+
entry?: Open<'automatic' | 'user-selected' | 'per-position'>;
|
|
8889
|
+
liquidation?: Partial<LiquidationTerms>;
|
|
8890
|
+
/**
|
|
8891
|
+
* Mode-scoped and usually RESTRICTED: an e-mode typically narrows the
|
|
8892
|
+
* accepted collateral to a correlated basket. Omitting it would make the
|
|
8893
|
+
* headline LTV look obtainable against collateral the mode forbids.
|
|
8894
|
+
*/
|
|
8895
|
+
acceptedCollateral?: ExposureTerms;
|
|
8896
|
+
rate?: Partial<RateTerms>;
|
|
8897
|
+
availability?: Partial<AvailabilityTerms>;
|
|
8898
|
+
}
|
|
8899
|
+
interface SupplyTermSheet {
|
|
8900
|
+
/** Is this position earning, or is it just collateral? */
|
|
8901
|
+
role: Open<'yield' | 'collateral' | 'both'>;
|
|
8902
|
+
rate: RateTerms;
|
|
8903
|
+
maturity: MaturityTerms;
|
|
8904
|
+
exit: SupplyExitTerms;
|
|
8905
|
+
/** ALL fees on this side, including the exit subset. */
|
|
8906
|
+
fees: FeeTerm[];
|
|
8907
|
+
/** What secures the debt drawn against this deposit. */
|
|
8908
|
+
backedBy?: ExposureTerms;
|
|
8909
|
+
modes?: ModeVariant[];
|
|
8910
|
+
counterparty: CounterpartyTerms;
|
|
8911
|
+
availability: AvailabilityTerms;
|
|
8912
|
+
/** Is the supplied principal at risk beyond ordinary credit risk? */
|
|
8913
|
+
principal: {
|
|
8914
|
+
protected: boolean;
|
|
8915
|
+
risks: Open<'bad-debt' | 'physical-delivery' | 'nav-drawdown' | 'first-loss' | 'depeg'>[];
|
|
8916
|
+
};
|
|
8917
|
+
info: TermInfo;
|
|
8918
|
+
/** Namespaced escape hatch — see the promotion rule in TERM_SHEET_PLAN §13.5. */
|
|
8919
|
+
ext?: Record<string, unknown>;
|
|
8920
|
+
}
|
|
8921
|
+
interface BorrowTermSheet {
|
|
8922
|
+
rate: RateTerms;
|
|
8923
|
+
maturity: MaturityTerms;
|
|
8924
|
+
/**
|
|
8925
|
+
* Does the amount owed GROW, or is it a static face value fixed at trade
|
|
8926
|
+
* time? The single biggest departure from variable-rate intuition — four of
|
|
8927
|
+
* six fixed-term lenders are static.
|
|
8928
|
+
*/
|
|
8929
|
+
debtShape: Open<'accruing' | 'static-face' | 'prepaid'>;
|
|
8930
|
+
exit: BorrowExitTerms;
|
|
8931
|
+
/** Fully resolved for the DEFAULT mode. `modes[]` carries the rest. */
|
|
8932
|
+
liquidation: LiquidationTerms;
|
|
8933
|
+
/** What you may post, each with its own LTV, oracle and quality. */
|
|
8934
|
+
acceptedCollateral?: ExposureTerms;
|
|
8935
|
+
modes?: ModeVariant[];
|
|
8936
|
+
fees: FeeTerm[];
|
|
8937
|
+
counterparty: CounterpartyTerms;
|
|
8938
|
+
availability: AvailabilityTerms;
|
|
8939
|
+
info: TermInfo;
|
|
8940
|
+
ext?: Record<string, unknown>;
|
|
8941
|
+
}
|
|
8942
|
+
/**
|
|
8943
|
+
* Distinguishes "not applicable" from "not implemented yet" — the affordance
|
|
8944
|
+
* that lets phases ship incrementally without lying. A missing `oracle` must
|
|
8945
|
+
* never read as "this market has no oracle" when the truth is "we have not
|
|
8946
|
+
* classified it".
|
|
8947
|
+
*/
|
|
8948
|
+
interface CoverageInfo {
|
|
8949
|
+
/** Blocks genuinely computed for this market. */
|
|
8950
|
+
present: string[];
|
|
8951
|
+
/** Blocks that do NOT APPLY here — a positive fact. */
|
|
8952
|
+
notApplicable?: Record<string, string>;
|
|
8953
|
+
/** Blocks that WOULD apply but are not wired yet. */
|
|
8954
|
+
pending?: Record<string, string>;
|
|
8955
|
+
}
|
|
8956
|
+
/** Current schema version. Bumped ONLY for removals/semantic/unit changes;
|
|
8957
|
+
* new optional fields and new enum members are additive. */
|
|
8958
|
+
declare const TERM_SHEET_SCHEMA_VERSION = 1;
|
|
8959
|
+
interface TermSheet {
|
|
8960
|
+
schemaVersion: number;
|
|
8961
|
+
/** unix seconds at fetch — everything here is a snapshot. */
|
|
8962
|
+
asOf: number;
|
|
8963
|
+
/** `<family>.<variant>@v<n>`, e.g. `aave-v3.pool@v1`. Points at the prose
|
|
8964
|
+
* catalogue so the per-market payload stays small. */
|
|
8965
|
+
profileId: string;
|
|
8966
|
+
/** The anchor this sheet describes. */
|
|
8967
|
+
marketUid?: string;
|
|
8968
|
+
lender?: string;
|
|
8969
|
+
chainId?: string;
|
|
8970
|
+
supply?: SupplyTermSheet;
|
|
8971
|
+
borrow?: BorrowTermSheet;
|
|
8972
|
+
/** Shared — these describe the MARKET, not a side. */
|
|
8973
|
+
governance?: GovernanceTerms;
|
|
8974
|
+
oracle?: OracleTerms;
|
|
8975
|
+
utilization?: UtilizationTerms;
|
|
8976
|
+
constraints?: PositionConstraints;
|
|
8977
|
+
coverage?: CoverageInfo;
|
|
8978
|
+
ext?: Record<string, unknown>;
|
|
8979
|
+
}
|
|
8980
|
+
/** Compact form for list endpoints — `?terms=digest`. */
|
|
8981
|
+
interface TermSheetDigest {
|
|
8982
|
+
schemaVersion: number;
|
|
8983
|
+
profileId: string;
|
|
8984
|
+
marketUid?: string;
|
|
8985
|
+
supply?: {
|
|
8986
|
+
rateKind: RateKind;
|
|
8987
|
+
aprTotal: AprPercent;
|
|
8988
|
+
maturityKind: MaturityTerms['kind'];
|
|
8989
|
+
maturity?: number;
|
|
8990
|
+
exitMode: SupplyExitMode;
|
|
8991
|
+
settlement: SupplyExitTerms['settlement'];
|
|
8992
|
+
canOpen: boolean;
|
|
8993
|
+
headline: string;
|
|
8994
|
+
tags: TermTag[];
|
|
8995
|
+
backedBy?: Omit<ExposureTerms, 'items'>;
|
|
8996
|
+
};
|
|
8997
|
+
borrow?: {
|
|
8998
|
+
rateKind: RateKind;
|
|
8999
|
+
apr: AprPercent;
|
|
9000
|
+
maturityKind: MaturityTerms['kind'];
|
|
9001
|
+
maturity?: number;
|
|
9002
|
+
debtShape: BorrowTermSheet['debtShape'];
|
|
9003
|
+
earlyRepay: BorrowExitTerms['earlyRepay'];
|
|
9004
|
+
liquidationTrigger: LiquidationTerms['trigger'];
|
|
9005
|
+
canOpen: boolean;
|
|
9006
|
+
headline: string;
|
|
9007
|
+
tags: TermTag[];
|
|
9008
|
+
acceptedCollateral?: Omit<ExposureTerms, 'items'>;
|
|
9009
|
+
};
|
|
9010
|
+
oracle?: Pick<OracleTerms, 'kind' | 'address' | 'provider' | 'band'>;
|
|
9011
|
+
governance?: Pick<GovernanceTerms, 'mutability' | 'controllerKind' | 'timelockSecs' | 'tier'>;
|
|
9012
|
+
utilization?: number;
|
|
9013
|
+
}
|
|
9014
|
+
/** A term profile — the invariant prose, one per lender family × variant. */
|
|
9015
|
+
interface TermProfile {
|
|
9016
|
+
id: string;
|
|
9017
|
+
/** Display name, e.g. `Aave V3 pool market`. */
|
|
9018
|
+
name: string;
|
|
9019
|
+
/** Which lender family this covers. */
|
|
9020
|
+
family: string;
|
|
9021
|
+
supply?: {
|
|
9022
|
+
description: string;
|
|
9023
|
+
implications?: string[];
|
|
9024
|
+
};
|
|
9025
|
+
borrow?: {
|
|
9026
|
+
description: string;
|
|
9027
|
+
implications?: string[];
|
|
9028
|
+
};
|
|
9029
|
+
docsUrl?: string;
|
|
9030
|
+
}
|
|
9031
|
+
/** Deep-partial, for adapters that return only what they override. */
|
|
9032
|
+
type DeepPartial<T> = {
|
|
9033
|
+
[K in keyof T]?: T[K] extends (infer U)[] ? U[] : T[K] extends object | undefined ? DeepPartial<NonNullable<T[K]>> : T[K];
|
|
9034
|
+
};
|
|
9035
|
+
|
|
9036
|
+
/**
|
|
9037
|
+
* The normalized input the builder reads.
|
|
9038
|
+
*
|
|
9039
|
+
* Deliberately NOT `PoolData` directly: the same market travels through this
|
|
9040
|
+
* codebase in two casings — the in-package shape (`totalDepositsUSD`,
|
|
9041
|
+
* `variableBorrowRate`) and the API-serialized shape (`totalDepositsUsd`,
|
|
9042
|
+
* nested `caps`/`flags`/`config`). The builder must work on both, because it
|
|
9043
|
+
* runs in-package during a fetch AND at the worker while proxying an origin
|
|
9044
|
+
* response.
|
|
9045
|
+
*
|
|
9046
|
+
* So: one tolerant reader (`toTermSheetInput`) normalizes either shape into
|
|
9047
|
+
* this interface, and the builder itself is pure over the normalized form.
|
|
9048
|
+
*/
|
|
9049
|
+
interface TermConfigEntry {
|
|
9050
|
+
category: number | string;
|
|
9051
|
+
label?: string;
|
|
9052
|
+
borrowCollateralFactor?: number;
|
|
9053
|
+
collateralFactor?: number;
|
|
9054
|
+
borrowFactor?: number;
|
|
9055
|
+
liquidationPenalty?: number;
|
|
9056
|
+
closeFactor?: number;
|
|
9057
|
+
targetHealthFactor?: number;
|
|
9058
|
+
collateralDisabled?: boolean;
|
|
9059
|
+
debtDisabled?: boolean;
|
|
9060
|
+
}
|
|
9061
|
+
interface TermRewardInput {
|
|
9062
|
+
asset?: string;
|
|
9063
|
+
depositRate?: number;
|
|
9064
|
+
variableBorrowRate?: number;
|
|
9065
|
+
stableBorrowRate?: number;
|
|
9066
|
+
/** Merkl / points programs mark themselves; absent ⇒ a normal token. */
|
|
9067
|
+
kind?: string;
|
|
9068
|
+
endsAt?: number;
|
|
9069
|
+
claim?: string;
|
|
9070
|
+
}
|
|
9071
|
+
interface TermMenuInput {
|
|
9072
|
+
termId: number;
|
|
9073
|
+
durationSecs: number;
|
|
9074
|
+
durationDays: number;
|
|
9075
|
+
apr: number;
|
|
9076
|
+
depositApr?: number;
|
|
9077
|
+
available?: number;
|
|
9078
|
+
}
|
|
9079
|
+
/** Normalized market facts the generic builder needs. */
|
|
9080
|
+
interface TermSheetInput {
|
|
9081
|
+
marketUid: string;
|
|
9082
|
+
lender: string;
|
|
9083
|
+
chainId: string;
|
|
9084
|
+
/** Underlying asset of THIS row. */
|
|
9085
|
+
asset?: {
|
|
9086
|
+
chainId?: string;
|
|
9087
|
+
address?: string;
|
|
9088
|
+
symbol?: string;
|
|
9089
|
+
name?: string;
|
|
9090
|
+
decimals?: number;
|
|
9091
|
+
assetGroup?: string;
|
|
9092
|
+
logoURI?: string;
|
|
9093
|
+
};
|
|
9094
|
+
underlying?: string;
|
|
9095
|
+
decimals?: number;
|
|
9096
|
+
depositRate?: number;
|
|
9097
|
+
variableBorrowRate?: number;
|
|
9098
|
+
stableBorrowRate?: number;
|
|
9099
|
+
intrinsicYield?: number;
|
|
9100
|
+
rewards?: TermRewardInput[];
|
|
9101
|
+
rateModel?: string;
|
|
9102
|
+
originationFee?: number;
|
|
9103
|
+
totalDeposits?: number;
|
|
9104
|
+
totalDebt?: number;
|
|
9105
|
+
totalDebtStable?: number;
|
|
9106
|
+
totalLiquidity?: number;
|
|
9107
|
+
borrowLiquidity?: number;
|
|
9108
|
+
totalDepositsUsd?: number;
|
|
9109
|
+
totalDebtUsd?: number;
|
|
9110
|
+
totalLiquidityUsd?: number;
|
|
9111
|
+
utilization?: number;
|
|
9112
|
+
irmTotalDeposits?: number;
|
|
9113
|
+
irmTotalDebt?: number;
|
|
9114
|
+
lockupRatio?: number;
|
|
9115
|
+
supplyCap?: number;
|
|
9116
|
+
borrowCap?: number;
|
|
9117
|
+
debtCeiling?: string | number;
|
|
9118
|
+
isActive?: boolean;
|
|
9119
|
+
isFrozen?: boolean;
|
|
9120
|
+
borrowingEnabled?: boolean;
|
|
9121
|
+
depositsEnabled?: boolean;
|
|
9122
|
+
collateralActive?: boolean;
|
|
9123
|
+
hasStable?: boolean;
|
|
9124
|
+
variableBorrowDisabled?: boolean;
|
|
9125
|
+
config?: Record<string, TermConfigEntry>;
|
|
9126
|
+
closeFactor?: number;
|
|
9127
|
+
targetHealthFactor?: number;
|
|
9128
|
+
fixedTerm?: {
|
|
9129
|
+
model?: string;
|
|
9130
|
+
maturity?: number;
|
|
9131
|
+
fees?: {
|
|
9132
|
+
continuousFeeApr?: number;
|
|
9133
|
+
settlementFee?: number;
|
|
9134
|
+
latePenaltyApr?: number;
|
|
9135
|
+
originationFeePercent?: number;
|
|
9136
|
+
};
|
|
9137
|
+
earlyRepay?: {
|
|
9138
|
+
kind?: string;
|
|
9139
|
+
};
|
|
9140
|
+
provider?: {
|
|
9141
|
+
kind?: string;
|
|
9142
|
+
address?: string;
|
|
9143
|
+
};
|
|
9144
|
+
auction?: Record<string, unknown>;
|
|
9145
|
+
};
|
|
9146
|
+
terms?: TermMenuInput[];
|
|
9147
|
+
/** Market-level params (`params.market`) when the lender has them. */
|
|
9148
|
+
market?: Record<string, unknown>;
|
|
9149
|
+
}
|
|
9150
|
+
/**
|
|
9151
|
+
* Normalize either the in-package `PoolData`-ish row or an API `LendingMarket`
|
|
9152
|
+
* item into {@link TermSheetInput}. Tolerant by design: a field missing under
|
|
9153
|
+
* one casing is looked up under the other, and nested `caps`/`flags` bundles
|
|
9154
|
+
* are unwrapped.
|
|
9155
|
+
*/
|
|
9156
|
+
declare function toTermSheetInput(row: Record<string, any>, ctx?: {
|
|
9157
|
+
marketUid?: string;
|
|
9158
|
+
lender?: string;
|
|
9159
|
+
chainId?: string;
|
|
9160
|
+
market?: Record<string, any>;
|
|
9161
|
+
/**
|
|
9162
|
+
* Item-level fixed-term descriptor. `/lending/latest` attaches `fixedTerm`
|
|
9163
|
+
* to the LENDER item, not to each market row, so without this every
|
|
9164
|
+
* fixed-term market would silently lose its maturity, its fees and its
|
|
9165
|
+
* auction window. A row-level `fixedTerm` (how `/pools/latest` serializes
|
|
9166
|
+
* it) is more specific and wins.
|
|
9167
|
+
*/
|
|
9168
|
+
fixedTerm?: Record<string, any>;
|
|
9169
|
+
}): TermSheetInput;
|
|
9170
|
+
|
|
9171
|
+
/**
|
|
9172
|
+
* Accepted-collateral / backing set from the SIBLING rows of the same lender.
|
|
9173
|
+
*
|
|
9174
|
+
* Pooled lenders (Aave, Compound) do NOT record on-chain which collateral
|
|
9175
|
+
* backs which borrow, so the result is the ACCEPTED SET with
|
|
9176
|
+
* `weightBasis: 'unweighted'` and NO `weightPct` on any item. Inventing a
|
|
9177
|
+
* TVL-proxy weight would look authoritative and be false — a large idle
|
|
9178
|
+
* collateral market is not a large exposure.
|
|
9179
|
+
*/
|
|
9180
|
+
declare function buildExposures(input: TermSheetInput, siblings: TermSheetInput[], direction: 'backing' | 'accepted'): ExposureTerms | undefined;
|
|
9181
|
+
/** Deep merge an adapter's partial over the generic result. Arrays REPLACE. */
|
|
9182
|
+
declare function mergeDeep<T>(base: T, patch: DeepPartial<T> | undefined): T;
|
|
9183
|
+
/**
|
|
9184
|
+
* Fill `info` (headline / description / tags) LAST, after adapters have run,
|
|
9185
|
+
* so the prose always describes the final values rather than the generic
|
|
9186
|
+
* guess. This is the mechanism that stops copy drifting from numbers.
|
|
9187
|
+
*/
|
|
9188
|
+
declare function finalizeInfo(sheet: TermSheet): TermSheet;
|
|
9189
|
+
interface BuildTermSheetOptions {
|
|
9190
|
+
/** Unix seconds; injected so tests are deterministic. */
|
|
9191
|
+
now?: number;
|
|
9192
|
+
/** Other rows of the SAME lender+chain — used to derive the exposure set. */
|
|
9193
|
+
siblings?: TermSheetInput[];
|
|
9194
|
+
/** Adapter output, merged over the generic result. */
|
|
9195
|
+
patch?: DeepPartial<TermSheet>;
|
|
9196
|
+
profileId?: string;
|
|
9197
|
+
}
|
|
9198
|
+
/** Build one complete term sheet for one market row. */
|
|
9199
|
+
declare function buildTermSheet(input: TermSheetInput, opts?: BuildTermSheetOptions): TermSheet;
|
|
9200
|
+
|
|
9201
|
+
/** Supply-side tags. Market-level tags are folded in by the caller. */
|
|
9202
|
+
declare function deriveSupplyTags(supply: SupplyTermSheet, market?: Pick<TermSheet, 'governance' | 'oracle'>): TermTag[];
|
|
9203
|
+
/** Borrow-side tags. */
|
|
9204
|
+
declare function deriveBorrowTags(borrow: BorrowTermSheet, market?: Pick<TermSheet, 'governance' | 'oracle'>): TermTag[];
|
|
9205
|
+
|
|
9206
|
+
/**
|
|
9207
|
+
* Severity model — PURE, derived only from structured fields.
|
|
9208
|
+
*
|
|
9209
|
+
* Space is the binding constraint at every display depth, so ranking has to be
|
|
9210
|
+
* principled rather than per-lender taste. There is deliberately NO
|
|
9211
|
+
* hand-maintained list of "scary markets": a newly integrated lender is
|
|
9212
|
+
* classified correctly the moment its adapter sets the right fields.
|
|
9213
|
+
*
|
|
9214
|
+
* - `critical` — you can lose MORE than the amount at stake, or lose it
|
|
9215
|
+
* without doing anything wrong. This is the only tier that should gate a
|
|
9216
|
+
* signature.
|
|
9217
|
+
* - `warn` — it costs money, or blocks you.
|
|
9218
|
+
* - `info` — everything else.
|
|
9219
|
+
*/
|
|
9220
|
+
type Severity = 'critical' | 'warn' | 'info';
|
|
9221
|
+
interface SeverityFinding {
|
|
9222
|
+
severity: Severity;
|
|
9223
|
+
/** Stable slug — the join key for UI copy and for tests. */
|
|
9224
|
+
id: string;
|
|
9225
|
+
/** Ready-to-render sentence. */
|
|
9226
|
+
message: string;
|
|
9227
|
+
side: 'supply' | 'borrow' | 'market';
|
|
9228
|
+
}
|
|
9229
|
+
/** Sort findings most-severe-first, stable within a tier. */
|
|
9230
|
+
declare function rankFindings(findings: SeverityFinding[]): SeverityFinding[];
|
|
9231
|
+
declare function supplyFindings(supply: SupplyTermSheet): SeverityFinding[];
|
|
9232
|
+
declare function borrowFindings(borrow: BorrowTermSheet): SeverityFinding[];
|
|
9233
|
+
/**
|
|
9234
|
+
* All findings for one side of a sheet, ranked most-severe-first. Pass
|
|
9235
|
+
* `side: 'supply' | 'borrow'` — market-level findings are always included
|
|
9236
|
+
* because governance and oracle affect both sides.
|
|
9237
|
+
*/
|
|
9238
|
+
declare function findingsFor(sheet: TermSheet, side: 'supply' | 'borrow'): SeverityFinding[];
|
|
9239
|
+
/** Does this side carry anything that should gate a signature? */
|
|
9240
|
+
declare function hasCritical(sheet: TermSheet, side: 'supply' | 'borrow'): boolean;
|
|
9241
|
+
|
|
9242
|
+
/** `4.1234` → `"4.12 %"`; trims to 2dp, drops a trailing `.00`. */
|
|
9243
|
+
declare function pct(value: number | undefined, dp?: number): string;
|
|
9244
|
+
/** Duration in seconds → the coarsest human unit that stays honest. */
|
|
9245
|
+
declare function duration(secs: number | undefined): string;
|
|
9246
|
+
/** Unix seconds → `"3 Sep 2026"`. Locale-independent so snapshots are stable. */
|
|
9247
|
+
declare function shortDate(unixSecs: number | undefined): string;
|
|
9248
|
+
/** One fee → a self-contained phrase, correct even for an unrecognised `id`. */
|
|
9249
|
+
declare function feePhrase(fee: FeeTerm): string;
|
|
9250
|
+
/** Supply-side headline: ≤ ~100 chars, always populated. */
|
|
9251
|
+
declare function supplyHeadline(s: SupplyTermSheet): string;
|
|
9252
|
+
/** Borrow-side headline. */
|
|
9253
|
+
declare function borrowHeadline(b: BorrowTermSheet): string;
|
|
9254
|
+
/** Supply-side description — 1–3 sentences, market values interpolated. */
|
|
9255
|
+
declare function supplyDescription(s: SupplyTermSheet, sheet?: Pick<TermSheet, 'utilization'>): string;
|
|
9256
|
+
/** Borrow-side description. */
|
|
9257
|
+
declare function borrowDescription(b: BorrowTermSheet): string;
|
|
9258
|
+
|
|
9259
|
+
declare const TERM_PROFILES: TermProfile[];
|
|
9260
|
+
declare function getTermProfile(id: string): TermProfile | undefined;
|
|
9261
|
+
/** Fallback used when a family has no dedicated profile yet. */
|
|
9262
|
+
declare const DEFAULT_PROFILE_ID = "pool.variable@v1";
|
|
9263
|
+
|
|
9264
|
+
/**
|
|
9265
|
+
* Stamping — the single place term sheets are attached.
|
|
9266
|
+
*
|
|
9267
|
+
* Runs ONCE at the end of the public-data pipeline rather than inside each
|
|
9268
|
+
* lender's converter. That is the whole architecture: ~200 Aave/Compound forks
|
|
9269
|
+
* get correct sheets from the generic builder with zero per-fork work, and
|
|
9270
|
+
* only the ~13 exotic families need an adapter.
|
|
9271
|
+
*/
|
|
9272
|
+
interface StampOptions {
|
|
9273
|
+
/** Unix seconds; injected so tests are deterministic. */
|
|
9274
|
+
now?: number;
|
|
9275
|
+
/** Attach ranked `implications[]` from the severity model. Default true. */
|
|
9276
|
+
withImplications?: boolean;
|
|
9277
|
+
/**
|
|
9278
|
+
* Derive `governance` / `oracle` / exposure quality from the rows' own
|
|
9279
|
+
* `oracleInfo` + `risk.breakdown`. Default true — set `false` only to test
|
|
9280
|
+
* the un-enriched builder in isolation.
|
|
9281
|
+
*/
|
|
9282
|
+
enrich?: boolean;
|
|
9283
|
+
}
|
|
9284
|
+
/**
|
|
9285
|
+
* Build sheets for one lender's rows on one chain.
|
|
9286
|
+
*
|
|
9287
|
+
* Siblings matter: the exposure set (`backedBy` / `acceptedCollateral`) is
|
|
9288
|
+
* derived by cross-referencing the OTHER rows of the same lender, so the whole
|
|
9289
|
+
* group has to be built together.
|
|
9290
|
+
*/
|
|
9291
|
+
declare function buildTermSheetsForGroup(rows: Record<string, any>[], ctx?: {
|
|
9292
|
+
lender?: string;
|
|
9293
|
+
chainId?: string;
|
|
9294
|
+
market?: Record<string, any>;
|
|
9295
|
+
/** Item-level `fixedTerm` from `/lending/latest` — see `toTermSheetInput`. */
|
|
9296
|
+
fixedTerm?: Record<string, any>;
|
|
9297
|
+
}, opts?: StampOptions): Map<string, TermSheet>;
|
|
9298
|
+
/**
|
|
9299
|
+
* Fill `info.implications[]` from the severity model, most severe first.
|
|
9300
|
+
*
|
|
9301
|
+
* Derived rather than hand-written, so a newly integrated lender gets correct
|
|
9302
|
+
* warnings the moment its adapter sets the right structured fields — and a
|
|
9303
|
+
* warning can never contradict the numbers next to it.
|
|
9304
|
+
*/
|
|
9305
|
+
declare function attachImplications(sheet: TermSheet): TermSheet;
|
|
9306
|
+
/**
|
|
9307
|
+
* Build an {@link EnrichmentIndex} from the market rows themselves.
|
|
9308
|
+
*
|
|
9309
|
+
* The governance and oracle screens are NOT a separate fetch: the origin
|
|
9310
|
+
* already ships both on every row — `oracleInfo.feeds[]` (the oracle-risk
|
|
9311
|
+
* classification) and `risk.breakdown[]` (the governance screen under
|
|
9312
|
+
* `category: 'governance'`, the asset screen under `category: 'token'`). So
|
|
9313
|
+
* the join is local to the group being stamped, with no extra round-trip and
|
|
9314
|
+
* no cross-service dependency.
|
|
9315
|
+
*
|
|
9316
|
+
* The per-exposure enrichment falls out of the same data: an exposure item
|
|
9317
|
+
* points at a SIBLING row's `marketUid`, and that sibling is already in this
|
|
9318
|
+
* group — so its oracle and its asset quality are right there.
|
|
9319
|
+
*/
|
|
9320
|
+
declare function enrichmentIndexFromRows(rows: Record<string, any>[]): EnrichmentIndex;
|
|
9321
|
+
/**
|
|
9322
|
+
* Collapse a sheet to its digest form (`?terms=digest`).
|
|
9323
|
+
*
|
|
9324
|
+
* Drops `items[]` from the exposure sets and the long prose — an Aave market
|
|
9325
|
+
* with 30 accepted collaterals is several kB on its own, and it is the SAME
|
|
9326
|
+
* accepted set repeated on every row of that lender. Every dropped item is
|
|
9327
|
+
* still reachable: each carries a `marketUid` for the bulk endpoint.
|
|
9328
|
+
*/
|
|
9329
|
+
declare function toDigest(sheet: TermSheet): TermSheetDigest;
|
|
9330
|
+
/** Row shape of `~/risk-data/data/oracles/oracle-risk-flat.json`. */
|
|
9331
|
+
interface OracleRiskRow {
|
|
9332
|
+
marketUid: string;
|
|
9333
|
+
oracle?: string;
|
|
9334
|
+
provider?: string;
|
|
9335
|
+
priceDescription?: string;
|
|
9336
|
+
intendedPair?: string;
|
|
9337
|
+
correctOracle?: boolean | null;
|
|
9338
|
+
denominatorMatch?: boolean | null;
|
|
9339
|
+
fixedRate?: boolean;
|
|
9340
|
+
score?: number;
|
|
9341
|
+
band?: string;
|
|
9342
|
+
flags?: string[];
|
|
9343
|
+
/** Underlying feeds when an adapter composes several. `oracle` stays the
|
|
9344
|
+
* single source of truth — this is for auditability only. */
|
|
9345
|
+
components?: string[];
|
|
9346
|
+
}
|
|
9347
|
+
/** Row shape of `~/risk-data/data/lending/market-governance-flat.json`. */
|
|
9348
|
+
interface GovernanceRow {
|
|
9349
|
+
marketUid: string;
|
|
9350
|
+
tier?: string;
|
|
9351
|
+
score?: number;
|
|
9352
|
+
ownerKind?: string;
|
|
9353
|
+
signerThreshold?: number | null;
|
|
9354
|
+
signerCount?: number | null;
|
|
9355
|
+
mode?: string;
|
|
9356
|
+
/** Present once the flat builder carries it through (see TERM_SHEET_PLAN §5.4.1). */
|
|
9357
|
+
delaySeconds?: number | null;
|
|
9358
|
+
}
|
|
9359
|
+
/** Per-asset quality, keyed `chainId → lowercased address`. */
|
|
9360
|
+
type AssetRiskIndex = Record<string, Record<string, {
|
|
9361
|
+
riskScore?: number;
|
|
9362
|
+
source?: string;
|
|
9363
|
+
liquidityUsd?: number;
|
|
9364
|
+
governanceScore?: number;
|
|
9365
|
+
governanceLevel?: string;
|
|
9366
|
+
upgradeable?: boolean;
|
|
9367
|
+
canPause?: boolean;
|
|
9368
|
+
adminKind?: string;
|
|
9369
|
+
}>>;
|
|
9370
|
+
interface EnrichmentIndex {
|
|
9371
|
+
oracleByMarketUid?: Map<string, OracleRiskRow>;
|
|
9372
|
+
governanceByMarketUid?: Map<string, GovernanceRow>;
|
|
9373
|
+
assetRisk?: AssetRiskIndex;
|
|
9374
|
+
}
|
|
9375
|
+
/**
|
|
9376
|
+
* Merge governance / oracle / asset-quality onto a sheet at the SERVING layer.
|
|
9377
|
+
*
|
|
9378
|
+
* These cannot be computed in-package — they come from the risk-data
|
|
9379
|
+
* screeners, which key on the same `marketUid` grammar (a dictionary lookup,
|
|
9380
|
+
* not a fuzzy match). `margin-fetcher` emits the sheet with these blocks
|
|
9381
|
+
* absent; the worker fills them in, exactly as it already does for
|
|
9382
|
+
* `oracleInfo`.
|
|
9383
|
+
*/
|
|
9384
|
+
declare function enrichTermSheet(sheet: TermSheet, index: EnrichmentIndex): TermSheet;
|
|
9385
|
+
|
|
9386
|
+
/**
|
|
9387
|
+
* Invariant checker — pure, and the mechanism that turns a derivation bug into
|
|
9388
|
+
* a loud failure instead of a plausible-looking wrong answer.
|
|
9389
|
+
*
|
|
9390
|
+
* Run over live fetched data in CI for every lender key and vault provider.
|
|
9391
|
+
* Every rule here encodes something that WOULD otherwise ship silently.
|
|
9392
|
+
*/
|
|
9393
|
+
interface TermSheetViolation {
|
|
9394
|
+
/** Stable slug, so a test can assert on the specific rule. */
|
|
9395
|
+
rule: string;
|
|
9396
|
+
message: string;
|
|
9397
|
+
marketUid?: string;
|
|
9398
|
+
}
|
|
9399
|
+
declare function validateTermSheet(sheet: TermSheet): TermSheetViolation[];
|
|
9400
|
+
/** Validate a batch; returns every violation found, flattened. */
|
|
9401
|
+
declare function validateTermSheets(sheets: TermSheet[]): TermSheetViolation[];
|
|
9402
|
+
|
|
9403
|
+
/**
|
|
9404
|
+
* A term-sheet adapter: returns ONLY what the generic builder cannot derive,
|
|
9405
|
+
* as a `DeepPartial<TermSheet>` merged over the generic result.
|
|
9406
|
+
*
|
|
9407
|
+
* Adding a lender is one adapter plus one profile entry — no core edits. The
|
|
9408
|
+
* completeness test fails when a lender family reaches production without a
|
|
9409
|
+
* profile, so the extension point cannot be silently skipped.
|
|
9410
|
+
*/
|
|
9411
|
+
interface TermAdapter {
|
|
9412
|
+
/** Stable id, for tests and debugging. */
|
|
9413
|
+
id: string;
|
|
9414
|
+
/** Does this adapter handle the given lender key? */
|
|
9415
|
+
matches: (lender: string) => boolean;
|
|
9416
|
+
/** The profile whose prose this market points at. */
|
|
9417
|
+
profileId: (input: TermSheetInput) => string;
|
|
9418
|
+
build: (input: TermSheetInput) => DeepPartial<TermSheet>;
|
|
9419
|
+
}
|
|
9420
|
+
/**
|
|
9421
|
+
* Order matters only where predicates could overlap; today they are disjoint.
|
|
9422
|
+
* The list is walked front-to-back and the first match wins.
|
|
9423
|
+
*/
|
|
9424
|
+
declare const TERM_ADAPTERS: TermAdapter[];
|
|
9425
|
+
declare function resolveAdapter(lender: string): TermAdapter | undefined;
|
|
9426
|
+
|
|
9427
|
+
export { type AaveMetadata, type AaveV2Public, type AaveV2UserReserveResponse, type AaveV3Public, type AaveV3UserReserveResponse, type AdditionalYields, type AdminKind, ApiBookSource, type AprData, type AprPercent, type AssetQuality, type AssetRiskIndex, type AuctionWindow, type AvailabilityTerms, type BalanceData, type BaseLendingPosition, type BasicReserveResponse, type BorrowExitTerms, type BorrowTermSheet, type BuildTermSheetOptions, type ChainDiagnostic, type ChainLinkResponse, type ChainQuery, type ChainSummary, type CompoundV2Metadata, type CompoundV3Public, type CompoundV3UserReserveResponse, type ConfigEntry, type ConvertLenderUserDataOptions, type CoreValidators, type CounterpartyTerms, type CoverageInfo, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, type DeepPartial, type Denomination, type DepthMap, EMPTY_BALANCE, type EModeAssets, type EModeData, type EModeResult, EXACTLY_LENDER_KEY, type EndpointFailure, type EnrichmentIndex, type EulerEarnVault, type EulerEarnVaults, type EulerV2Metadata, type ExactlyFixedPool, type ExactlyFixedPosition, type ExactlyMarketAccount, type ExactlyMarketsRaw, type ExactlyUserFixedPosition, type ExposureEntry, type ExposureTerms, type ExtraValidationCall, type FeeTerm, type FeeWhen, type FeedObservation, type FeedStat, type FeedStatsMap, type FeedTimestampMap, type FetchListaVaultsFromChainOptions, type FetchMorphoVaultsFromChainOptions, type FetchOraclePricesOptions, type FetchTokenBalancesOptions, type FlattenPriorityConfig, type FluidFToken, type FluidFTokens, type FrankencoinMarketRaw, type FrankencoinMarketsRaw, type FrankencoinPositionInfo, type FullLenderRewardsMap, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, type GenericCurrency, type GenericTokenList, type GetVaultPublicDataAllOptions, type GmxExecutionFees, type GmxPendingDeposit, type GmxPendingWithdrawal, type GmxReadContracts, type GmxUserBalance, type GmxUserPositions, type GmxUserPositionsOptions, type GmxVault, type GmxVaultKind, type GmxVaults, type GmxVaultsFetchOptions, type GovernancePower, type GovernanceRow, type GovernanceTerms, type GroupAccumulator, HYPERCORE_VAULT_REGISTRY, type HypercoreLockStatus, type HypercoreUserPositionsOptions, type HypercoreVault, type HypercoreVaultPosition, type HypercoreVaultRegistryEntry, type HypercoreVaults, type HypercoreVaultsFetchOptions, IDLE_MARKET_ID, INTERFACE_IDS, type IncompleteLenderRead, type IncompleteReason, type InitMetadata, type InitPublic, type InitUserReserveResponse, type InterfaceKind, type InvariantViolation, type InverseMarketRaw, type InverseMarketsRaw, type InversePositionInfo, LAGOON_API_URL, LAGOON_CHAIN_IDS, type LagoonApiVault, type LagoonSyncMode, type LagoonVault, type LagoonVaults, type LenderConfigData, type LenderConfigMap, type LenderCrossPoolMeta, type LenderData, type LenderDataEntry, type LenderInfo, type LenderInfoMap, type LenderPublicBase, type LenderRewardsMap, type LenderSummary, type LenderToLenderCrossPoolMeta, type LenderTotalAmounts, type LenderUserQuery, type LenderUserResponse, type LenderYieldComplete, type LenderYields$1 as LenderYields, LendingMode, type LiquidationTerms, type LiquityBranchRaw, type LiquityDiscoveredTrove, type LiquityDiscovery, type LiquityMarketsRaw, type LiquitySpInfo, type LiquityTroveInfo, type ListaMarketOverrides, type LlamaLendMarketRaw, type LlamaLendMarketsRaw, type LlamaLendPositionInfo, type LoopPostTradeMetrics, type LstDelegation, type LstDelegationKind, type LstValidator, type LstWithdrawalFetchOptions, type LstWithdrawalRegistryEntry, type LstWithdrawalRequest, type LstWithdrawalRequestsByLst, type LstWithdrawalStatus, MORPHO_LENS, MULTICALL_FAILURE, type MaturityTerms, MaxParamThresholds, type MergedUserData, type MidnightBook, type MidnightBookLevel, type MidnightBookSource, type ModeBase, type ModeVariant, type MorphoMarketOverrides, type MorphoSubgraphProxyConfig, type MorphoUserMarketBalance, type MorphoUserReserveResponse, type MorphoVault, type MorphoVaults, type MulticallEndpointOptions, type MulticallRpcBatch, type NumberMap, type Open, type OracleBand, type OracleDiagnostics, type OraclePriceEntry, type OraclePricesResult, type OracleRiskRow, type OracleTerms, type OutlierGuardConfig, type ParsedBalanceData, type ParsedResponse, type ParsedUserBalance, type PermissionKind, type PermissionParams, type PoolData, type PoolWithMeta, type PortfolioSummary, type PortfolioTotals, type PositionConstraints, type PostTradeMetrics, type PreparedCall, type PreparedMergedMulticallParams, type PreparedMergedRpcCalls, type PreparedTokenBalanceRpcCalls, type PreparedUserDataRpcCalls, type PriceDerivation, type PriceSelection, type ProtocolParams, type ProviderOptions, type RateKind, type RateMenuEntry, type RateTerms, type RawRpcBatch, type RawRpcCall, type RawRpcResponse, type ReadFailurePolicy, type ResupplyMarketsRaw, type ResupplyPairIdentity, type ResupplyPairRaw, type ResupplyPositionInfo, type ResupplyWrappedMarket, type RewardTerm, type RiverMarketRaw, type RiverMarketsRaw, type RiverPositionInfo, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, type SelectPricesOptions, type Severity, type SeverityFinding, type SiloVault, type SiloVaults, type StCeloValidatorGroup, type StaleFeedEntry, type StampOptions, type StructuredOraclePrices, type SubAccountSummary, type SumerPositionInput, type SummaryAprData, type SummaryBalanceData, type SupplyExitMode, type SupplyExitTerms, type SupplyTermSheet, TELLER_CALLS_PER_BID, TERMMAX_CALLS_PER_ACCOUNT, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TERM_ADAPTERS, TERM_PROFILES, TERM_SHEET_SCHEMA_VERSION, type TellerDiscoveredBid, type TellerDiscovery, type TellerMarketsRaw, type TellerPoolRaw, type TermAdapter, type TermAssetRef, type TermAuctionOrder, type TermAuctionOrders, type TermBookSource, type TermBookTop, type TermInfo, type TermListing, type TermMarketRaw, TermMaxApiSource, type TermMaxBookTop, type TermMaxCurveSegment, type TermMaxDataSource, type TermMaxDiscovery, type TermMaxFeeConfig, type TermMaxMarketConfig, type TermMaxMarketRaw, type TermMaxOrderState, type TermProfile, type TermSheet, type TermSheetDigest, type TermSheetInput, type TermSheetViolation, TermSubgraphSource, type TermTag, type TokenApprovalMeta, type TokenApprovalParams, type TokenBalanceEntry, type TokenBalanceQuery, type TokenBalanceResult, type TokenEntry, type TokenList, type TokenListInput, type TrackerDiagnostic, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, type USDPriceMap, type UpshiftApiAsset, type UpshiftApiVault, type UpshiftVault, type UpshiftVaults, type UsddMarketRaw, type UsddMarketsRaw, type UsddPositionInfo, type UserApr, type UserConfig, type UserData, type UserDataResult, type UserLendingPosition, type UtilizationTerms, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, type ValidationResult, type VaultAprResult, type VaultClassification, type VaultClassificationFields, type VaultLookupEntry, type VaultMarketExposure, type VaultProvider, type VaultPublicDataAll, type VaultPublicDataResult, type VaultYieldSeries, type VaultYieldSnapshot, type YDaemonVault, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, type YearnVault, type YearnVaultKind, type YearnVaults, type YieldProfile, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, borrowDescription, borrowFindings, borrowHeadline, buildExposures, buildFluidFTokensCall, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, collectFeedObservations, computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta, computeZapTradeDeltas, consensusReference, convertExactlyMarketsToResponse, convertFrankencoinMarketsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, deriveBorrowTags, deriveSupplyTags, detectInterfaceKinds, duration, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchDolomiteAccountNumbers, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchFrankencoinMarkets, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendlePrices, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, finalizeInfo, findingsFor, frankencoinKeyParts, frankencoinLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getReadFailurePolicy, getResolvedDolomiteAccountNumbers, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasUpshiftVaults, hasYearnVaults, inverseKeyParts, inverseLenderKey, isFailedCall, isStablecoinSymbol, isYearnV3, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, mergeDeep, multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTermMaxLtv, parseTokenBalanceResult, pct, positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveAdapter, resolveDerivation, resolveStCeloDepositGroup, resupplyKeyParts, resupplyLenderKey, riverKeyParts, riverLenderKey, selectAssetGroupPrices, shortDate, stampVaultClassification, supplyDescription, supplyFindings, supplyHeadline, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, tickToAprNumber, tickToPrice, toDigest, toTermSheetInput, unflattenLenderData, updateFeedStats, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData };
|