@1delta/margin-fetcher 5.0.0 → 5.0.1
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 +10 -1
- package/dist/index.js +203 -9
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -8767,7 +8767,16 @@ interface AvailabilityTerms {
|
|
|
8767
8767
|
gating: Open<'permissionless' | 'whitelist' | 'attestation' | 'kyc' | 'allowlist-contract'>;
|
|
8768
8768
|
/** Absent ⇒ no window applies. NOT the same as `closed`. */
|
|
8769
8769
|
window?: AuctionWindow;
|
|
8770
|
-
/**
|
|
8770
|
+
/**
|
|
8771
|
+
* Minimum position size to OPEN, in RAW base units of THIS side's asset.
|
|
8772
|
+
*
|
|
8773
|
+
* On the borrow side this is a minimum DEBT (Comet `baseBorrowMin`, Liquity
|
|
8774
|
+
* `minDebt`, Maker-fork `dust`). On the supply/collateral side it is a
|
|
8775
|
+
* minimum COLLATERAL — a genuinely different gate, and the only one some
|
|
8776
|
+
* lenders have: Frankencoin caps nothing on the debt but refuses a position
|
|
8777
|
+
* below `minimumCollateral`, and dropping under it closes the position
|
|
8778
|
+
* permanently.
|
|
8779
|
+
*/
|
|
8771
8780
|
minSize?: string;
|
|
8772
8781
|
cap?: string;
|
|
8773
8782
|
/** 0..1 — how full the cap is. */
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError, erc20Abi, stringToHex, pad, encodeFunctionData, formatUnits, isAddress, getAddress, decodeFunctionResult, decodeAbiParameters, concat, AbiEncodingLengthMismatchError, concatHex, toBytes, slice, hexToString, InvalidAddressError, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-YILYOOYB.js';
|
|
2
2
|
import './chunk-BYTNVMX7.js';
|
|
3
3
|
import './chunk-PR4QN5HX.js';
|
|
4
|
-
import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isUsdd, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite,
|
|
4
|
+
import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isUsdd, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, isFrankencoin, isResupply, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, hasCrossMarginRisk, isEulerType, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isYLDR, isLista, hasSubAccounts, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
|
|
5
5
|
export { hasCrossMarginRisk, isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
6
6
|
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, llamaLendLendersByChain, usddLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, usddConfigFor, usddChainData, frankencoinConfigFor, frankencoinChainData, aaveOracles, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, aaveTokens, morphoTypeVaults, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles } from '@1delta/data-sdk';
|
|
7
7
|
import lodash from 'lodash';
|
|
@@ -61581,6 +61581,32 @@ var TERM_PROFILES = [
|
|
|
61581
61581
|
]
|
|
61582
61582
|
}
|
|
61583
61583
|
}),
|
|
61584
|
+
P({
|
|
61585
|
+
id: "frankencoin.challenge@v1",
|
|
61586
|
+
name: "Frankencoin position",
|
|
61587
|
+
family: "frankencoin",
|
|
61588
|
+
borrow: {
|
|
61589
|
+
description: "A per-position CDP minting ZCHF. There is no price oracle: you DECLARE the liquidation price yourself, and anyone may challenge it with a Dutch auction.",
|
|
61590
|
+
implications: [
|
|
61591
|
+
"Liquidation is NOT driven by your health factor. A challenge succeeds when the market price falls below the price YOU declared, regardless of how much you have borrowed \u2014 repaying does not reduce that risk, only re-declaring the price does.",
|
|
61592
|
+
"You owe more than you received: a 10\u201340 % reserve contribution is withheld at mint, plus an upfront fee. The debt is not the amount you got.",
|
|
61593
|
+
"The position EXPIRES on a fixed date; past it the position can be liquidated."
|
|
61594
|
+
]
|
|
61595
|
+
}
|
|
61596
|
+
}),
|
|
61597
|
+
P({
|
|
61598
|
+
id: "resupply.cdp@v1",
|
|
61599
|
+
name: "Resupply pair",
|
|
61600
|
+
family: "resupply",
|
|
61601
|
+
borrow: {
|
|
61602
|
+
description: "A CDP minting reUSD against a supply position in ANOTHER lending market, held as a staked ERC-4626 share.",
|
|
61603
|
+
implications: [
|
|
61604
|
+
"Redemptions are COMMUNAL: collateral is skimmed pro-rata from every borrower in the pair, so being well-collateralised does not exempt you and there is no rate to raise in defence.",
|
|
61605
|
+
"Your collateral is a lending position elsewhere \u2014 bad debt in that market is bad debt here.",
|
|
61606
|
+
"There is a hard minimum position size: a smaller borrow, or a repay that would leave less than it, reverts."
|
|
61607
|
+
]
|
|
61608
|
+
}
|
|
61609
|
+
}),
|
|
61584
61610
|
// ── Vaults ───────────────────────────────────────────────────────────────
|
|
61585
61611
|
P({
|
|
61586
61612
|
id: "vault.lending@v1",
|
|
@@ -61851,7 +61877,9 @@ function resolveMinDebt(input) {
|
|
|
61851
61877
|
// USDD / Maker-fork: `dust` IS the per-vault debt floor.
|
|
61852
61878
|
m.usdd?.dust,
|
|
61853
61879
|
// Gearbox credit facade.
|
|
61854
|
-
m.gearbox?.minDebt
|
|
61880
|
+
m.gearbox?.minDebt,
|
|
61881
|
+
// Resupply — a hard per-position floor that also bounds partial repayment.
|
|
61882
|
+
m.resupply?.minimumBorrowAmount
|
|
61855
61883
|
];
|
|
61856
61884
|
for (const c of candidates) {
|
|
61857
61885
|
if (c == null) continue;
|
|
@@ -61862,6 +61890,14 @@ function resolveMinDebt(input) {
|
|
|
61862
61890
|
}
|
|
61863
61891
|
return void 0;
|
|
61864
61892
|
}
|
|
61893
|
+
function resolveMinCollateral(input) {
|
|
61894
|
+
const m = input.market ?? {};
|
|
61895
|
+
const raw = m.frankencoin?.minimumCollateral;
|
|
61896
|
+
if (raw == null) return void 0;
|
|
61897
|
+
const str3 = String(raw);
|
|
61898
|
+
if (str3 === "0" || str3 === "" || !/^\d+$/.test(str3)) return void 0;
|
|
61899
|
+
return str3;
|
|
61900
|
+
}
|
|
61865
61901
|
function capUtil(total, cap) {
|
|
61866
61902
|
if (!isNum(cap) || cap <= 0 || !isNum(total)) return void 0;
|
|
61867
61903
|
return clamp01(total / cap);
|
|
@@ -61893,7 +61929,7 @@ function buildAvailability(input, side) {
|
|
|
61893
61929
|
gating: "permissionless",
|
|
61894
61930
|
// A borrow below the protocol's floor REVERTS, so gate the CTA on it
|
|
61895
61931
|
// rather than letting the transaction fail.
|
|
61896
|
-
minSize: side === "borrow" ? resolveMinDebt(input) :
|
|
61932
|
+
minSize: side === "borrow" ? resolveMinDebt(input) : resolveMinCollateral(input),
|
|
61897
61933
|
cap: isNum(cap) && cap > 0 ? String(cap) : void 0,
|
|
61898
61934
|
capUtilization,
|
|
61899
61935
|
requires: side === "supply" ? ["token-approval"] : void 0
|
|
@@ -63060,6 +63096,158 @@ var llamaLendAdapter = {
|
|
|
63060
63096
|
};
|
|
63061
63097
|
}
|
|
63062
63098
|
};
|
|
63099
|
+
var ppmToPercent = (v) => {
|
|
63100
|
+
if (v == null) return void 0;
|
|
63101
|
+
const n = Number(v);
|
|
63102
|
+
return Number.isFinite(n) ? n / 1e4 : void 0;
|
|
63103
|
+
};
|
|
63104
|
+
var frankencoinAdapter = {
|
|
63105
|
+
id: "frankencoin",
|
|
63106
|
+
matches: isFrankencoin,
|
|
63107
|
+
profileId: () => "frankencoin.challenge@v1",
|
|
63108
|
+
build: (input) => {
|
|
63109
|
+
const fc = input.market?.frankencoin ?? {};
|
|
63110
|
+
const reservePct = ppmToPercent(fc.reserveContributionPPM);
|
|
63111
|
+
const upfrontPct = ppmToPercent(fc.upfrontFeePPM);
|
|
63112
|
+
const challengerPct = ppmToPercent(fc.challengerRewardPPM);
|
|
63113
|
+
const expiration = Number(fc.expiration ?? 0);
|
|
63114
|
+
const challengePeriod = Number(fc.challengePeriod ?? 0);
|
|
63115
|
+
const fees = [
|
|
63116
|
+
reservePct != null && reservePct > 0 ? {
|
|
63117
|
+
id: "reserve-contribution",
|
|
63118
|
+
label: "Equity-reserve contribution",
|
|
63119
|
+
when: "entry",
|
|
63120
|
+
unit: "percent",
|
|
63121
|
+
basis: "principal",
|
|
63122
|
+
value: reservePct,
|
|
63123
|
+
payee: "protocol",
|
|
63124
|
+
description: "Withheld at mint into the FPS equity reserve. You owe the full amount but receive this much less, so the debt is NOT what you got."
|
|
63125
|
+
} : null,
|
|
63126
|
+
upfrontPct != null && upfrontPct > 0 ? {
|
|
63127
|
+
id: "origination",
|
|
63128
|
+
label: "Upfront interest",
|
|
63129
|
+
when: "entry",
|
|
63130
|
+
unit: "percent",
|
|
63131
|
+
basis: "principal",
|
|
63132
|
+
value: upfrontPct,
|
|
63133
|
+
payee: "protocol",
|
|
63134
|
+
description: "Charged once at mint, pro-rated over the time to expiry."
|
|
63135
|
+
} : null
|
|
63136
|
+
].filter(Boolean);
|
|
63137
|
+
return {
|
|
63138
|
+
// Not a coverage hole: the protocol has no price feed by design.
|
|
63139
|
+
oracle: { kind: "none" },
|
|
63140
|
+
borrow: {
|
|
63141
|
+
debtShape: "accruing",
|
|
63142
|
+
maturity: expiration > 0 ? {
|
|
63143
|
+
kind: "fixed-date",
|
|
63144
|
+
maturity: expiration,
|
|
63145
|
+
maturityIso: new Date(expiration * 1e3).toISOString(),
|
|
63146
|
+
atMaturity: "liquidatable"
|
|
63147
|
+
} : void 0,
|
|
63148
|
+
exit: {
|
|
63149
|
+
// Repaying is not free here: the reserve haircut means the net cost
|
|
63150
|
+
// is `faceDelta − assignedReserve`, and it is resolved at repay time.
|
|
63151
|
+
earlyRepay: "discount",
|
|
63152
|
+
atMaturityCost: "accrued",
|
|
63153
|
+
lateBehaviour: "liquidatable",
|
|
63154
|
+
partialAllowed: true
|
|
63155
|
+
},
|
|
63156
|
+
liquidation: {
|
|
63157
|
+
// A Dutch-auction challenge, not a repay-and-seize.
|
|
63158
|
+
model: "auction",
|
|
63159
|
+
absorber: "liquidator",
|
|
63160
|
+
// Price-triggered, but against the OWNER-DECLARED price — and with
|
|
63161
|
+
// no health gate whatsoever.
|
|
63162
|
+
trigger: "price",
|
|
63163
|
+
seizure: "proportional",
|
|
63164
|
+
permissioned: false,
|
|
63165
|
+
windowSecs: challengePeriod > 0 ? challengePeriod : void 0,
|
|
63166
|
+
penalty: challengerPct != null ? challengerPct / 100 : 0,
|
|
63167
|
+
penalties: challengerPct != null ? [
|
|
63168
|
+
{
|
|
63169
|
+
id: "challenger-reward",
|
|
63170
|
+
label: "Challenger reward",
|
|
63171
|
+
value: challengerPct / 100,
|
|
63172
|
+
description: "Paid to whoever successfully challenges the declared price."
|
|
63173
|
+
}
|
|
63174
|
+
] : void 0,
|
|
63175
|
+
badDebt: "socialized"
|
|
63176
|
+
},
|
|
63177
|
+
fees,
|
|
63178
|
+
counterparty: { kind: "cdp", solvency: "overcollateralized" }
|
|
63179
|
+
},
|
|
63180
|
+
constraints: {
|
|
63181
|
+
crossMargin: false,
|
|
63182
|
+
// Each position is its own CONTRACT, cloned from an "original".
|
|
63183
|
+
positionModel: "account",
|
|
63184
|
+
positionIdMeaning: "Each position is its own contract, cloned from the market\u2019s original position; you own the clone."
|
|
63185
|
+
}
|
|
63186
|
+
};
|
|
63187
|
+
}
|
|
63188
|
+
};
|
|
63189
|
+
var e5ToFraction = (v) => {
|
|
63190
|
+
if (v == null) return void 0;
|
|
63191
|
+
const n = Number(v);
|
|
63192
|
+
return Number.isFinite(n) ? n / 1e5 : void 0;
|
|
63193
|
+
};
|
|
63194
|
+
var resupplyAdapter = {
|
|
63195
|
+
id: "resupply",
|
|
63196
|
+
matches: isResupply,
|
|
63197
|
+
profileId: () => "resupply.cdp@v1",
|
|
63198
|
+
build: (input) => {
|
|
63199
|
+
const rs = input.market?.resupply ?? {};
|
|
63200
|
+
const liquidationFee = e5ToFraction(rs.liquidationFee);
|
|
63201
|
+
const mintFee = e5ToFraction(rs.mintFee);
|
|
63202
|
+
const minBorrow = rs.minimumBorrowAmount != null && String(rs.minimumBorrowAmount) !== "0" ? String(rs.minimumBorrowAmount) : void 0;
|
|
63203
|
+
return {
|
|
63204
|
+
borrow: {
|
|
63205
|
+
debtShape: "accruing",
|
|
63206
|
+
exit: {
|
|
63207
|
+
earlyRepay: "free",
|
|
63208
|
+
atMaturityCost: "accrued",
|
|
63209
|
+
lateBehaviour: "none",
|
|
63210
|
+
partialAllowed: true,
|
|
63211
|
+
// The floor bounds repayment too: a partial repay may not leave the
|
|
63212
|
+
// position under it.
|
|
63213
|
+
minDebt: minBorrow
|
|
63214
|
+
},
|
|
63215
|
+
liquidation: {
|
|
63216
|
+
model: "repay-seize",
|
|
63217
|
+
absorber: "liquidator",
|
|
63218
|
+
trigger: "price",
|
|
63219
|
+
seizure: "proportional",
|
|
63220
|
+
penalty: liquidationFee ?? 0,
|
|
63221
|
+
// Every borrower in the pair is exposed, not just the marginal one.
|
|
63222
|
+
redeemable: true,
|
|
63223
|
+
badDebt: "socialized"
|
|
63224
|
+
},
|
|
63225
|
+
fees: mintFee != null && mintFee > 0 ? [
|
|
63226
|
+
{
|
|
63227
|
+
id: "origination",
|
|
63228
|
+
label: "Mint fee",
|
|
63229
|
+
when: "entry",
|
|
63230
|
+
unit: "percent",
|
|
63231
|
+
basis: "principal",
|
|
63232
|
+
value: mintFee * 100,
|
|
63233
|
+
payee: "protocol"
|
|
63234
|
+
}
|
|
63235
|
+
] : void 0,
|
|
63236
|
+
availability: minBorrow ? { minSize: minBorrow } : void 0,
|
|
63237
|
+
counterparty: { kind: "cdp", solvency: "overcollateralized" }
|
|
63238
|
+
},
|
|
63239
|
+
supply: {
|
|
63240
|
+
// The collateral is itself a lending position elsewhere.
|
|
63241
|
+
principal: { protected: false, risks: ["bad-debt"] }
|
|
63242
|
+
},
|
|
63243
|
+
constraints: {
|
|
63244
|
+
crossMargin: false,
|
|
63245
|
+
positionModel: "account",
|
|
63246
|
+
positionIdMeaning: "One position per address per pair \u2014 address-keyed, no discovery."
|
|
63247
|
+
}
|
|
63248
|
+
};
|
|
63249
|
+
}
|
|
63250
|
+
};
|
|
63063
63251
|
|
|
63064
63252
|
// src/terms/adapters/index.ts
|
|
63065
63253
|
var TERM_ADAPTERS = [
|
|
@@ -63076,7 +63264,9 @@ var TERM_ADAPTERS = [
|
|
|
63076
63264
|
compoundV3Adapter,
|
|
63077
63265
|
fluidAdapter,
|
|
63078
63266
|
gearboxAdapter,
|
|
63079
|
-
llamaLendAdapter
|
|
63267
|
+
llamaLendAdapter,
|
|
63268
|
+
frankencoinAdapter,
|
|
63269
|
+
resupplyAdapter
|
|
63080
63270
|
];
|
|
63081
63271
|
function resolveAdapter(lender) {
|
|
63082
63272
|
return TERM_ADAPTERS.find((a) => a.matches(lender));
|
|
@@ -63470,11 +63660,15 @@ function validateTermSheet(sheet) {
|
|
|
63470
63660
|
if (o) {
|
|
63471
63661
|
if (o.kind === "none" && o.address)
|
|
63472
63662
|
fail("oracle-none-address", "oracle.kind none must not carry an address");
|
|
63473
|
-
if (o.kind === "none" && sheet.borrow
|
|
63474
|
-
|
|
63475
|
-
|
|
63476
|
-
|
|
63477
|
-
|
|
63663
|
+
if (o.kind === "none" && sheet.borrow) {
|
|
63664
|
+
const t = sheet.borrow.liquidation.trigger;
|
|
63665
|
+
const m = sheet.borrow.liquidation.model;
|
|
63666
|
+
if (t !== "time" && t !== "none" && m !== "auction")
|
|
63667
|
+
fail(
|
|
63668
|
+
"no-oracle-non-time",
|
|
63669
|
+
`oracle.kind none but liquidation.trigger is ${t} with model ${m ?? "unset"}`
|
|
63670
|
+
);
|
|
63671
|
+
}
|
|
63478
63672
|
if (o.address && o.address !== o.address.toLowerCase())
|
|
63479
63673
|
fail("oracle-lowercase", "oracle.address must be lowercased");
|
|
63480
63674
|
}
|