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