@morpho-org/bundler-sdk-viem 2.3.0-next.0 → 3.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/BundlerAction.d.ts +177 -107
- package/lib/BundlerAction.js +1036 -403
- package/lib/abis.d.ts +3062 -0
- package/lib/abis.js +2095 -0
- package/lib/actions.d.ts +0 -1
- package/lib/actions.js +92 -163
- package/lib/errors.d.ts +4 -1
- package/lib/errors.js +6 -0
- package/lib/operations.js +67 -58
- package/lib/types/actions.d.ts +73 -27
- package/package.json +10 -10
package/lib/operations.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { DEFAULT_SLIPPAGE_TOLERANCE, MarketUtils, MathLib, NATIVE_ADDRESS, erc20WrapperTokens, getChainAddresses, getUnwrappedToken, permissionedBackedTokens, permissionedWrapperTokens, } from "@morpho-org/blue-sdk";
|
|
2
2
|
import { bigIntComparator, entries, getLast, getValue, keys, } from "@morpho-org/morpho-ts";
|
|
3
3
|
import { handleOperation, handleOperations, produceImmutable, simulateOperation, simulateOperations, } from "@morpho-org/simulation-sdk";
|
|
4
|
-
import { maxUint256 } from "viem";
|
|
4
|
+
import { isAddressEqual, maxUint256 } from "viem";
|
|
5
5
|
import { BundlerErrors } from "./errors.js";
|
|
6
6
|
/**
|
|
7
7
|
* The default target utilization above which the shared liquidity algorithm is triggered (scaled by WAD).
|
|
8
8
|
*/
|
|
9
9
|
export const DEFAULT_SUPPLY_TARGET_UTILIZATION = 905000000000000000n;
|
|
10
10
|
export const populateInputTransfer = ({ address, args: { amount, from } }, data, { hasSimplePermit = false } = {}) => {
|
|
11
|
-
const {
|
|
11
|
+
const { bundler3: { bundler3, generalAdapter1 }, permit2, } = getChainAddresses(data.chainId);
|
|
12
12
|
// If native token, it is expected to be sent along as call value.
|
|
13
13
|
if (address === NATIVE_ADDRESS)
|
|
14
14
|
return [
|
|
@@ -19,22 +19,22 @@ export const populateInputTransfer = ({ address, args: { amount, from } }, data,
|
|
|
19
19
|
args: {
|
|
20
20
|
amount,
|
|
21
21
|
from,
|
|
22
|
-
to:
|
|
22
|
+
to: generalAdapter1,
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
];
|
|
26
26
|
const { erc20Allowances, permit2BundlerAllowance, erc2612Nonce } = data.getHolding(from, address);
|
|
27
27
|
// ERC20 allowance to the bundler is enough, consume it.
|
|
28
|
-
if (erc20Allowances.
|
|
28
|
+
if (erc20Allowances["bundler3.generalAdapter1"] >= amount)
|
|
29
29
|
return [
|
|
30
30
|
{
|
|
31
31
|
type: "Erc20_Transfer",
|
|
32
|
-
sender:
|
|
32
|
+
sender: generalAdapter1,
|
|
33
33
|
address,
|
|
34
34
|
args: {
|
|
35
35
|
amount,
|
|
36
36
|
from,
|
|
37
|
-
to:
|
|
37
|
+
to: generalAdapter1,
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
40
|
];
|
|
@@ -43,7 +43,9 @@ export const populateInputTransfer = ({ address, args: { amount, from } }, data,
|
|
|
43
43
|
const useSimplePermit = erc2612Nonce != null &&
|
|
44
44
|
(data.tryGetVault(address) != null || // MetaMorpho vaults implement EIP-2612.
|
|
45
45
|
hasSimplePermit);
|
|
46
|
-
const
|
|
46
|
+
const useSimpleTransfer = permit2 == null ||
|
|
47
|
+
// Token is permissioned and Permit2 may not be authorized so Permit2 cannot be used.
|
|
48
|
+
permissionedWrapperTokens[data.chainId].has(address) ||
|
|
47
49
|
permissionedBackedTokens[data.chainId].has(address);
|
|
48
50
|
if (useSimplePermit)
|
|
49
51
|
operations.push({
|
|
@@ -52,33 +54,32 @@ export const populateInputTransfer = ({ address, args: { amount, from } }, data,
|
|
|
52
54
|
address,
|
|
53
55
|
args: {
|
|
54
56
|
amount,
|
|
55
|
-
spender:
|
|
57
|
+
spender: generalAdapter1,
|
|
56
58
|
nonce: erc2612Nonce,
|
|
57
59
|
},
|
|
58
60
|
});
|
|
59
|
-
|
|
60
|
-
else if (isPermissioned)
|
|
61
|
+
else if (useSimpleTransfer)
|
|
61
62
|
operations.push({
|
|
62
63
|
type: "Erc20_Approve",
|
|
63
64
|
sender: from,
|
|
64
65
|
address,
|
|
65
66
|
args: {
|
|
66
67
|
amount,
|
|
67
|
-
spender:
|
|
68
|
+
spender: generalAdapter1,
|
|
68
69
|
},
|
|
69
70
|
});
|
|
70
|
-
if (useSimplePermit ||
|
|
71
|
+
if (useSimplePermit || useSimpleTransfer)
|
|
71
72
|
operations.push({
|
|
72
73
|
type: "Erc20_Transfer",
|
|
73
|
-
sender:
|
|
74
|
+
sender: generalAdapter1,
|
|
74
75
|
address,
|
|
75
76
|
args: {
|
|
76
77
|
amount,
|
|
77
78
|
from,
|
|
78
|
-
to:
|
|
79
|
+
to: generalAdapter1,
|
|
79
80
|
},
|
|
80
81
|
});
|
|
81
|
-
// Simple permit is not supported
|
|
82
|
+
// Simple permit is not supported: fallback to Permit2.
|
|
82
83
|
else {
|
|
83
84
|
if (erc20Allowances.permit2 < amount)
|
|
84
85
|
operations.push({
|
|
@@ -104,12 +105,12 @@ export const populateInputTransfer = ({ address, args: { amount, from } }, data,
|
|
|
104
105
|
});
|
|
105
106
|
operations.push({
|
|
106
107
|
type: "Erc20_Transfer2",
|
|
107
|
-
sender:
|
|
108
|
+
sender: bundler3,
|
|
108
109
|
address,
|
|
109
110
|
args: {
|
|
110
111
|
amount,
|
|
111
112
|
from,
|
|
112
|
-
to:
|
|
113
|
+
to: generalAdapter1,
|
|
113
114
|
},
|
|
114
115
|
});
|
|
115
116
|
}
|
|
@@ -130,7 +131,7 @@ export const populateInputTransfer = ({ address, args: { amount, from } }, data,
|
|
|
130
131
|
*/
|
|
131
132
|
export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
132
133
|
const { sender } = inputOperation;
|
|
133
|
-
const { morpho,
|
|
134
|
+
const { morpho, bundler3: { bundler3, generalAdapter1 }, } = getChainAddresses(data.chainId);
|
|
134
135
|
const { withSimplePermit = new Set(), publicAllocatorOptions, getRequirementOperations, } = options;
|
|
135
136
|
const operations = [];
|
|
136
137
|
const wrappedToken = inputOperation.type === "Erc20_Wrap"
|
|
@@ -140,7 +141,7 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
140
141
|
erc20WrapperTokens[data.chainId].has(wrappedToken.address);
|
|
141
142
|
// Transform input operation to act on behalf of the sender, via the bundler.
|
|
142
143
|
const mainOperation = produceImmutable(inputOperation, (draft) => {
|
|
143
|
-
draft.sender =
|
|
144
|
+
draft.sender = generalAdapter1;
|
|
144
145
|
// Redirect MetaMorpho operation owner.
|
|
145
146
|
switch (draft.type) {
|
|
146
147
|
case "Erc20_Wrap": {
|
|
@@ -154,7 +155,7 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
154
155
|
case "MetaMorpho_Withdraw":
|
|
155
156
|
// Only if sender is owner otherwise the owner would be lost.
|
|
156
157
|
if (draft.args.owner === sender)
|
|
157
|
-
draft.args.owner =
|
|
158
|
+
draft.args.owner = generalAdapter1;
|
|
158
159
|
}
|
|
159
160
|
// Redirect operation targets.
|
|
160
161
|
switch (draft.type) {
|
|
@@ -165,7 +166,7 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
165
166
|
case "MetaMorpho_Withdraw":
|
|
166
167
|
// Only if sender is receiver otherwise the receiver would be lost.
|
|
167
168
|
if (draft.args.receiver === sender)
|
|
168
|
-
draft.args.receiver =
|
|
169
|
+
draft.args.receiver = generalAdapter1;
|
|
169
170
|
}
|
|
170
171
|
});
|
|
171
172
|
const needsBundlerAuthorization = mainOperation.type === "Blue_Borrow" ||
|
|
@@ -174,7 +175,7 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
174
175
|
if (needsBundlerAuthorization && !data.getUser(sender).isBundlerAuthorized)
|
|
175
176
|
operations.push({
|
|
176
177
|
type: "Blue_SetAuthorization",
|
|
177
|
-
sender:
|
|
178
|
+
sender: bundler3,
|
|
178
179
|
address: morpho,
|
|
179
180
|
args: {
|
|
180
181
|
owner: sender,
|
|
@@ -238,6 +239,9 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
238
239
|
requiredAssets -= withdrawal.assets;
|
|
239
240
|
vaultReallocations.push(withdrawal);
|
|
240
241
|
}
|
|
242
|
+
// TODO: we know there are no unwrap native in the middle
|
|
243
|
+
// of the bundle so we are certain we need to add an input transfer.
|
|
244
|
+
// This could be handled by `simulateRequiredTokenAmounts` below.
|
|
241
245
|
const fees = keys(reallocations).reduce((total, vault) => total + data.getVault(vault).publicAllocatorConfig.fee, 0n);
|
|
242
246
|
// Native input transfer of all fees.
|
|
243
247
|
if (fees > 0n)
|
|
@@ -248,14 +252,14 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
248
252
|
args: {
|
|
249
253
|
amount: fees,
|
|
250
254
|
from: sender,
|
|
251
|
-
to:
|
|
255
|
+
to: bundler3,
|
|
252
256
|
},
|
|
253
257
|
});
|
|
254
258
|
}
|
|
255
259
|
// Reallocate each vault.
|
|
256
260
|
operations.push(...Object.entries(reallocations).map(([vault, vaultWithdrawals]) => ({
|
|
257
261
|
type: "MetaMorpho_PublicReallocate",
|
|
258
|
-
sender:
|
|
262
|
+
sender: bundler3,
|
|
259
263
|
address: vault,
|
|
260
264
|
args: {
|
|
261
265
|
// Reallocation withdrawals must be sorted by market id in ascending alphabetical order.
|
|
@@ -296,7 +300,7 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
296
300
|
mainOperation.args.assets === maxUint256) ||
|
|
297
301
|
("shares" in mainOperation.args && mainOperation.args.shares === maxUint256)) {
|
|
298
302
|
if (mainOperation.type === "MetaMorpho_Withdraw")
|
|
299
|
-
mainOperation.args.owner =
|
|
303
|
+
mainOperation.args.owner = generalAdapter1;
|
|
300
304
|
return allOperations;
|
|
301
305
|
}
|
|
302
306
|
const requirementOperations = getRequirementOperations?.(requiredTokenAmounts) ?? [];
|
|
@@ -307,12 +311,12 @@ export const populateSubBundle = (inputOperation, data, options = {}) => {
|
|
|
307
311
|
requiredTokenAmounts.forEach(({ token, required }) => {
|
|
308
312
|
requirementOperations.push(...populateInputTransfer({
|
|
309
313
|
type: "Erc20_Transfer",
|
|
310
|
-
sender:
|
|
314
|
+
sender: generalAdapter1,
|
|
311
315
|
address: token,
|
|
312
316
|
args: {
|
|
313
317
|
amount: required,
|
|
314
318
|
from: sender,
|
|
315
|
-
to:
|
|
319
|
+
to: generalAdapter1,
|
|
316
320
|
},
|
|
317
321
|
}, data, { hasSimplePermit: withSimplePermit.has(token) }));
|
|
318
322
|
});
|
|
@@ -334,8 +338,9 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
334
338
|
const nbOperations = operations.length;
|
|
335
339
|
if (nbOperations === 0)
|
|
336
340
|
return operations;
|
|
337
|
-
const {
|
|
338
|
-
if (receiver
|
|
341
|
+
const { bundler3: { bundler3, generalAdapter1 }, } = getChainAddresses(startData.chainId);
|
|
342
|
+
if (isAddressEqual(receiver, bundler3) ||
|
|
343
|
+
isAddressEqual(receiver, generalAdapter1))
|
|
339
344
|
throw Error(`receiver is bundler`);
|
|
340
345
|
const approvals = [];
|
|
341
346
|
const permits = [];
|
|
@@ -387,8 +392,8 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
387
392
|
}
|
|
388
393
|
case "Erc20_Transfer": {
|
|
389
394
|
const { address, sender, args: { amount, from, to }, } = operation;
|
|
390
|
-
if (from !==
|
|
391
|
-
to ===
|
|
395
|
+
if (from !== generalAdapter1 &&
|
|
396
|
+
to === generalAdapter1 &&
|
|
392
397
|
!erc20WrapperTokens[startData.chainId].has(address)) {
|
|
393
398
|
const duplicateTransfer = inputTransfers.find((transfer) => transfer.address === address &&
|
|
394
399
|
transfer.sender === sender &&
|
|
@@ -405,7 +410,7 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
405
410
|
}
|
|
406
411
|
case "Erc20_Transfer2": {
|
|
407
412
|
const { address, sender, args: { amount, from, to }, } = operation;
|
|
408
|
-
if (from !==
|
|
413
|
+
if (from !== generalAdapter1 && to === generalAdapter1) {
|
|
409
414
|
const duplicateTransfer2 = inputTransfer2s.find((transfer) => transfer.address === address &&
|
|
410
415
|
transfer.sender === sender &&
|
|
411
416
|
transfer.args.from === from);
|
|
@@ -436,15 +441,15 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
436
441
|
// Redirect MetaMorpho deposits.
|
|
437
442
|
operations.forEach((operation, index) => {
|
|
438
443
|
if (operation.type !== "MetaMorpho_Deposit" ||
|
|
439
|
-
operation.args.owner !==
|
|
444
|
+
operation.args.owner !== generalAdapter1)
|
|
440
445
|
return;
|
|
441
446
|
const token = operation.address;
|
|
442
447
|
// shares are not defined when depositing assets, so we rely on simulation steps.
|
|
443
|
-
const shares = steps[index + 1].getHolding(
|
|
444
|
-
steps[index].getHolding(
|
|
448
|
+
const shares = steps[index + 1].getHolding(generalAdapter1, token).balance -
|
|
449
|
+
steps[index].getHolding(generalAdapter1, token).balance;
|
|
445
450
|
if (steps
|
|
446
451
|
.slice(index + 2)
|
|
447
|
-
.some((step) => step.getHolding(
|
|
452
|
+
.some((step) => step.getHolding(generalAdapter1, token).balance < shares))
|
|
448
453
|
// If the bundler's balance is at least once lower than assets, the bundler does need these assets.
|
|
449
454
|
return;
|
|
450
455
|
operation.args.owner = receiver;
|
|
@@ -466,14 +471,14 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
466
471
|
default:
|
|
467
472
|
return;
|
|
468
473
|
}
|
|
469
|
-
if (operation.args.receiver !==
|
|
474
|
+
if (operation.args.receiver !== generalAdapter1 || unwrapTokens.has(token))
|
|
470
475
|
return;
|
|
471
476
|
// assets are not defined when using shares, so we rely on simulation steps.
|
|
472
|
-
const assets = steps[index + 1].getHolding(
|
|
473
|
-
steps[index].getHolding(
|
|
477
|
+
const assets = steps[index + 1].getHolding(generalAdapter1, token).balance -
|
|
478
|
+
steps[index].getHolding(generalAdapter1, token).balance;
|
|
474
479
|
if (steps
|
|
475
480
|
.slice(index + 2)
|
|
476
|
-
.some((step) => step.getHolding(
|
|
481
|
+
.some((step) => step.getHolding(generalAdapter1, token).balance < assets))
|
|
477
482
|
// If the bundler's balance is at least once lower than assets, the bundler does need these assets.
|
|
478
483
|
return;
|
|
479
484
|
operation.args.receiver = receiver;
|
|
@@ -481,15 +486,15 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
481
486
|
// Simplify Erc20_Transfer(sender = bundler, to = bundler) + MetaMorpho_Withdraw(owner = bundler) = MetaMorpho_Withdraw(owner = from).
|
|
482
487
|
operations.forEach((operation, index) => {
|
|
483
488
|
if (operation.type !== "MetaMorpho_Withdraw" ||
|
|
484
|
-
operation.args.owner !==
|
|
489
|
+
operation.args.owner !== generalAdapter1)
|
|
485
490
|
return;
|
|
486
491
|
// shares are not defined when using assets, so we rely on simulation steps.
|
|
487
|
-
const shares = steps[index].getHolding(
|
|
488
|
-
steps[index + 1].getHolding(
|
|
492
|
+
const shares = steps[index].getHolding(generalAdapter1, operation.address).balance -
|
|
493
|
+
steps[index + 1].getHolding(generalAdapter1, operation.address).balance;
|
|
489
494
|
const inputTransferIndex = operations.findIndex((candidate) => candidate.type === "Erc20_Transfer" &&
|
|
490
495
|
candidate.address === operation.address &&
|
|
491
|
-
candidate.sender ===
|
|
492
|
-
candidate.args.to ===
|
|
496
|
+
candidate.sender === generalAdapter1 &&
|
|
497
|
+
candidate.args.to === generalAdapter1 &&
|
|
493
498
|
candidate.args.amount >= shares);
|
|
494
499
|
if (inputTransferIndex <= 0)
|
|
495
500
|
return;
|
|
@@ -502,12 +507,12 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
502
507
|
if (operation.type !== "Erc20_Transfer")
|
|
503
508
|
return true;
|
|
504
509
|
const { amount, from, to } = operation.args;
|
|
505
|
-
if (from ===
|
|
510
|
+
if (from === generalAdapter1 || to !== generalAdapter1)
|
|
506
511
|
return true;
|
|
507
512
|
const token = operation.address;
|
|
508
513
|
if (steps
|
|
509
514
|
.slice(index + 2)
|
|
510
|
-
.some((step) => step.getHolding(
|
|
515
|
+
.some((step) => step.getHolding(generalAdapter1, token).balance < amount))
|
|
511
516
|
// If the bundler's balance is at least once less than amount, the bundler does need these assets.
|
|
512
517
|
// Do not only keep the amount actually used in this case because some input transfers
|
|
513
518
|
// are expected to be larger to account for slippage.
|
|
@@ -518,7 +523,7 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
518
523
|
steps = simulateBundlerOperations(operations, startData, { slippage: 0n });
|
|
519
524
|
// Unwrap requested remaining wrapped tokens.
|
|
520
525
|
const unwraps = [];
|
|
521
|
-
const endBundlerTokenData = getLast(steps).holdings[
|
|
526
|
+
const endBundlerTokenData = getLast(steps).holdings[generalAdapter1] ?? {};
|
|
522
527
|
unwrapTokens.forEach((wrappedToken) => {
|
|
523
528
|
const remaining = endBundlerTokenData[wrappedToken]?.balance ?? 0n;
|
|
524
529
|
if (remaining <= 5n)
|
|
@@ -529,7 +534,7 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
529
534
|
unwraps.push({
|
|
530
535
|
type: "Erc20_Unwrap",
|
|
531
536
|
address: wrappedToken,
|
|
532
|
-
sender:
|
|
537
|
+
sender: generalAdapter1,
|
|
533
538
|
args: {
|
|
534
539
|
amount: maxUint256,
|
|
535
540
|
receiver,
|
|
@@ -544,17 +549,19 @@ export const finalizeBundle = (operations, startData, receiver, unwrapTokens = n
|
|
|
544
549
|
// Skim any token expected to be left on the bundler.
|
|
545
550
|
const skims = [];
|
|
546
551
|
{
|
|
547
|
-
const startBundlerTokenData = steps[0].holdings[
|
|
548
|
-
const endBundlerTokenData = getLast(steps).holdings[
|
|
552
|
+
const startBundlerTokenData = steps[0].holdings[generalAdapter1] ?? {};
|
|
553
|
+
const endBundlerTokenData = getLast(steps).holdings[generalAdapter1] ?? {};
|
|
549
554
|
skims.push(...entries(endBundlerTokenData)
|
|
550
|
-
.filter(([token,
|
|
555
|
+
.filter(([token, holding]) => holding != null &&
|
|
556
|
+
holding.balance - (startBundlerTokenData[token]?.balance ?? 0n) >
|
|
557
|
+
5n)
|
|
551
558
|
.map(([address]) => ({
|
|
552
559
|
type: "Erc20_Transfer",
|
|
553
560
|
address,
|
|
554
|
-
sender:
|
|
561
|
+
sender: generalAdapter1,
|
|
555
562
|
args: {
|
|
556
563
|
amount: maxUint256,
|
|
557
|
-
from:
|
|
564
|
+
from: generalAdapter1,
|
|
558
565
|
to: receiver,
|
|
559
566
|
},
|
|
560
567
|
})));
|
|
@@ -579,15 +586,17 @@ export const populateBundle = (inputOperations, data, options) => {
|
|
|
579
586
|
return { operations, steps };
|
|
580
587
|
};
|
|
581
588
|
export const simulateRequiredTokenAmounts = (operations, data) => {
|
|
582
|
-
const {
|
|
589
|
+
const { bundler3: { generalAdapter1 }, } = getChainAddresses(data.chainId);
|
|
583
590
|
const virtualBundlerData = produceImmutable(data, (draft) => {
|
|
584
|
-
Object.values(draft.holdings[
|
|
591
|
+
Object.values(draft.holdings[generalAdapter1] ?? {}).forEach((bundlerTokenData) => {
|
|
592
|
+
if (bundlerTokenData == null)
|
|
593
|
+
return;
|
|
585
594
|
// Virtual balance to calculate the amount required.
|
|
586
595
|
bundlerTokenData.balance += MathLib.MAX_UINT_160;
|
|
587
596
|
});
|
|
588
597
|
});
|
|
589
598
|
const steps = simulateOperations(operations, virtualBundlerData);
|
|
590
|
-
const bundlerTokenDiffs = keys(virtualBundlerData.holdings[
|
|
599
|
+
const bundlerTokenDiffs = keys(virtualBundlerData.holdings[generalAdapter1]).map((token) => ({
|
|
591
600
|
token,
|
|
592
601
|
required: steps
|
|
593
602
|
.map((step) =>
|
|
@@ -597,7 +606,7 @@ export const simulateRequiredTokenAmounts = (operations, data) => {
|
|
|
597
606
|
// | |=> MAX_UINT_160 - (2 * MAX_UINT_160 - y) < 0
|
|
598
607
|
// |=> MAX_UINT_160 - (MAX_UINT_160 - y - x) > 0
|
|
599
608
|
MathLib.MAX_UINT_160 -
|
|
600
|
-
(step.holdings[
|
|
609
|
+
(step.holdings[generalAdapter1]?.[token]?.balance ?? 0n))
|
|
601
610
|
.sort(bigIntComparator((required) => required,
|
|
602
611
|
// Take the highest required amount among all operations.
|
|
603
612
|
"desc"))[0],
|
package/lib/types/actions.d.ts
CHANGED
|
@@ -24,54 +24,68 @@ export interface Permit2PermitSingle {
|
|
|
24
24
|
sigDeadline: bigint;
|
|
25
25
|
}
|
|
26
26
|
export interface ActionArgs {
|
|
27
|
-
nativeTransfer: [recipient: Address, amount: bigint];
|
|
27
|
+
nativeTransfer: [owner: Address, recipient: Address, amount: bigint];
|
|
28
28
|
erc20Transfer: [asset: Address, recipient: Address, amount: bigint];
|
|
29
|
-
erc20TransferFrom: [asset: Address, amount: bigint];
|
|
30
|
-
erc20WrapperDepositFor: [
|
|
31
|
-
|
|
29
|
+
erc20TransferFrom: [asset: Address, amount: bigint, recipient?: Address];
|
|
30
|
+
erc20WrapperDepositFor: [
|
|
31
|
+
wrapper: Address,
|
|
32
|
+
underlying: Address,
|
|
33
|
+
amount: bigint
|
|
34
|
+
];
|
|
35
|
+
erc20WrapperWithdrawTo: [wrapper: Address, receiver: Address, amount: bigint];
|
|
32
36
|
permit: [
|
|
37
|
+
owner: Address,
|
|
33
38
|
asset: Address,
|
|
34
39
|
amount: bigint,
|
|
35
40
|
deadline: bigint,
|
|
36
41
|
signature: Hex | null,
|
|
42
|
+
spender?: Address,
|
|
37
43
|
skipRevert?: boolean
|
|
38
44
|
];
|
|
39
45
|
permitDai: [
|
|
46
|
+
owner: Address,
|
|
40
47
|
nonce: bigint,
|
|
41
48
|
expiry: bigint,
|
|
42
49
|
allowed: boolean,
|
|
43
50
|
signature: Hex | null,
|
|
51
|
+
spender?: Address,
|
|
44
52
|
skipRevert?: boolean
|
|
45
53
|
];
|
|
46
54
|
approve2: [
|
|
55
|
+
owner: Address,
|
|
47
56
|
permitSingle: Permit2PermitSingle,
|
|
48
57
|
signature: Hex | null,
|
|
49
58
|
skipRevert?: boolean
|
|
50
59
|
];
|
|
51
|
-
transferFrom2: [
|
|
60
|
+
transferFrom2: [
|
|
61
|
+
asset: Address,
|
|
62
|
+
owner: Address,
|
|
63
|
+
amount: bigint,
|
|
64
|
+
recipient?: Address
|
|
65
|
+
];
|
|
52
66
|
erc4626Mint: [
|
|
53
67
|
erc4626: Address,
|
|
54
68
|
shares: bigint,
|
|
55
|
-
|
|
69
|
+
maxSharePrice: bigint,
|
|
56
70
|
receiver: Address
|
|
57
71
|
];
|
|
58
72
|
erc4626Deposit: [
|
|
59
73
|
erc4626: Address,
|
|
60
74
|
assets: bigint,
|
|
61
|
-
|
|
75
|
+
maxSharePrice: bigint,
|
|
62
76
|
receiver: Address
|
|
63
77
|
];
|
|
64
78
|
erc4626Withdraw: [
|
|
65
79
|
erc4626: Address,
|
|
66
80
|
assets: bigint,
|
|
67
|
-
|
|
81
|
+
minSharePrice: bigint,
|
|
68
82
|
receiver: Address,
|
|
69
83
|
owner: Address
|
|
70
84
|
];
|
|
71
85
|
erc4626Redeem: [
|
|
72
86
|
erc4626: Address,
|
|
73
87
|
shares: bigint,
|
|
74
|
-
|
|
88
|
+
minSharePrice: bigint,
|
|
75
89
|
receiver: Address,
|
|
76
90
|
owner: Address
|
|
77
91
|
];
|
|
@@ -128,9 +142,8 @@ export interface ActionArgs {
|
|
|
128
142
|
receiver: Address
|
|
129
143
|
];
|
|
130
144
|
reallocateTo: [
|
|
131
|
-
publicAllocator: Address,
|
|
132
145
|
vault: Address,
|
|
133
|
-
|
|
146
|
+
fee: bigint,
|
|
134
147
|
withdrawals: InputReallocation[],
|
|
135
148
|
supplyMarket: InputMarketParams
|
|
136
149
|
];
|
|
@@ -142,39 +155,72 @@ export interface ActionArgs {
|
|
|
142
155
|
proof: Hex[],
|
|
143
156
|
skipRevert?: boolean
|
|
144
157
|
];
|
|
145
|
-
wrapNative: [amount: bigint];
|
|
146
|
-
unwrapNative: [amount: bigint];
|
|
147
|
-
stakeEth: [
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
wrapNative: [amount: bigint, recipient?: Address];
|
|
159
|
+
unwrapNative: [amount: bigint, recipient?: Address];
|
|
160
|
+
stakeEth: [
|
|
161
|
+
amount: bigint,
|
|
162
|
+
minShares: bigint,
|
|
163
|
+
referral: Address,
|
|
164
|
+
recipient?: Address
|
|
165
|
+
];
|
|
166
|
+
wrapStEth: [amount: bigint, recipient?: Address];
|
|
167
|
+
unwrapStEth: [amount: bigint, recipient?: Address];
|
|
168
|
+
aaveV2Repay: [
|
|
169
|
+
asset: Address,
|
|
170
|
+
amount: bigint,
|
|
171
|
+
onBehalf: Address,
|
|
172
|
+
rateMode?: bigint
|
|
173
|
+
];
|
|
174
|
+
aaveV2Withdraw: [asset: Address, amount: bigint, recipient?: Address];
|
|
175
|
+
aaveV3Repay: [
|
|
176
|
+
asset: Address,
|
|
177
|
+
amount: bigint,
|
|
178
|
+
onBehalf: Address,
|
|
179
|
+
rateMode?: bigint
|
|
180
|
+
];
|
|
181
|
+
aaveV3Withdraw: [asset: Address, amount: bigint, recipient?: Address];
|
|
182
|
+
aaveV3OptimizerRepay: [
|
|
183
|
+
underlying: Address,
|
|
184
|
+
amount: bigint,
|
|
185
|
+
onBehalf: Address
|
|
186
|
+
];
|
|
155
187
|
aaveV3OptimizerWithdraw: [
|
|
156
188
|
underlying: Address,
|
|
157
189
|
amount: bigint,
|
|
158
|
-
maxIterations: bigint
|
|
190
|
+
maxIterations: bigint,
|
|
191
|
+
recipient?: Address
|
|
192
|
+
];
|
|
193
|
+
aaveV3OptimizerWithdrawCollateral: [
|
|
194
|
+
underlying: Address,
|
|
195
|
+
amount: bigint,
|
|
196
|
+
recipient?: Address
|
|
159
197
|
];
|
|
160
|
-
aaveV3OptimizerWithdrawCollateral: [underlying: Address, amount: bigint];
|
|
161
198
|
aaveV3OptimizerApproveManagerWithSig: [
|
|
199
|
+
owner: Address,
|
|
162
200
|
isApproved: boolean,
|
|
163
201
|
nonce: bigint,
|
|
164
202
|
deadline: bigint,
|
|
165
203
|
signature: Hex | null,
|
|
204
|
+
manager?: Address,
|
|
166
205
|
skipRevert?: boolean
|
|
167
206
|
];
|
|
168
|
-
compoundV2Repay: [cToken: Address, amount: bigint];
|
|
169
|
-
compoundV2Redeem: [cToken: Address, amount: bigint];
|
|
170
|
-
compoundV3Repay: [instance: Address, amount: bigint];
|
|
171
|
-
compoundV3WithdrawFrom: [
|
|
207
|
+
compoundV2Repay: [cToken: Address, amount: bigint, onBehalf: Address];
|
|
208
|
+
compoundV2Redeem: [cToken: Address, amount: bigint, recipient?: Address];
|
|
209
|
+
compoundV3Repay: [instance: Address, amount: bigint, onBehalf: Address];
|
|
210
|
+
compoundV3WithdrawFrom: [
|
|
211
|
+
instance: Address,
|
|
212
|
+
asset: Address,
|
|
213
|
+
amount: bigint,
|
|
214
|
+
recipient?: Address
|
|
215
|
+
];
|
|
172
216
|
compoundV3AllowBySig: [
|
|
173
217
|
instance: Address,
|
|
218
|
+
owner: Address,
|
|
174
219
|
isAllowed: boolean,
|
|
175
220
|
nonce: bigint,
|
|
176
221
|
expiry: bigint,
|
|
177
222
|
signature: Hex | null,
|
|
223
|
+
manager?: Address,
|
|
178
224
|
skipRevert?: boolean
|
|
179
225
|
];
|
|
180
226
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morpho-org/bundler-sdk-viem",
|
|
3
3
|
"description": "Viem-based extension of `@morpho-org/simulation-sdk` that exports utilities to transform simple interactions on Morpho (such as `Blue_Borrow`) and Morpho Vaults (such as `MetaMorpho_Deposit`) into the required bundles (with ERC20 approvals, transfers, etc) to submit to the bundler onchain.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0-next.1",
|
|
5
5
|
"author": "Morpho Association <contact@morpho.org>",
|
|
6
6
|
"contributors": [
|
|
7
7
|
"Rubilmax <rmilon@gmail.com>"
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
],
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"viem": "^2.0.0",
|
|
23
|
-
"@morpho-org/blue-sdk": "^3.0.0-next.
|
|
24
|
-
"@morpho-org/
|
|
25
|
-
"@morpho-org/
|
|
26
|
-
"@morpho-org/
|
|
23
|
+
"@morpho-org/blue-sdk-viem": "^3.0.0-next.1",
|
|
24
|
+
"@morpho-org/simulation-sdk": "^3.0.0-next.1",
|
|
25
|
+
"@morpho-org/blue-sdk": "^3.0.0-next.3",
|
|
26
|
+
"@morpho-org/morpho-ts": "^2.1.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@tanstack/query-core": "^5.62.16",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"typescript": "^5.7.2",
|
|
36
36
|
"viem": "^2.23.0",
|
|
37
37
|
"vitest": "^3.0.5",
|
|
38
|
-
"@morpho-org/blue-sdk": "^3.0.0-next.
|
|
39
|
-
"@morpho-org/blue-sdk-viem": "^
|
|
40
|
-
"@morpho-org/morpho-ts": "^2.1.0",
|
|
41
|
-
"@morpho-org/simulation-sdk": "^2.2.0-next.0",
|
|
38
|
+
"@morpho-org/blue-sdk": "^3.0.0-next.3",
|
|
39
|
+
"@morpho-org/blue-sdk-viem": "^3.0.0-next.1",
|
|
42
40
|
"@morpho-org/morpho-test": "^2.2.1",
|
|
43
|
-
"@morpho-org/
|
|
41
|
+
"@morpho-org/morpho-ts": "^2.1.0",
|
|
42
|
+
"@morpho-org/simulation-sdk": "^3.0.0-next.1",
|
|
43
|
+
"@morpho-org/simulation-sdk-wagmi": "^2.0.5",
|
|
44
44
|
"@morpho-org/test": "^2.0.6",
|
|
45
45
|
"@morpho-org/test-wagmi": "^2.0.4"
|
|
46
46
|
},
|