@continuumdao/ctm-mpc-defi 0.2.30 → 0.2.32
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/agent/catalog.cjs +1933 -56
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +3671 -661
- package/dist/agent/catalog.js +1896 -58
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aerodrome/SKILL.md +93 -0
- package/dist/agent/skills/compound-v3/SKILL.md +132 -0
- package/dist/agent/skills/euler-v2/SKILL.md +1 -1
- package/dist/agent/skills/morpho/SKILL.md +16 -8
- package/dist/buildBatch-CngvebiD.d.ts +45 -0
- package/dist/chains/evm/index.d.ts +6 -44
- package/dist/core/index.cjs +2 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +119 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +119 -2
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aerodrome/index.cjs +3922 -0
- package/dist/protocols/evm/aerodrome/index.cjs.map +1 -0
- package/dist/protocols/evm/aerodrome/index.d.ts +792 -0
- package/dist/protocols/evm/aerodrome/index.js +3843 -0
- package/dist/protocols/evm/aerodrome/index.js.map +1 -0
- package/dist/protocols/evm/compound-v3/index.cjs +1542 -0
- package/dist/protocols/evm/compound-v3/index.cjs.map +1 -0
- package/dist/protocols/evm/compound-v3/index.d.ts +683 -0
- package/dist/protocols/evm/compound-v3/index.js +1488 -0
- package/dist/protocols/evm/compound-v3/index.js.map +1 -0
- package/dist/protocols/evm/euler-v2/index.cjs +17 -10
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.js +17 -10
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/morpho/index.cjs +746 -39
- package/dist/protocols/evm/morpho/index.cjs.map +1 -1
- package/dist/protocols/evm/morpho/index.d.ts +161 -14
- package/dist/protocols/evm/morpho/index.js +736 -42
- package/dist/protocols/evm/morpho/index.js.map +1 -1
- package/package.json +15 -1
|
@@ -47,17 +47,27 @@ var init_defiProxy = __esm({
|
|
|
47
47
|
// src/protocols/evm/morpho/midnightConstants.ts
|
|
48
48
|
var midnightConstants_exports = {};
|
|
49
49
|
__export(midnightConstants_exports, {
|
|
50
|
+
MORPHO_BLUE_CANONICAL: () => exports.MORPHO_BLUE_CANONICAL,
|
|
50
51
|
MORPHO_MIDNIGHT_ADDRESSES: () => exports.MORPHO_MIDNIGHT_ADDRESSES,
|
|
51
52
|
MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS,
|
|
52
53
|
MORPHO_MIDNIGHT_BASE_CHAIN_ID: () => exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID,
|
|
54
|
+
MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS,
|
|
55
|
+
MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS,
|
|
53
56
|
MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT: () => exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT,
|
|
54
57
|
MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS,
|
|
58
|
+
MORPHO_MIDNIGHT_CALLBACK_SALT: () => exports.MORPHO_MIDNIGHT_CALLBACK_SALT,
|
|
59
|
+
MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS,
|
|
55
60
|
MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS: () => exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS,
|
|
61
|
+
MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS: () => exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS,
|
|
56
62
|
MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT: () => exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT,
|
|
57
63
|
MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK: () => exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK,
|
|
64
|
+
MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID: () => exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID,
|
|
58
65
|
MORPHO_MIDNIGHT_LEND_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_LEND_FALLBACK_GAS,
|
|
66
|
+
MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS,
|
|
59
67
|
MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS,
|
|
60
68
|
MORPHO_MIDNIGHT_REST_BASE: () => exports.MORPHO_MIDNIGHT_REST_BASE,
|
|
69
|
+
MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS,
|
|
70
|
+
MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS: () => exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS,
|
|
61
71
|
MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK: () => exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK,
|
|
62
72
|
TOKEN_PERMIT_NONE: () => exports.TOKEN_PERMIT_NONE,
|
|
63
73
|
morphoMidnightAddressesForChain: () => morphoMidnightAddressesForChain
|
|
@@ -65,18 +75,36 @@ __export(midnightConstants_exports, {
|
|
|
65
75
|
function morphoMidnightAddressesForChain(chainId) {
|
|
66
76
|
return exports.MORPHO_MIDNIGHT_ADDRESSES[chainId] ?? null;
|
|
67
77
|
}
|
|
68
|
-
exports.MORPHO_MIDNIGHT_REST_BASE = void 0; exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS = void 0; exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID = void 0; exports.MORPHO_MIDNIGHT_ADDRESSES = void 0; exports.TOKEN_PERMIT_NONE = void 0; exports.MORPHO_MIDNIGHT_LEND_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK = void 0; exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK = void 0;
|
|
78
|
+
exports.MORPHO_MIDNIGHT_REST_BASE = void 0; exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS = void 0; exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS = void 0; exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID = void 0; exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID = void 0; exports.MORPHO_BLUE_CANONICAL = void 0; exports.MORPHO_MIDNIGHT_CALLBACK_SALT = void 0; exports.MORPHO_MIDNIGHT_ADDRESSES = void 0; exports.TOKEN_PERMIT_NONE = void 0; exports.MORPHO_MIDNIGHT_LEND_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BORROW_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_REPAY_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK = void 0; exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK = void 0; exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS = void 0; exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS = void 0;
|
|
69
79
|
var init_midnightConstants = __esm({
|
|
70
80
|
"src/protocols/evm/morpho/midnightConstants.ts"() {
|
|
71
81
|
exports.MORPHO_MIDNIGHT_REST_BASE = "https://api.morpho.org/v0/midnight";
|
|
72
82
|
exports.MORPHO_MIDNIGHT_BOOKS_MAX_LIMIT = 20;
|
|
73
83
|
exports.MORPHO_MIDNIGHT_DEFAULT_SLIPPAGE_PCT = "0.5";
|
|
74
84
|
exports.MORPHO_MIDNIGHT_DEFAULT_DEADLINE_SECONDS = 3600;
|
|
85
|
+
exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS = 7 * 24 * 3600;
|
|
75
86
|
exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID = 8453;
|
|
87
|
+
exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID = 1;
|
|
88
|
+
exports.MORPHO_BLUE_CANONICAL = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb";
|
|
89
|
+
exports.MORPHO_MIDNIGHT_CALLBACK_SALT = viem.keccak256(viem.toBytes("continuum-midnight-lend-v1"));
|
|
76
90
|
exports.MORPHO_MIDNIGHT_ADDRESSES = {
|
|
91
|
+
[exports.MORPHO_MIDNIGHT_ETHEREUM_CHAIN_ID]: {
|
|
92
|
+
midnight: "0x471686c42792F93528B000beF54bC10E3aa2045f",
|
|
93
|
+
bundles: "0x7c00dBB2b6b6b9B28745332e550dC8782Fcf77EC",
|
|
94
|
+
mempool: "0xde2d62449301a09A51EbF9326EA60d2e8BF4A8F7",
|
|
95
|
+
setterRatifier: "0xb72c416382c8A6399D0765CebfB032F040B00B3c",
|
|
96
|
+
ecrecoverRatifier: "0xAC439c81CAA6ef4C7B7E8F0110F8CE63A4b6D43e",
|
|
97
|
+
blueBuyCallbackFactory: "0x172d1FdC5f79bFe1ED46448f18541E591E5c93a7",
|
|
98
|
+
morphoBlue: exports.MORPHO_BLUE_CANONICAL
|
|
99
|
+
},
|
|
77
100
|
[exports.MORPHO_MIDNIGHT_BASE_CHAIN_ID]: {
|
|
78
|
-
midnight: "
|
|
79
|
-
bundles: "
|
|
101
|
+
midnight: "0xAdedD8ab6dE832766Fedf0FaC4992E5C4D3EA18A",
|
|
102
|
+
bundles: "0x091183d729BE9f808c212b475E387A12E67850A7",
|
|
103
|
+
mempool: "0xdD6DCE32e21f7b020898a8258dA37355b4017993",
|
|
104
|
+
setterRatifier: "0x800B5F12A61B8198a5a6EfD794Cac6699B294d63",
|
|
105
|
+
ecrecoverRatifier: "0xd6e70365C8E8DDa9a4ca662C07bbE663b017755E",
|
|
106
|
+
blueBuyCallbackFactory: "0x7337f119Eca028bD39E0e543cEf71631D2333425",
|
|
107
|
+
morphoBlue: exports.MORPHO_BLUE_CANONICAL
|
|
80
108
|
}
|
|
81
109
|
};
|
|
82
110
|
exports.TOKEN_PERMIT_NONE = { kind: 0, data: "0x" };
|
|
@@ -86,6 +114,12 @@ var init_midnightConstants = __esm({
|
|
|
86
114
|
exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS = 80000n;
|
|
87
115
|
exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK = 100000n;
|
|
88
116
|
exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK = 120000n;
|
|
117
|
+
exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS = 1200000n;
|
|
118
|
+
exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS = 400000n;
|
|
119
|
+
exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS = 350000n;
|
|
120
|
+
exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS = 80000n;
|
|
121
|
+
exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS = 250000n;
|
|
122
|
+
exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS = 80000n;
|
|
89
123
|
}
|
|
90
124
|
});
|
|
91
125
|
|
|
@@ -95,6 +129,7 @@ __export(midnightApi_exports, {
|
|
|
95
129
|
fetchMorphoMidnightBook: () => fetchMorphoMidnightBook,
|
|
96
130
|
fetchMorphoMidnightBookQuote: () => fetchMorphoMidnightBookQuote,
|
|
97
131
|
fetchMorphoMidnightBooks: () => fetchMorphoMidnightBooks,
|
|
132
|
+
fetchMorphoMidnightMakerOffers: () => fetchMorphoMidnightMakerOffers,
|
|
98
133
|
fetchMorphoMidnightMarketById: () => fetchMorphoMidnightMarketById,
|
|
99
134
|
fetchMorphoMidnightUserMarketPosition: () => fetchMorphoMidnightUserMarketPosition,
|
|
100
135
|
fetchMorphoMidnightUserPositions: () => fetchMorphoMidnightUserPositions,
|
|
@@ -237,6 +272,39 @@ async function fetchMorphoMidnightUserPositions(args) {
|
|
|
237
272
|
}
|
|
238
273
|
return rows;
|
|
239
274
|
}
|
|
275
|
+
async function fetchMorphoMidnightMakerOffers(args) {
|
|
276
|
+
const qs = new URLSearchParams();
|
|
277
|
+
qs.set("maker", viem.getAddress(args.maker));
|
|
278
|
+
if (args.chainId != null) qs.set("chain_ids", String(args.chainId));
|
|
279
|
+
const j = await midnightGetJson(`/takeable-offers?${qs}`);
|
|
280
|
+
const out = [];
|
|
281
|
+
for (const row of j.data ?? []) {
|
|
282
|
+
const o = row.offer;
|
|
283
|
+
if (!o?.maker || !viem.isAddress(o.maker) || !o.market?.loan_token || !viem.isAddress(o.market.loan_token)) continue;
|
|
284
|
+
if (!o.market.midnight || !viem.isAddress(o.market.midnight)) continue;
|
|
285
|
+
const group = (o.group ?? "").trim();
|
|
286
|
+
if (!group.startsWith("0x") || group.length !== 66) continue;
|
|
287
|
+
const callback = o.callback && viem.isAddress(o.callback) ? viem.getAddress(o.callback) : "0x0000000000000000000000000000000000000000";
|
|
288
|
+
out.push({
|
|
289
|
+
marketId: String(row.market_id ?? ""),
|
|
290
|
+
chainId: Number(o.market.chain_id ?? args.chainId ?? 0),
|
|
291
|
+
midnight: viem.getAddress(o.market.midnight),
|
|
292
|
+
loanToken: viem.getAddress(o.market.loan_token),
|
|
293
|
+
maker: viem.getAddress(o.maker),
|
|
294
|
+
buy: o.buy === true,
|
|
295
|
+
tick: String(o.tick ?? "0"),
|
|
296
|
+
maxAssets: String(o.max_assets ?? "0"),
|
|
297
|
+
maxUnits: String(o.max_units ?? "0"),
|
|
298
|
+
expiry: Number(o.expiry ?? 0),
|
|
299
|
+
group,
|
|
300
|
+
callback,
|
|
301
|
+
callbackData: o.callback_data ?? "0x",
|
|
302
|
+
units: String(row.units ?? "0"),
|
|
303
|
+
maturity: o.market.maturity != null ? Number(o.market.maturity) : null
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return out;
|
|
307
|
+
}
|
|
240
308
|
async function fetchMorphoMidnightUserMarketPosition(args) {
|
|
241
309
|
const marketId = args.marketId.trim();
|
|
242
310
|
const user = args.user.trim();
|
|
@@ -1463,18 +1531,43 @@ async function fetchMorphoMidnightIntents(_args) {
|
|
|
1463
1531
|
// src/protocols/evm/morpho/index.ts
|
|
1464
1532
|
init_midnightConstants();
|
|
1465
1533
|
init_midnightApi();
|
|
1466
|
-
|
|
1467
|
-
|
|
1534
|
+
var WAD = 10n ** 18n;
|
|
1535
|
+
var SECONDS_PER_YEAR = 365 * 86400;
|
|
1536
|
+
function parseMorphoMidnightPriceWad(priceWad) {
|
|
1537
|
+
if (priceWad == null) return null;
|
|
1538
|
+
try {
|
|
1539
|
+
if (typeof priceWad === "bigint") return priceWad > 0n ? priceWad : null;
|
|
1540
|
+
if (typeof priceWad === "number") {
|
|
1541
|
+
if (!Number.isFinite(priceWad) || priceWad <= 0) return null;
|
|
1542
|
+
return BigInt(Math.round(priceWad));
|
|
1543
|
+
}
|
|
1544
|
+
const raw = BigInt(String(priceWad).split(".")[0] || "0");
|
|
1545
|
+
return raw > 0n ? raw : null;
|
|
1546
|
+
} catch {
|
|
1547
|
+
return null;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1468
1550
|
function morphoMidnightAprFromPriceWad(priceWad, ttmSeconds) {
|
|
1469
|
-
const raw =
|
|
1470
|
-
if (raw
|
|
1551
|
+
const raw = parseMorphoMidnightPriceWad(priceWad);
|
|
1552
|
+
if (raw == null || !Number.isFinite(ttmSeconds) || ttmSeconds <= 0) return null;
|
|
1471
1553
|
const p = Number(raw) / 1e18;
|
|
1472
1554
|
if (!Number.isFinite(p) || p <= 0) return null;
|
|
1473
|
-
const apr = (1 / p - 1) * (
|
|
1555
|
+
const apr = (1 / p - 1) * (SECONDS_PER_YEAR / ttmSeconds);
|
|
1474
1556
|
return Number.isFinite(apr) ? apr : null;
|
|
1475
1557
|
}
|
|
1476
|
-
function
|
|
1477
|
-
if (
|
|
1558
|
+
function morphoMidnightAprFromBookLevel(level, ttmSeconds) {
|
|
1559
|
+
if (!level || !Number.isFinite(ttmSeconds) || ttmSeconds <= 0) return null;
|
|
1560
|
+
if (level.tick != null && String(level.tick).trim() !== "") {
|
|
1561
|
+
try {
|
|
1562
|
+
const fromTick = morphoMidnightAprFromTick(BigInt(level.tick), ttmSeconds);
|
|
1563
|
+
if (fromTick != null) return fromTick;
|
|
1564
|
+
} catch {
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
return level.price != null ? morphoMidnightAprFromPriceWad(level.price, ttmSeconds) : null;
|
|
1568
|
+
}
|
|
1569
|
+
function formatMorphoMidnightAprPct(apr, digits = 2, empty = "\u2014") {
|
|
1570
|
+
if (apr == null || !Number.isFinite(apr)) return empty;
|
|
1478
1571
|
return `${(apr * 100).toFixed(digits)}%`;
|
|
1479
1572
|
}
|
|
1480
1573
|
function morphoMidnightTtmSeconds(maturityUnix, nowMs = Date.now()) {
|
|
@@ -1484,6 +1577,37 @@ function morphoMidnightUnitsFromAssets(targetAssets, priceWad) {
|
|
|
1484
1577
|
if (priceWad <= 0n || targetAssets <= 0n) return 0n;
|
|
1485
1578
|
return (targetAssets * 10n ** 18n + priceWad - 1n) / priceWad;
|
|
1486
1579
|
}
|
|
1580
|
+
function parseMorphoMidnightAprInput(raw) {
|
|
1581
|
+
const t = raw.trim().replace(/%/g, "");
|
|
1582
|
+
if (!t || !/^\d*\.?\d+$/.test(t)) return null;
|
|
1583
|
+
const n = Number(t);
|
|
1584
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
1585
|
+
return n > 1 ? n / 100 : n;
|
|
1586
|
+
}
|
|
1587
|
+
function morphoMidnightPriceWadFromApr(apr, ttmSeconds) {
|
|
1588
|
+
if (!Number.isFinite(apr) || apr <= 0 || !Number.isFinite(ttmSeconds) || ttmSeconds <= 0) return null;
|
|
1589
|
+
const price = 1 / (1 + apr * (ttmSeconds / SECONDS_PER_YEAR));
|
|
1590
|
+
if (!Number.isFinite(price) || price <= 0 || price > 1) return null;
|
|
1591
|
+
return BigInt(Math.round(price * 1e18));
|
|
1592
|
+
}
|
|
1593
|
+
function morphoMidnightTickFromPriceWad(priceWad, spacing = midnightSdk.DEFAULT_TICK_SPACING) {
|
|
1594
|
+
return midnightSdk.TickLib.priceToTick(priceWad, spacing);
|
|
1595
|
+
}
|
|
1596
|
+
function morphoMidnightTickFromApr(apr, ttmSeconds, spacing = midnightSdk.DEFAULT_TICK_SPACING) {
|
|
1597
|
+
const priceWad = morphoMidnightPriceWadFromApr(apr, ttmSeconds);
|
|
1598
|
+
if (priceWad == null) return null;
|
|
1599
|
+
return morphoMidnightTickFromPriceWad(priceWad, spacing);
|
|
1600
|
+
}
|
|
1601
|
+
function morphoMidnightAprFromTick(tick, ttmSeconds) {
|
|
1602
|
+
if (ttmSeconds <= 0) return null;
|
|
1603
|
+
try {
|
|
1604
|
+
const aprWad = midnightSdk.TickLib.tickToApr(tick, BigInt(Math.floor(ttmSeconds)));
|
|
1605
|
+
const n = Number(aprWad) / Number(WAD);
|
|
1606
|
+
return Number.isFinite(n) ? n : null;
|
|
1607
|
+
} catch {
|
|
1608
|
+
return morphoMidnightAprFromPriceWad(midnightSdk.TickLib.tickToPrice(tick), ttmSeconds);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1487
1611
|
|
|
1488
1612
|
// src/protocols/evm/morpho/midnightDiscovery.ts
|
|
1489
1613
|
init_midnightApi();
|
|
@@ -1501,10 +1625,10 @@ function maturityIso(maturity) {
|
|
|
1501
1625
|
}
|
|
1502
1626
|
function morphoMidnightBookToDiscoveryRow(book) {
|
|
1503
1627
|
const ttm = morphoMidnightTtmSeconds(book.maturity);
|
|
1504
|
-
const bestAsk = book.asks[0];
|
|
1505
|
-
const bestBid = book.bids[0];
|
|
1506
|
-
const lendAprN =
|
|
1507
|
-
const borrowAprN =
|
|
1628
|
+
const bestAsk = book.asks?.[0];
|
|
1629
|
+
const bestBid = book.bids?.[0];
|
|
1630
|
+
const lendAprN = morphoMidnightAprFromBookLevel(bestAsk, ttm);
|
|
1631
|
+
const borrowAprN = morphoMidnightAprFromBookLevel(bestBid, ttm);
|
|
1508
1632
|
const loan = viem.getAddress(book.loanToken);
|
|
1509
1633
|
const collaterals = book.collaterals.map((c) => viem.getAddress(c.token));
|
|
1510
1634
|
const primary = book.collaterals[0];
|
|
@@ -1524,8 +1648,8 @@ function morphoMidnightBookToDiscoveryRow(book) {
|
|
|
1524
1648
|
bestBidPriceWad: bestBid?.price ?? null,
|
|
1525
1649
|
bestAskAssets: bestAsk?.assets ?? null,
|
|
1526
1650
|
bestBidAssets: bestBid?.assets ?? null,
|
|
1527
|
-
lendApr: formatMorphoMidnightAprPct(lendAprN),
|
|
1528
|
-
borrowApr: formatMorphoMidnightAprPct(borrowAprN),
|
|
1651
|
+
lendApr: formatMorphoMidnightAprPct(lendAprN, 2, "No asks"),
|
|
1652
|
+
borrowApr: formatMorphoMidnightAprPct(borrowAprN, 2, "No bids"),
|
|
1529
1653
|
lendAprNumeric: lendAprN,
|
|
1530
1654
|
borrowAprNumeric: borrowAprN,
|
|
1531
1655
|
marketLabel
|
|
@@ -1705,6 +1829,122 @@ async function morphoFetchMidnightPositionsSummary(args) {
|
|
|
1705
1829
|
return { positions: rows.map(morphoMidnightPositionToDiscoveryRow) };
|
|
1706
1830
|
}
|
|
1707
1831
|
|
|
1832
|
+
// src/protocols/evm/morpho/midnightOffers.ts
|
|
1833
|
+
init_midnightApi();
|
|
1834
|
+
function isoFromUnix(sec) {
|
|
1835
|
+
if (sec == null || sec <= 0) return "\u2014";
|
|
1836
|
+
try {
|
|
1837
|
+
return new Date(sec * 1e3).toISOString().slice(0, 10);
|
|
1838
|
+
} catch {
|
|
1839
|
+
return "\u2014";
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
async function morphoFetchMidnightMakerOffersSummary(args) {
|
|
1843
|
+
if (!viem.isAddress(args.user)) {
|
|
1844
|
+
throw new Error("user must be a valid EVM address.");
|
|
1845
|
+
}
|
|
1846
|
+
const rows = await fetchMorphoMidnightMakerOffers({
|
|
1847
|
+
maker: viem.getAddress(args.user),
|
|
1848
|
+
chainId: args.chainId
|
|
1849
|
+
});
|
|
1850
|
+
const offers = [];
|
|
1851
|
+
for (const r of rows) {
|
|
1852
|
+
if (!r.buy) continue;
|
|
1853
|
+
const ttm = r.maturity != null ? morphoMidnightTtmSeconds(r.maturity) : 0;
|
|
1854
|
+
let tick = 0n;
|
|
1855
|
+
try {
|
|
1856
|
+
tick = BigInt(r.tick);
|
|
1857
|
+
} catch {
|
|
1858
|
+
tick = 0n;
|
|
1859
|
+
}
|
|
1860
|
+
const apr = ttm > 0 && tick > 0n ? morphoMidnightAprFromTick(tick, ttm) : null;
|
|
1861
|
+
offers.push({
|
|
1862
|
+
marketId: r.marketId,
|
|
1863
|
+
chainId: r.chainId,
|
|
1864
|
+
midnightAddress: r.midnight,
|
|
1865
|
+
loanTokenAddress: r.loanToken,
|
|
1866
|
+
maker: r.maker,
|
|
1867
|
+
group: r.group,
|
|
1868
|
+
callback: r.callback,
|
|
1869
|
+
callbackData: r.callbackData,
|
|
1870
|
+
tick: r.tick,
|
|
1871
|
+
maxAssets: r.maxAssets,
|
|
1872
|
+
remainingUnits: r.units,
|
|
1873
|
+
expiry: r.expiry,
|
|
1874
|
+
expiryIso: isoFromUnix(r.expiry),
|
|
1875
|
+
maturity: r.maturity,
|
|
1876
|
+
maturityIso: isoFromUnix(r.maturity),
|
|
1877
|
+
lendApr: formatMorphoMidnightAprPct(apr),
|
|
1878
|
+
lendAprNumeric: apr,
|
|
1879
|
+
marketLabel: `Offer \xB7 ${isoFromUnix(r.maturity)} \xB7 ${formatMorphoMidnightAprPct(apr)}`
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
return { offers };
|
|
1883
|
+
}
|
|
1884
|
+
var BLUE_MARKET_PARAMS_ABI = [
|
|
1885
|
+
{
|
|
1886
|
+
type: "tuple",
|
|
1887
|
+
components: [
|
|
1888
|
+
{ name: "loanToken", type: "address" },
|
|
1889
|
+
{ name: "collateralToken", type: "address" },
|
|
1890
|
+
{ name: "oracle", type: "address" },
|
|
1891
|
+
{ name: "irm", type: "address" },
|
|
1892
|
+
{ name: "lltv", type: "uint256" }
|
|
1893
|
+
]
|
|
1894
|
+
}
|
|
1895
|
+
];
|
|
1896
|
+
function encodeMorphoBlueMarketParamsCallbackData(params) {
|
|
1897
|
+
return viem.encodeAbiParameters(BLUE_MARKET_PARAMS_ABI, [
|
|
1898
|
+
{
|
|
1899
|
+
loanToken: params.loanToken,
|
|
1900
|
+
collateralToken: params.collateralToken,
|
|
1901
|
+
oracle: params.oracle,
|
|
1902
|
+
irm: params.irm,
|
|
1903
|
+
lltv: params.lltv
|
|
1904
|
+
}
|
|
1905
|
+
]);
|
|
1906
|
+
}
|
|
1907
|
+
async function pickBestBlueSupplyMarketForLoan(args) {
|
|
1908
|
+
const loan = viem.getAddress(args.loanToken).toLowerCase();
|
|
1909
|
+
const d = await morphoGql(
|
|
1910
|
+
`
|
|
1911
|
+
query MorphoBlueParkMarkets($chainId: Int!) {
|
|
1912
|
+
markets(first: 200, where: { chainId_in: [$chainId] }, orderBy: SupplyAssetsUsd, orderDirection: Desc) {
|
|
1913
|
+
items {
|
|
1914
|
+
marketId
|
|
1915
|
+
loanAsset { address symbol decimals price { usd } }
|
|
1916
|
+
collateralAsset { address symbol decimals price { usd } }
|
|
1917
|
+
lltv
|
|
1918
|
+
oracle { address }
|
|
1919
|
+
irmAddress
|
|
1920
|
+
morphoBlue { address }
|
|
1921
|
+
state {
|
|
1922
|
+
supplyApy borrowApy netSupplyApy netBorrowApy
|
|
1923
|
+
supplyAssetsUsd borrowAssetsUsd collateralAssetsUsd utilization
|
|
1924
|
+
rewards { supplyApr borrowApr asset { address symbol } }
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
`,
|
|
1930
|
+
{ chainId: args.chainId }
|
|
1931
|
+
);
|
|
1932
|
+
for (const row of d.markets?.items ?? []) {
|
|
1933
|
+
const loanAddr = (row.loanAsset?.address ?? "").trim().toLowerCase();
|
|
1934
|
+
if (loanAddr !== loan || !row.morphoBlue?.address) continue;
|
|
1935
|
+
try {
|
|
1936
|
+
return {
|
|
1937
|
+
...row,
|
|
1938
|
+
morphoBlueAddress: viem.getAddress(row.morphoBlue.address),
|
|
1939
|
+
marketParams: marketParamsFromApiRow(row)
|
|
1940
|
+
};
|
|
1941
|
+
} catch {
|
|
1942
|
+
continue;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
return null;
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1708
1948
|
// src/core/purpose.ts
|
|
1709
1949
|
function mergePurposeText(purposeText, purposeSuffix) {
|
|
1710
1950
|
const t = (purposeText ?? "").trim();
|
|
@@ -2401,6 +2641,458 @@ async function buildEvmMultisignBodyMorphoMidnightRepayBatch(args) {
|
|
|
2401
2641
|
})
|
|
2402
2642
|
});
|
|
2403
2643
|
}
|
|
2644
|
+
init_midnightConstants();
|
|
2645
|
+
init_midnightApi();
|
|
2646
|
+
var wethDepositAbi2 = viem.parseAbi(["function deposit() payable"]);
|
|
2647
|
+
var erc20Abi2 = viem.parseAbi([
|
|
2648
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
2649
|
+
"function decimals() view returns (uint8)",
|
|
2650
|
+
"function approve(address spender, uint256 amount) returns (bool)"
|
|
2651
|
+
]);
|
|
2652
|
+
var factoryAbi = viem.parseAbi([
|
|
2653
|
+
"function callbackOf(address owner, bytes32 salt) view returns (address)",
|
|
2654
|
+
"function createBlueBuyCallback(address owner, bytes32 salt) returns (address)"
|
|
2655
|
+
]);
|
|
2656
|
+
var setterAbi = viem.parseAbi([
|
|
2657
|
+
"function isRootRatified(address maker, bytes32 root) view returns (bool)",
|
|
2658
|
+
"function setIsRootRatified(address maker, bytes32 root, bool newIsRatified)"
|
|
2659
|
+
]);
|
|
2660
|
+
var morphoBlueAbi = viem.parseAbi([
|
|
2661
|
+
"function supply((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, bytes data)",
|
|
2662
|
+
"function withdraw((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, address receiver)",
|
|
2663
|
+
"function position(bytes32 id, address user) view returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral)"
|
|
2664
|
+
]);
|
|
2665
|
+
var blueMarketParamsAbi = [
|
|
2666
|
+
{
|
|
2667
|
+
type: "tuple",
|
|
2668
|
+
components: [
|
|
2669
|
+
{ name: "loanToken", type: "address" },
|
|
2670
|
+
{ name: "collateralToken", type: "address" },
|
|
2671
|
+
{ name: "oracle", type: "address" },
|
|
2672
|
+
{ name: "irm", type: "address" },
|
|
2673
|
+
{ name: "lltv", type: "uint256" }
|
|
2674
|
+
]
|
|
2675
|
+
}
|
|
2676
|
+
];
|
|
2677
|
+
function publicClientFor2(rpcUrl, chainId) {
|
|
2678
|
+
const ch = viem.defineChain({
|
|
2679
|
+
id: chainId,
|
|
2680
|
+
name: "MorphoMidnight",
|
|
2681
|
+
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
2682
|
+
rpcUrls: { default: { http: [rpcUrl] } }
|
|
2683
|
+
});
|
|
2684
|
+
return viem.createPublicClient({ chain: ch, transport: viem.http(rpcUrl) });
|
|
2685
|
+
}
|
|
2686
|
+
async function readTokenDecimals2(args) {
|
|
2687
|
+
const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
|
|
2688
|
+
const d = await publicClient.readContract({
|
|
2689
|
+
address: args.token,
|
|
2690
|
+
abi: erc20Abi2,
|
|
2691
|
+
functionName: "decimals"
|
|
2692
|
+
});
|
|
2693
|
+
const n = typeof d === "bigint" ? Number(d) : Number(d);
|
|
2694
|
+
return !Number.isFinite(n) || n < 0 || n > 36 ? 18 : n;
|
|
2695
|
+
}
|
|
2696
|
+
async function buildApproveSteps2(args) {
|
|
2697
|
+
const steps = [];
|
|
2698
|
+
let spendToken = args.token;
|
|
2699
|
+
if (args.isNativeIn && args.nativeWrapped) {
|
|
2700
|
+
const weth = viem.getAddress(args.nativeWrapped);
|
|
2701
|
+
if (spendToken.toLowerCase() !== weth.toLowerCase()) {
|
|
2702
|
+
throw new Error("Native path: token must match wrapped native.");
|
|
2703
|
+
}
|
|
2704
|
+
steps.push({
|
|
2705
|
+
kind: "weth_deposit",
|
|
2706
|
+
to: weth,
|
|
2707
|
+
data: viem.encodeFunctionData({ abi: wethDepositAbi2, functionName: "deposit" }),
|
|
2708
|
+
value: args.amountWei
|
|
2709
|
+
});
|
|
2710
|
+
spendToken = weth;
|
|
2711
|
+
}
|
|
2712
|
+
const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
|
|
2713
|
+
const currentAllowance = await publicClient.readContract({
|
|
2714
|
+
address: spendToken,
|
|
2715
|
+
abi: erc20Abi2,
|
|
2716
|
+
functionName: "allowance",
|
|
2717
|
+
args: [args.executor, args.spender]
|
|
2718
|
+
});
|
|
2719
|
+
if (currentAllowance < args.amountWei) {
|
|
2720
|
+
if (currentAllowance > 0n) {
|
|
2721
|
+
steps.push({
|
|
2722
|
+
kind: "approve",
|
|
2723
|
+
to: spendToken,
|
|
2724
|
+
data: viem.encodeFunctionData({ abi: erc20Abi2, functionName: "approve", args: [args.spender, 0n] }),
|
|
2725
|
+
value: 0n
|
|
2726
|
+
});
|
|
2727
|
+
}
|
|
2728
|
+
steps.push({
|
|
2729
|
+
kind: "approve",
|
|
2730
|
+
to: spendToken,
|
|
2731
|
+
data: viem.encodeFunctionData({
|
|
2732
|
+
abi: erc20Abi2,
|
|
2733
|
+
functionName: "approve",
|
|
2734
|
+
args: [args.spender, args.amountWei]
|
|
2735
|
+
}),
|
|
2736
|
+
value: 0n
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2739
|
+
return steps;
|
|
2740
|
+
}
|
|
2741
|
+
function approveStepsToEvm2(steps) {
|
|
2742
|
+
return steps.map((s) => ({
|
|
2743
|
+
to: s.to,
|
|
2744
|
+
data: s.data,
|
|
2745
|
+
value: s.value,
|
|
2746
|
+
fallbackGas: s.kind === "weth_deposit" ? exports.MORPHO_MIDNIGHT_WETH_DEPOSIT_FALLBACK : exports.MORPHO_MIDNIGHT_ERC20_APPROVE_FALLBACK
|
|
2747
|
+
}));
|
|
2748
|
+
}
|
|
2749
|
+
async function ensureAuthorizedSteps(args) {
|
|
2750
|
+
const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
|
|
2751
|
+
const authorized = await publicClient.readContract({
|
|
2752
|
+
address: args.midnight,
|
|
2753
|
+
abi: midnightSdk.midnightAbi,
|
|
2754
|
+
functionName: "isAuthorized",
|
|
2755
|
+
args: [args.onBehalf, args.authorized]
|
|
2756
|
+
});
|
|
2757
|
+
if (authorized) return [];
|
|
2758
|
+
return [
|
|
2759
|
+
{
|
|
2760
|
+
to: args.midnight,
|
|
2761
|
+
data: viem.encodeFunctionData({
|
|
2762
|
+
abi: midnightSdk.midnightAbi,
|
|
2763
|
+
functionName: "setIsAuthorized",
|
|
2764
|
+
args: [args.authorized, true, args.onBehalf]
|
|
2765
|
+
}),
|
|
2766
|
+
value: 0n,
|
|
2767
|
+
fallbackGas: exports.MORPHO_MIDNIGHT_AUTHORIZE_FALLBACK_GAS
|
|
2768
|
+
}
|
|
2769
|
+
];
|
|
2770
|
+
}
|
|
2771
|
+
function bookLevelTick(level) {
|
|
2772
|
+
if (!level) return null;
|
|
2773
|
+
if (level.tick != null && String(level.tick).trim() !== "") {
|
|
2774
|
+
try {
|
|
2775
|
+
return BigInt(level.tick);
|
|
2776
|
+
} catch {
|
|
2777
|
+
return null;
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
if (!level.price) return null;
|
|
2781
|
+
try {
|
|
2782
|
+
return morphoMidnightTickFromPriceWad(BigInt(String(level.price).split(".")[0] || "0"));
|
|
2783
|
+
} catch {
|
|
2784
|
+
return null;
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
function resolveOfferTick(args) {
|
|
2788
|
+
if (args.tick?.trim()) {
|
|
2789
|
+
try {
|
|
2790
|
+
const t = BigInt(args.tick.trim());
|
|
2791
|
+
if (t > 0n) return t;
|
|
2792
|
+
} catch {
|
|
2793
|
+
throw new Error(`Invalid Midnight offer tick: ${args.tick}`);
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
const ttm = morphoMidnightTtmSeconds(args.book.maturity);
|
|
2797
|
+
if (args.lendAprPct?.trim()) {
|
|
2798
|
+
const apr = parseMorphoMidnightAprInput(args.lendAprPct);
|
|
2799
|
+
if (apr == null) throw new Error("lendAprPct must be a positive percent (e.g. 5.2).");
|
|
2800
|
+
const tick = morphoMidnightTickFromApr(apr, ttm);
|
|
2801
|
+
if (tick == null) throw new Error("Could not convert lendAprPct to a Midnight tick.");
|
|
2802
|
+
return tick;
|
|
2803
|
+
}
|
|
2804
|
+
const bidTick = bookLevelTick(args.book.bids?.[0]);
|
|
2805
|
+
if (bidTick != null && bidTick > 0n) return bidTick;
|
|
2806
|
+
const askTick = bookLevelTick(args.book.asks?.[0]);
|
|
2807
|
+
if (askTick != null && askTick > 0n) return askTick;
|
|
2808
|
+
throw new Error("No book tick available. Pass lendAprPct (e.g. 5.2) or tick.");
|
|
2809
|
+
}
|
|
2810
|
+
function offerExpiryUnix(maturity, ttlSeconds) {
|
|
2811
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
2812
|
+
const ttl = ttlSeconds && ttlSeconds > 0 ? ttlSeconds : exports.MORPHO_MIDNIGHT_DEFAULT_OFFER_TTL_SECONDS;
|
|
2813
|
+
const byTtl = now + ttl;
|
|
2814
|
+
const byMaturity = maturity > 60 ? maturity - 60 : maturity;
|
|
2815
|
+
return BigInt(Math.max(now + 60, Math.min(byTtl, byMaturity)));
|
|
2816
|
+
}
|
|
2817
|
+
function decodeBlueMarketParams(data) {
|
|
2818
|
+
const [decoded] = viem.decodeAbiParameters(blueMarketParamsAbi, data);
|
|
2819
|
+
return {
|
|
2820
|
+
loanToken: viem.getAddress(decoded.loanToken),
|
|
2821
|
+
collateralToken: viem.getAddress(decoded.collateralToken),
|
|
2822
|
+
oracle: viem.getAddress(decoded.oracle),
|
|
2823
|
+
irm: viem.getAddress(decoded.irm),
|
|
2824
|
+
lltv: decoded.lltv
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
async function buildEvmMultisignBodyMorphoMidnightLendOfferBatch(args) {
|
|
2828
|
+
const maker = viem.getAddress(args.maker);
|
|
2829
|
+
const executor = viem.getAddress(args.executorAddress);
|
|
2830
|
+
const known = morphoMidnightAddressesForChain(args.chainId);
|
|
2831
|
+
if (!known) {
|
|
2832
|
+
throw new Error(`Morpho Midnight addresses unknown for chain ${args.chainId}.`);
|
|
2833
|
+
}
|
|
2834
|
+
const book = await fetchMorphoMidnightBook(args.marketId);
|
|
2835
|
+
if (!book) throw new Error(`Midnight book not found: ${args.marketId}`);
|
|
2836
|
+
const marketParams = morphoMidnightBookToMarketParams(book);
|
|
2837
|
+
const midnight = args.midnight ? viem.getAddress(args.midnight) : viem.getAddress(book.midnight || known.midnight);
|
|
2838
|
+
const loanToken = args.loanToken ? viem.getAddress(args.loanToken) : viem.getAddress(marketParams.loanToken);
|
|
2839
|
+
if (loanToken.toLowerCase() !== marketParams.loanToken.toLowerCase()) {
|
|
2840
|
+
throw new Error("loanToken does not match Midnight market loan token.");
|
|
2841
|
+
}
|
|
2842
|
+
const dec = await readTokenDecimals2({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loanToken });
|
|
2843
|
+
const maxAssets = viem.parseUnits(args.amountHuman, dec);
|
|
2844
|
+
if (maxAssets === 0n) throw new Error("Lend offer amount is zero.");
|
|
2845
|
+
const blueRow = args.blueMarketId?.trim() ? await fetchMorphoMarketById({ chainId: args.chainId, marketId: args.blueMarketId.trim() }) : await pickBestBlueSupplyMarketForLoan({ chainId: args.chainId, loanToken });
|
|
2846
|
+
if (!blueRow) {
|
|
2847
|
+
throw new Error(
|
|
2848
|
+
`No Morpho Blue market found to park ${loanToken} while the Midnight offer waits. Pass blueMarketId.`
|
|
2849
|
+
);
|
|
2850
|
+
}
|
|
2851
|
+
if (blueRow.marketParams.loanToken.toLowerCase() !== loanToken.toLowerCase()) {
|
|
2852
|
+
throw new Error("blueMarketId loan token must match the Midnight loan token.");
|
|
2853
|
+
}
|
|
2854
|
+
const morphoBlue = viem.getAddress(blueRow.morphoBlueAddress);
|
|
2855
|
+
const callbackData = encodeMorphoBlueMarketParamsCallbackData(blueRow.marketParams);
|
|
2856
|
+
const tick = resolveOfferTick({ book, lendAprPct: args.lendAprPct, tick: args.tick });
|
|
2857
|
+
const expiry = offerExpiryUnix(book.maturity, args.expirySeconds);
|
|
2858
|
+
const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
|
|
2859
|
+
let callback = await publicClient.readContract({
|
|
2860
|
+
address: known.blueBuyCallbackFactory,
|
|
2861
|
+
abi: factoryAbi,
|
|
2862
|
+
functionName: "callbackOf",
|
|
2863
|
+
args: [maker, exports.MORPHO_MIDNIGHT_CALLBACK_SALT]
|
|
2864
|
+
});
|
|
2865
|
+
const evmSteps = [];
|
|
2866
|
+
if (callback === viem.zeroAddress) {
|
|
2867
|
+
const sim = await publicClient.simulateContract({
|
|
2868
|
+
address: known.blueBuyCallbackFactory,
|
|
2869
|
+
abi: factoryAbi,
|
|
2870
|
+
functionName: "createBlueBuyCallback",
|
|
2871
|
+
args: [maker, exports.MORPHO_MIDNIGHT_CALLBACK_SALT],
|
|
2872
|
+
account: executor
|
|
2873
|
+
});
|
|
2874
|
+
callback = sim.result;
|
|
2875
|
+
evmSteps.push({
|
|
2876
|
+
to: known.blueBuyCallbackFactory,
|
|
2877
|
+
data: viem.encodeFunctionData({
|
|
2878
|
+
abi: factoryAbi,
|
|
2879
|
+
functionName: "createBlueBuyCallback",
|
|
2880
|
+
args: [maker, exports.MORPHO_MIDNIGHT_CALLBACK_SALT]
|
|
2881
|
+
}),
|
|
2882
|
+
value: 0n,
|
|
2883
|
+
fallbackGas: exports.MORPHO_MIDNIGHT_CREATE_CALLBACK_FALLBACK_GAS
|
|
2884
|
+
});
|
|
2885
|
+
}
|
|
2886
|
+
if (callback === viem.zeroAddress) {
|
|
2887
|
+
throw new Error("Could not resolve BlueBuyCallback address for this owner.");
|
|
2888
|
+
}
|
|
2889
|
+
const offer = midnightSdk.Offer.create({
|
|
2890
|
+
market: {
|
|
2891
|
+
chainId: args.chainId,
|
|
2892
|
+
midnight,
|
|
2893
|
+
loanToken,
|
|
2894
|
+
collateralParams: marketParams.collateralParams.map((c) => ({
|
|
2895
|
+
token: c.token,
|
|
2896
|
+
lltv: c.lltv,
|
|
2897
|
+
liquidationCursor: c.liquidationCursor,
|
|
2898
|
+
oracle: c.oracle
|
|
2899
|
+
})),
|
|
2900
|
+
maturity: marketParams.maturity,
|
|
2901
|
+
rcfThreshold: marketParams.rcfThreshold,
|
|
2902
|
+
enterGate: marketParams.enterGate,
|
|
2903
|
+
liquidatorGate: marketParams.liquidatorGate
|
|
2904
|
+
},
|
|
2905
|
+
buy: true,
|
|
2906
|
+
maker,
|
|
2907
|
+
tick,
|
|
2908
|
+
maxAssets,
|
|
2909
|
+
expiry,
|
|
2910
|
+
ratifier: known.setterRatifier,
|
|
2911
|
+
callback,
|
|
2912
|
+
callbackData
|
|
2913
|
+
});
|
|
2914
|
+
const tree = midnightSdk.Tree.create([offer]);
|
|
2915
|
+
await tree.mempoolValidate({ chainId: args.chainId, apiUrl: morphoMidnightApiBaseUrl() });
|
|
2916
|
+
const items = midnightSdk.SetterRatifierUtils.ratify({ tree });
|
|
2917
|
+
const payload = await midnightSdk.Payload.encode(items);
|
|
2918
|
+
evmSteps.push(
|
|
2919
|
+
...approveStepsToEvm2(
|
|
2920
|
+
await buildApproveSteps2({
|
|
2921
|
+
rpcUrl: args.rpcUrl,
|
|
2922
|
+
chainId: args.chainId,
|
|
2923
|
+
token: loanToken,
|
|
2924
|
+
spender: morphoBlue,
|
|
2925
|
+
amountWei: maxAssets,
|
|
2926
|
+
executor,
|
|
2927
|
+
isNativeIn: args.isNativeIn,
|
|
2928
|
+
nativeWrapped: args.nativeWrapped
|
|
2929
|
+
})
|
|
2930
|
+
)
|
|
2931
|
+
);
|
|
2932
|
+
evmSteps.push({
|
|
2933
|
+
to: morphoBlue,
|
|
2934
|
+
data: viem.encodeFunctionData({
|
|
2935
|
+
abi: morphoBlueAbi,
|
|
2936
|
+
functionName: "supply",
|
|
2937
|
+
args: [blueRow.marketParams, maxAssets, 0n, callback, "0x"]
|
|
2938
|
+
}),
|
|
2939
|
+
value: 0n,
|
|
2940
|
+
fallbackGas: exports.MORPHO_MIDNIGHT_BLUE_SUPPLY_FALLBACK_GAS
|
|
2941
|
+
});
|
|
2942
|
+
evmSteps.push(
|
|
2943
|
+
...await ensureAuthorizedSteps({
|
|
2944
|
+
rpcUrl: args.rpcUrl,
|
|
2945
|
+
chainId: args.chainId,
|
|
2946
|
+
midnight,
|
|
2947
|
+
authorized: known.setterRatifier,
|
|
2948
|
+
onBehalf: maker
|
|
2949
|
+
})
|
|
2950
|
+
);
|
|
2951
|
+
evmSteps.push({
|
|
2952
|
+
to: known.setterRatifier,
|
|
2953
|
+
data: viem.encodeFunctionData({
|
|
2954
|
+
abi: setterAbi,
|
|
2955
|
+
functionName: "setIsRootRatified",
|
|
2956
|
+
args: [maker, tree.root, true]
|
|
2957
|
+
}),
|
|
2958
|
+
value: 0n,
|
|
2959
|
+
fallbackGas: exports.MORPHO_MIDNIGHT_SET_ROOT_FALLBACK_GAS
|
|
2960
|
+
});
|
|
2961
|
+
evmSteps.push({
|
|
2962
|
+
to: known.mempool,
|
|
2963
|
+
data: payload,
|
|
2964
|
+
value: 0n,
|
|
2965
|
+
fallbackGas: exports.MORPHO_MIDNIGHT_MEMPOOL_PUBLISH_FALLBACK_GAS
|
|
2966
|
+
});
|
|
2967
|
+
const marketLabel = (args.marketLabel ?? "").trim() || `Midnight ${args.marketId.slice(0, 10)}\u2026`;
|
|
2968
|
+
return buildEvmMultisignBatch({
|
|
2969
|
+
context: {
|
|
2970
|
+
chainCategory: "evm",
|
|
2971
|
+
keyGen: args.keyGen,
|
|
2972
|
+
purposeText: args.purposeText,
|
|
2973
|
+
chainId: args.chainId,
|
|
2974
|
+
rpcUrl: args.rpcUrl,
|
|
2975
|
+
executorAddress: executor,
|
|
2976
|
+
chainDetail: args.chainDetail,
|
|
2977
|
+
useCustomGas: args.useCustomGas,
|
|
2978
|
+
customGasChainDetails: args.customGasChainDetails
|
|
2979
|
+
},
|
|
2980
|
+
steps: evmSteps,
|
|
2981
|
+
purposeSuffix: `Morpho Midnight: lend offer (${args.amountHuman}) on "${marketLabel}" (variable yield until filled).`,
|
|
2982
|
+
firstMsgRawNo0x: evmSteps[0].data.slice(2),
|
|
2983
|
+
destinationAddress: known.mempool,
|
|
2984
|
+
buildBatchMeta: ({ gasLimit }) => ({
|
|
2985
|
+
signatureText: JSON.stringify({
|
|
2986
|
+
kind: "MorphoMidnight",
|
|
2987
|
+
name: "lend_offer",
|
|
2988
|
+
marketLabel,
|
|
2989
|
+
amountHuman: args.amountHuman
|
|
2990
|
+
}),
|
|
2991
|
+
evm: { type: "morpho_midnight_lend_offer", version: 1, chainId: String(args.chainId) },
|
|
2992
|
+
morpho: {
|
|
2993
|
+
marketId: args.marketId,
|
|
2994
|
+
marketLabel,
|
|
2995
|
+
amountHuman: args.amountHuman,
|
|
2996
|
+
tick: tick.toString(),
|
|
2997
|
+
blueMarketId: blueRow.marketId,
|
|
2998
|
+
callback,
|
|
2999
|
+
treeRoot: tree.root,
|
|
3000
|
+
group: offer.group,
|
|
3001
|
+
gasBuild: { baseGasUnits: gasLimit.toString() }
|
|
3002
|
+
}
|
|
3003
|
+
})
|
|
3004
|
+
});
|
|
3005
|
+
}
|
|
3006
|
+
async function buildEvmMultisignBodyMorphoMidnightCancelLendOfferBatch(args) {
|
|
3007
|
+
const maker = viem.getAddress(args.maker);
|
|
3008
|
+
const executor = viem.getAddress(args.executorAddress);
|
|
3009
|
+
const known = morphoMidnightAddressesForChain(args.chainId);
|
|
3010
|
+
if (!known) {
|
|
3011
|
+
throw new Error(`Morpho Midnight addresses unknown for chain ${args.chainId}.`);
|
|
3012
|
+
}
|
|
3013
|
+
const midnight = args.midnight ? viem.getAddress(args.midnight) : known.midnight;
|
|
3014
|
+
const group = args.group.trim();
|
|
3015
|
+
if (!group.startsWith("0x") || group.length !== 66) {
|
|
3016
|
+
throw new Error("group must be a bytes32 hex id from ctm_morpho_fetch_midnight_offers.");
|
|
3017
|
+
}
|
|
3018
|
+
const evmSteps = [
|
|
3019
|
+
{
|
|
3020
|
+
to: midnight,
|
|
3021
|
+
data: viem.encodeFunctionData({
|
|
3022
|
+
abi: midnightSdk.midnightAbi,
|
|
3023
|
+
functionName: "setConsumed",
|
|
3024
|
+
args: [group, viem.maxUint256, maker]
|
|
3025
|
+
}),
|
|
3026
|
+
value: 0n,
|
|
3027
|
+
fallbackGas: exports.MORPHO_MIDNIGHT_SET_CONSUMED_FALLBACK_GAS
|
|
3028
|
+
}
|
|
3029
|
+
];
|
|
3030
|
+
const withdrawRemaining = args.withdrawRemaining !== false;
|
|
3031
|
+
const callback = args.callback && args.callback !== viem.zeroAddress ? viem.getAddress(args.callback) : null;
|
|
3032
|
+
const callbackData = args.callbackData ?? "0x";
|
|
3033
|
+
if (withdrawRemaining && callback && callbackData !== "0x") {
|
|
3034
|
+
const params = decodeBlueMarketParams(callbackData);
|
|
3035
|
+
const publicClient = publicClientFor2(args.rpcUrl, args.chainId);
|
|
3036
|
+
const marketId = viem.keccak256(
|
|
3037
|
+
viem.encodeAbiParameters(
|
|
3038
|
+
[
|
|
3039
|
+
{ type: "address" },
|
|
3040
|
+
{ type: "address" },
|
|
3041
|
+
{ type: "address" },
|
|
3042
|
+
{ type: "address" },
|
|
3043
|
+
{ type: "uint256" }
|
|
3044
|
+
],
|
|
3045
|
+
[params.loanToken, params.collateralToken, params.oracle, params.irm, params.lltv]
|
|
3046
|
+
)
|
|
3047
|
+
);
|
|
3048
|
+
const pos = await publicClient.readContract({
|
|
3049
|
+
address: known.morphoBlue,
|
|
3050
|
+
abi: morphoBlueAbi,
|
|
3051
|
+
functionName: "position",
|
|
3052
|
+
args: [marketId, callback]
|
|
3053
|
+
});
|
|
3054
|
+
const supplyShares = pos[0];
|
|
3055
|
+
if (supplyShares > 0n) {
|
|
3056
|
+
evmSteps.push({
|
|
3057
|
+
to: known.morphoBlue,
|
|
3058
|
+
data: viem.encodeFunctionData({
|
|
3059
|
+
abi: morphoBlueAbi,
|
|
3060
|
+
functionName: "withdraw",
|
|
3061
|
+
args: [params, 0n, supplyShares, callback, maker]
|
|
3062
|
+
}),
|
|
3063
|
+
value: 0n,
|
|
3064
|
+
fallbackGas: exports.MORPHO_MIDNIGHT_BLUE_WITHDRAW_FALLBACK_GAS
|
|
3065
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
const marketLabel = (args.marketLabel ?? "").trim() || "Midnight lend offer";
|
|
3069
|
+
return buildEvmMultisignBatch({
|
|
3070
|
+
context: {
|
|
3071
|
+
chainCategory: "evm",
|
|
3072
|
+
keyGen: args.keyGen,
|
|
3073
|
+
purposeText: args.purposeText,
|
|
3074
|
+
chainId: args.chainId,
|
|
3075
|
+
rpcUrl: args.rpcUrl,
|
|
3076
|
+
executorAddress: executor,
|
|
3077
|
+
chainDetail: args.chainDetail,
|
|
3078
|
+
useCustomGas: args.useCustomGas,
|
|
3079
|
+
customGasChainDetails: args.customGasChainDetails
|
|
3080
|
+
},
|
|
3081
|
+
steps: evmSteps,
|
|
3082
|
+
purposeSuffix: `Morpho Midnight: cancel lend offer on "${marketLabel}".`,
|
|
3083
|
+
firstMsgRawNo0x: evmSteps[0].data.slice(2),
|
|
3084
|
+
destinationAddress: midnight,
|
|
3085
|
+
buildBatchMeta: ({ gasLimit }) => ({
|
|
3086
|
+
signatureText: JSON.stringify({ kind: "MorphoMidnight", name: "cancel_lend_offer", marketLabel }),
|
|
3087
|
+
evm: { type: "morpho_midnight_cancel_lend_offer", version: 1, chainId: String(args.chainId) },
|
|
3088
|
+
morpho: {
|
|
3089
|
+
group,
|
|
3090
|
+
marketLabel,
|
|
3091
|
+
gasBuild: { baseGasUnits: gasLimit.toString() }
|
|
3092
|
+
}
|
|
3093
|
+
})
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
2404
3096
|
var erc4626Abi = viem.parseAbi([
|
|
2405
3097
|
"function asset() view returns (address)",
|
|
2406
3098
|
"function decimals() view returns (uint8)",
|
|
@@ -2445,13 +3137,13 @@ async function fetchMorphoVaultMaxWithdrawWei(args) {
|
|
|
2445
3137
|
args: [viem.getAddress(args.owner)]
|
|
2446
3138
|
});
|
|
2447
3139
|
}
|
|
2448
|
-
var
|
|
3140
|
+
var morphoBlueAbi2 = viem.parseAbi([
|
|
2449
3141
|
"function position(bytes32 id, address user) view returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral)",
|
|
2450
3142
|
"function market(bytes32 id) view returns (uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee)",
|
|
2451
3143
|
"function idToMarketParams(bytes32 id) view returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv)"
|
|
2452
3144
|
]);
|
|
2453
3145
|
var oracleAbi = viem.parseAbi(["function price() view returns (uint256)"]);
|
|
2454
|
-
var
|
|
3146
|
+
var WAD2 = 10n ** 18n;
|
|
2455
3147
|
var ORACLE_PRICE_SCALE = 10n ** 36n;
|
|
2456
3148
|
async function previewMorphoBlueHealthAfterCollateralWithdraw(args) {
|
|
2457
3149
|
const ch = viem.defineChain({
|
|
@@ -2467,19 +3159,19 @@ async function previewMorphoBlueHealthAfterCollateralWithdraw(args) {
|
|
|
2467
3159
|
const [pos, mkt, params] = await Promise.all([
|
|
2468
3160
|
publicClient.readContract({
|
|
2469
3161
|
address: morpho,
|
|
2470
|
-
abi:
|
|
3162
|
+
abi: morphoBlueAbi2,
|
|
2471
3163
|
functionName: "position",
|
|
2472
3164
|
args: [id, user]
|
|
2473
3165
|
}),
|
|
2474
3166
|
publicClient.readContract({
|
|
2475
3167
|
address: morpho,
|
|
2476
|
-
abi:
|
|
3168
|
+
abi: morphoBlueAbi2,
|
|
2477
3169
|
functionName: "market",
|
|
2478
3170
|
args: [id]
|
|
2479
3171
|
}),
|
|
2480
3172
|
publicClient.readContract({
|
|
2481
3173
|
address: morpho,
|
|
2482
|
-
abi:
|
|
3174
|
+
abi: morphoBlueAbi2,
|
|
2483
3175
|
functionName: "idToMarketParams",
|
|
2484
3176
|
args: [id]
|
|
2485
3177
|
})
|
|
@@ -2498,15 +3190,15 @@ async function previewMorphoBlueHealthAfterCollateralWithdraw(args) {
|
|
|
2498
3190
|
const totalBorrowShares = BigInt(mkt[3]);
|
|
2499
3191
|
if (totalBorrowShares === 0n) return { healthy: true, healthFactor: null };
|
|
2500
3192
|
const borrowed = (borrowShares * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares;
|
|
2501
|
-
const maxBorrow = collateral * price / ORACLE_PRICE_SCALE * lltv /
|
|
3193
|
+
const maxBorrow = collateral * price / ORACLE_PRICE_SCALE * lltv / WAD2;
|
|
2502
3194
|
const healthy = maxBorrow >= borrowed;
|
|
2503
|
-
const hf = borrowed === 0n ? null : Number(maxBorrow *
|
|
3195
|
+
const hf = borrowed === 0n ? null : Number(maxBorrow * WAD2 / borrowed) / Number(WAD2);
|
|
2504
3196
|
return { healthy, healthFactor: hf != null && Number.isFinite(hf) ? hf : null };
|
|
2505
3197
|
}
|
|
2506
3198
|
var MORPHO_VAULT_DEPOSIT_FALLBACK_GAS = 950000n;
|
|
2507
3199
|
var MORPHO_ERC20_APPROVE_FALLBACK = 100000n;
|
|
2508
3200
|
var MORPHO_WETH_DEPOSIT_FALLBACK = 120000n;
|
|
2509
|
-
var
|
|
3201
|
+
var wethDepositAbi3 = viem.parseAbi(["function deposit() payable"]);
|
|
2510
3202
|
var erc20AllowanceAbi = viem.parseAbi([
|
|
2511
3203
|
"function allowance(address owner, address spender) view returns (uint256)"
|
|
2512
3204
|
]);
|
|
@@ -2535,7 +3227,7 @@ async function buildEvmMultisignBodyMorphoVaultDepositBatch(args) {
|
|
|
2535
3227
|
if (amountWei === 0n) throw new Error("Deposit amount is zero after converting with token decimals.");
|
|
2536
3228
|
const steps = [];
|
|
2537
3229
|
if (args.isNativeIn) {
|
|
2538
|
-
const wethData = viem.encodeFunctionData({ abi:
|
|
3230
|
+
const wethData = viem.encodeFunctionData({ abi: wethDepositAbi3, functionName: "deposit" });
|
|
2539
3231
|
steps.push({ kind: "weth_deposit", to: weth, data: wethData, value: amountWei });
|
|
2540
3232
|
}
|
|
2541
3233
|
const spendToken = args.isNativeIn ? weth : asset;
|
|
@@ -2687,13 +3379,13 @@ var MORPHO_BLUE_REPAY_FALLBACK_GAS = 1000000n;
|
|
|
2687
3379
|
var MORPHO_BLUE_COLLATERAL_WITHDRAW_FALLBACK_GAS = 900000n;
|
|
2688
3380
|
var MORPHO_ERC20_APPROVE_FALLBACK2 = 100000n;
|
|
2689
3381
|
var MORPHO_WETH_DEPOSIT_FALLBACK2 = 120000n;
|
|
2690
|
-
var
|
|
3382
|
+
var wethDepositAbi4 = viem.parseAbi(["function deposit() payable"]);
|
|
2691
3383
|
var erc20AllowanceAbi2 = viem.parseAbi([
|
|
2692
3384
|
"function allowance(address owner, address spender) view returns (uint256)",
|
|
2693
3385
|
"function decimals() view returns (uint8)"
|
|
2694
3386
|
]);
|
|
2695
3387
|
var erc20ApproveAbi2 = viem.parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]);
|
|
2696
|
-
var
|
|
3388
|
+
var morphoBlueAbi3 = viem.parseAbi([
|
|
2697
3389
|
"function supplyCollateral((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, address onBehalf, bytes data)",
|
|
2698
3390
|
"function borrow((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, address receiver)",
|
|
2699
3391
|
"function repay((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv), uint256 assets, uint256 shares, address onBehalf, bytes data)",
|
|
@@ -2708,7 +3400,7 @@ function marketParamsTuple(p) {
|
|
|
2708
3400
|
lltv: p.lltv
|
|
2709
3401
|
};
|
|
2710
3402
|
}
|
|
2711
|
-
async function
|
|
3403
|
+
async function readTokenDecimals3(args) {
|
|
2712
3404
|
const ch = viem.defineChain({
|
|
2713
3405
|
id: args.chainId,
|
|
2714
3406
|
name: "MorphoToken",
|
|
@@ -2724,7 +3416,7 @@ async function readTokenDecimals2(args) {
|
|
|
2724
3416
|
const n = typeof d === "bigint" ? Number(d) : Number(d);
|
|
2725
3417
|
return !Number.isFinite(n) || n < 0 || n > 36 ? 18 : n;
|
|
2726
3418
|
}
|
|
2727
|
-
async function
|
|
3419
|
+
async function buildApproveSteps3(args) {
|
|
2728
3420
|
const steps = [];
|
|
2729
3421
|
let spendToken = args.token;
|
|
2730
3422
|
if (args.isNativeIn && args.nativeWrapped) {
|
|
@@ -2732,7 +3424,7 @@ async function buildApproveSteps2(args) {
|
|
|
2732
3424
|
if (spendToken.toLowerCase() !== weth.toLowerCase()) {
|
|
2733
3425
|
throw new Error("Native collateral path: token must match wrapped native.");
|
|
2734
3426
|
}
|
|
2735
|
-
const wethData = viem.encodeFunctionData({ abi:
|
|
3427
|
+
const wethData = viem.encodeFunctionData({ abi: wethDepositAbi4, functionName: "deposit" });
|
|
2736
3428
|
steps.push({ kind: "weth_deposit", to: weth, data: wethData, value: args.amountWei });
|
|
2737
3429
|
spendToken = weth;
|
|
2738
3430
|
}
|
|
@@ -2783,10 +3475,10 @@ async function buildEvmMultisignBodyMorphoBlueSupplyCollateralBatch(args) {
|
|
|
2783
3475
|
const onBehalf = viem.getAddress(args.onBehalf);
|
|
2784
3476
|
const executor = viem.getAddress(args.executorAddress);
|
|
2785
3477
|
const collateral = viem.getAddress(args.collateralToken);
|
|
2786
|
-
const dec = await
|
|
3478
|
+
const dec = await readTokenDecimals3({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: collateral });
|
|
2787
3479
|
const amountWei = viem.parseUnits(args.amountHuman, dec);
|
|
2788
3480
|
if (amountWei === 0n) throw new Error("Collateral amount is zero.");
|
|
2789
|
-
const approveSteps = await
|
|
3481
|
+
const approveSteps = await buildApproveSteps3({
|
|
2790
3482
|
rpcUrl: args.rpcUrl,
|
|
2791
3483
|
chainId: args.chainId,
|
|
2792
3484
|
token: collateral,
|
|
@@ -2797,7 +3489,7 @@ async function buildEvmMultisignBodyMorphoBlueSupplyCollateralBatch(args) {
|
|
|
2797
3489
|
nativeWrapped: args.nativeWrapped
|
|
2798
3490
|
});
|
|
2799
3491
|
const supplyData = viem.encodeFunctionData({
|
|
2800
|
-
abi:
|
|
3492
|
+
abi: morphoBlueAbi3,
|
|
2801
3493
|
functionName: "supplyCollateral",
|
|
2802
3494
|
args: [marketParamsTuple(args.marketParams), amountWei, onBehalf, "0x"]
|
|
2803
3495
|
});
|
|
@@ -2837,11 +3529,11 @@ async function buildEvmMultisignBodyMorphoBlueBorrowBatch(args) {
|
|
|
2837
3529
|
const receiver = viem.getAddress(args.receiver);
|
|
2838
3530
|
const executor = viem.getAddress(args.executorAddress);
|
|
2839
3531
|
const loan = viem.getAddress(args.loanToken);
|
|
2840
|
-
const dec = await
|
|
3532
|
+
const dec = await readTokenDecimals3({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loan });
|
|
2841
3533
|
const amountWei = viem.parseUnits(args.amountHuman, dec);
|
|
2842
3534
|
if (amountWei === 0n) throw new Error("Borrow amount is zero.");
|
|
2843
3535
|
const borrowData = viem.encodeFunctionData({
|
|
2844
|
-
abi:
|
|
3536
|
+
abi: morphoBlueAbi3,
|
|
2845
3537
|
functionName: "borrow",
|
|
2846
3538
|
args: [marketParamsTuple(args.marketParams), amountWei, 0n, onBehalf, receiver]
|
|
2847
3539
|
});
|
|
@@ -2877,10 +3569,10 @@ async function buildEvmMultisignBodyMorphoBlueRepayBatch(args) {
|
|
|
2877
3569
|
const onBehalf = viem.getAddress(args.onBehalf);
|
|
2878
3570
|
const executor = viem.getAddress(args.executorAddress);
|
|
2879
3571
|
const loan = viem.getAddress(args.loanToken);
|
|
2880
|
-
const dec = await
|
|
3572
|
+
const dec = await readTokenDecimals3({ rpcUrl: args.rpcUrl, chainId: args.chainId, token: loan });
|
|
2881
3573
|
const amountWei = viem.parseUnits(args.amountHuman, dec);
|
|
2882
3574
|
if (amountWei === 0n) throw new Error("Repay amount is zero.");
|
|
2883
|
-
const approveSteps = await
|
|
3575
|
+
const approveSteps = await buildApproveSteps3({
|
|
2884
3576
|
rpcUrl: args.rpcUrl,
|
|
2885
3577
|
chainId: args.chainId,
|
|
2886
3578
|
token: loan,
|
|
@@ -2889,7 +3581,7 @@ async function buildEvmMultisignBodyMorphoBlueRepayBatch(args) {
|
|
|
2889
3581
|
executor
|
|
2890
3582
|
});
|
|
2891
3583
|
const repayData = viem.encodeFunctionData({
|
|
2892
|
-
abi:
|
|
3584
|
+
abi: morphoBlueAbi3,
|
|
2893
3585
|
functionName: "repay",
|
|
2894
3586
|
args: [marketParamsTuple(args.marketParams), amountWei, 0n, onBehalf, "0x"]
|
|
2895
3587
|
});
|
|
@@ -2931,7 +3623,7 @@ async function buildEvmMultisignBodyMorphoBlueWithdrawCollateralBatch(args) {
|
|
|
2931
3623
|
const amountWei = viem.parseUnits(args.amountHuman, args.collateralDecimals);
|
|
2932
3624
|
if (amountWei === 0n) throw new Error("Collateral withdraw amount is zero.");
|
|
2933
3625
|
const withdrawData = viem.encodeFunctionData({
|
|
2934
|
-
abi:
|
|
3626
|
+
abi: morphoBlueAbi3,
|
|
2935
3627
|
functionName: "withdrawCollateral",
|
|
2936
3628
|
args: [marketParamsTuple(args.marketParams), amountWei, onBehalf, receiver]
|
|
2937
3629
|
});
|
|
@@ -3020,6 +3712,8 @@ var morphoProtocolModule = {
|
|
|
3020
3712
|
{ id: "morpho.fetch-midnight-quote", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Quote Morpho Midnight lend/borrow fill", commonParams: [], params: {} },
|
|
3021
3713
|
{ id: "morpho.fetch-midnight-positions", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "List Morpho Midnight user positions", commonParams: [], params: {} },
|
|
3022
3714
|
{ id: "morpho.midnight-lend", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight fixed-rate lend (take asks)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3715
|
+
{ id: "morpho.midnight-lend-offer", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight lend limit offer parked in Blue until filled", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3716
|
+
{ id: "morpho.midnight-cancel-lend-offer", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Cancel a Morpho Midnight lend offer and withdraw unused Blue park", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3023
3717
|
{ id: "morpho.midnight-borrow", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight fixed-rate borrow (supply collateral + take bids)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3024
3718
|
{ id: "morpho.midnight-repay", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight repay debt and withdraw collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
3025
3719
|
]
|
|
@@ -3047,11 +3741,14 @@ exports.buildEvmMultisignBodyMorphoBlueSupplyCollateralBatch = buildEvmMultisign
|
|
|
3047
3741
|
exports.buildEvmMultisignBodyMorphoBlueWithdrawCollateralBatch = buildEvmMultisignBodyMorphoBlueWithdrawCollateralBatch;
|
|
3048
3742
|
exports.buildEvmMultisignBodyMorphoMerklDistributorClaim = buildEvmMultisignBodyMorphoMerklDistributorClaim;
|
|
3049
3743
|
exports.buildEvmMultisignBodyMorphoMidnightBorrowBatch = buildEvmMultisignBodyMorphoMidnightBorrowBatch;
|
|
3744
|
+
exports.buildEvmMultisignBodyMorphoMidnightCancelLendOfferBatch = buildEvmMultisignBodyMorphoMidnightCancelLendOfferBatch;
|
|
3050
3745
|
exports.buildEvmMultisignBodyMorphoMidnightLendBatch = buildEvmMultisignBodyMorphoMidnightLendBatch;
|
|
3746
|
+
exports.buildEvmMultisignBodyMorphoMidnightLendOfferBatch = buildEvmMultisignBodyMorphoMidnightLendOfferBatch;
|
|
3051
3747
|
exports.buildEvmMultisignBodyMorphoMidnightRepayBatch = buildEvmMultisignBodyMorphoMidnightRepayBatch;
|
|
3052
3748
|
exports.buildEvmMultisignBodyMorphoVaultDepositBatch = buildEvmMultisignBodyMorphoVaultDepositBatch;
|
|
3053
3749
|
exports.buildEvmMultisignBodyMorphoVaultWithdraw = buildEvmMultisignBodyMorphoVaultWithdraw;
|
|
3054
3750
|
exports.emptyMorphoEarnVaultDetailFields = emptyMorphoEarnVaultDetailFields;
|
|
3751
|
+
exports.encodeMorphoBlueMarketParamsCallbackData = encodeMorphoBlueMarketParamsCallbackData;
|
|
3055
3752
|
exports.enrichMorphoEarnOfferingRows = enrichMorphoEarnOfferingRows;
|
|
3056
3753
|
exports.enrichMorphoEarnOfferingRowsForAgent = enrichMorphoEarnOfferingRowsForAgent;
|
|
3057
3754
|
exports.ensureMorphoChainAssetCache = ensureMorphoChainAssetCache;
|
|
@@ -3067,6 +3764,7 @@ exports.fetchMorphoMidnightBookQuote = fetchMorphoMidnightBookQuote;
|
|
|
3067
3764
|
exports.fetchMorphoMidnightBooks = fetchMorphoMidnightBooks;
|
|
3068
3765
|
exports.fetchMorphoMidnightBooksForAsset = fetchMorphoMidnightBooksForAsset;
|
|
3069
3766
|
exports.fetchMorphoMidnightIntents = fetchMorphoMidnightIntents;
|
|
3767
|
+
exports.fetchMorphoMidnightMakerOffers = fetchMorphoMidnightMakerOffers;
|
|
3070
3768
|
exports.fetchMorphoMidnightMarketById = fetchMorphoMidnightMarketById;
|
|
3071
3769
|
exports.fetchMorphoMidnightUserMarketPosition = fetchMorphoMidnightUserMarketPosition;
|
|
3072
3770
|
exports.fetchMorphoMidnightUserPositions = fetchMorphoMidnightUserPositions;
|
|
@@ -3092,6 +3790,7 @@ exports.morphoEarnOfferingToDiscoveryRow = morphoEarnOfferingToDiscoveryRow;
|
|
|
3092
3790
|
exports.morphoFetchBlueMarketsSummary = morphoFetchBlueMarketsSummary;
|
|
3093
3791
|
exports.morphoFetchEarnVaultsSummary = morphoFetchEarnVaultsSummary;
|
|
3094
3792
|
exports.morphoFetchMidnightBooksSummary = morphoFetchMidnightBooksSummary;
|
|
3793
|
+
exports.morphoFetchMidnightMakerOffersSummary = morphoFetchMidnightMakerOffersSummary;
|
|
3095
3794
|
exports.morphoFetchMidnightPositionsSummary = morphoFetchMidnightPositionsSummary;
|
|
3096
3795
|
exports.morphoFetchMidnightQuote = morphoFetchMidnightQuote;
|
|
3097
3796
|
exports.morphoFetchMidnightQuoteSummary = morphoFetchMidnightQuoteSummary;
|
|
@@ -3100,15 +3799,23 @@ exports.morphoKeyForAssetRow = morphoKeyForAssetRow;
|
|
|
3100
3799
|
exports.morphoMarketToBorrowRow = morphoMarketToBorrowRow;
|
|
3101
3800
|
exports.morphoMidnightAddressesForChain = morphoMidnightAddressesForChain;
|
|
3102
3801
|
exports.morphoMidnightApiBaseUrl = morphoMidnightApiBaseUrl;
|
|
3802
|
+
exports.morphoMidnightAprFromBookLevel = morphoMidnightAprFromBookLevel;
|
|
3103
3803
|
exports.morphoMidnightAprFromPriceWad = morphoMidnightAprFromPriceWad;
|
|
3804
|
+
exports.morphoMidnightAprFromTick = morphoMidnightAprFromTick;
|
|
3104
3805
|
exports.morphoMidnightBookToDiscoveryRow = morphoMidnightBookToDiscoveryRow;
|
|
3105
3806
|
exports.morphoMidnightBookToMarketParams = morphoMidnightBookToMarketParams;
|
|
3106
3807
|
exports.morphoMidnightMarketToParams = morphoMidnightMarketToParams;
|
|
3107
3808
|
exports.morphoMidnightPositionToDiscoveryRow = morphoMidnightPositionToDiscoveryRow;
|
|
3809
|
+
exports.morphoMidnightPriceWadFromApr = morphoMidnightPriceWadFromApr;
|
|
3810
|
+
exports.morphoMidnightTickFromApr = morphoMidnightTickFromApr;
|
|
3811
|
+
exports.morphoMidnightTickFromPriceWad = morphoMidnightTickFromPriceWad;
|
|
3108
3812
|
exports.morphoMidnightTtmSeconds = morphoMidnightTtmSeconds;
|
|
3109
3813
|
exports.morphoMidnightUnitsFromAssets = morphoMidnightUnitsFromAssets;
|
|
3110
3814
|
exports.morphoProtocolModule = morphoProtocolModule;
|
|
3111
3815
|
exports.morphoResolveListedEarnVaultByAddress = morphoResolveListedEarnVaultByAddress;
|
|
3816
|
+
exports.parseMorphoMidnightAprInput = parseMorphoMidnightAprInput;
|
|
3817
|
+
exports.parseMorphoMidnightPriceWad = parseMorphoMidnightPriceWad;
|
|
3818
|
+
exports.pickBestBlueSupplyMarketForLoan = pickBestBlueSupplyMarketForLoan;
|
|
3112
3819
|
exports.previewMorphoBlueHealthAfterCollateralWithdraw = previewMorphoBlueHealthAfterCollateralWithdraw;
|
|
3113
3820
|
exports.resolveRobinhoodEarnFetchQuery = resolveRobinhoodEarnFetchQuery;
|
|
3114
3821
|
exports.searchMorphoListedEarnVaults = searchMorphoListedEarnVaults;
|