@gearbox-protocol/sdk 14.12.0-next.1 → 14.12.0-next.2
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/cjs/abi/iZapper.js +62 -24
- package/dist/cjs/preview/parse/errors.js +5 -2
- package/dist/cjs/preview/parse/parseOperationCalldata.js +30 -1
- package/dist/cjs/preview/parse/parsePoolOperationCalldata.js +10 -2
- package/dist/cjs/preview/prerequisites/buildPrerequisites.js +34 -0
- package/dist/cjs/preview/simulate/errors.js +0 -7
- package/dist/cjs/preview/simulate/index.js +0 -3
- package/dist/cjs/preview/simulate/simulatePoolOperation.js +154 -29
- package/dist/cjs/sdk/MultichainSDK.js +1 -0
- package/dist/cjs/sdk/OnchainSDK.js +7 -3
- package/dist/cjs/sdk/market/MarketRegister.js +10 -5
- package/dist/cjs/sdk/market/ZapperRegister.js +54 -0
- package/dist/cjs/sdk/market/zapper/IERC20ZapperContract.js +3 -38
- package/dist/cjs/sdk/market/zapper/IETHZapperContract.js +3 -38
- package/dist/cjs/sdk/market/zapper/ZapperContract.js +109 -0
- package/dist/cjs/sdk/market/zapper/createZapper.js +12 -4
- package/dist/cjs/{preview/simulate/constants.js → sdk/market/zapper/errors.js} +15 -6
- package/dist/cjs/sdk/market/zapper/index.js +6 -2
- package/dist/cjs/sdk/market/zapper/types.js +16 -0
- package/dist/cjs/sdk/options.js +41 -17
- package/dist/esm/abi/iZapper.js +62 -24
- package/dist/esm/preview/parse/errors.js +3 -1
- package/dist/esm/preview/parse/parseOperationCalldata.js +32 -2
- package/dist/esm/preview/parse/parsePoolOperationCalldata.js +10 -2
- package/dist/esm/preview/prerequisites/buildPrerequisites.js +34 -0
- package/dist/esm/preview/simulate/errors.js +0 -6
- package/dist/esm/preview/simulate/index.js +0 -2
- package/dist/esm/preview/simulate/simulatePoolOperation.js +155 -30
- package/dist/esm/sdk/MultichainSDK.js +1 -0
- package/dist/esm/sdk/OnchainSDK.js +7 -3
- package/dist/esm/sdk/market/MarketRegister.js +10 -5
- package/dist/esm/sdk/market/ZapperRegister.js +54 -0
- package/dist/esm/sdk/market/zapper/IERC20ZapperContract.js +3 -38
- package/dist/esm/sdk/market/zapper/IETHZapperContract.js +3 -38
- package/dist/esm/sdk/market/zapper/ZapperContract.js +85 -0
- package/dist/esm/sdk/market/zapper/createZapper.js +12 -4
- package/dist/esm/sdk/market/zapper/errors.js +13 -0
- package/dist/esm/sdk/market/zapper/index.js +3 -1
- package/dist/esm/sdk/market/zapper/types.js +0 -0
- package/dist/esm/sdk/options.js +39 -15
- package/dist/types/abi/iERC20Zapper.d.ts +91 -23
- package/dist/types/abi/iETHZapper.d.ts +91 -23
- package/dist/types/abi/iZapper.d.ts +91 -23
- package/dist/types/preview/parse/errors.d.ts +1 -0
- package/dist/types/preview/parse/parseOperationCalldata.d.ts +3 -3
- package/dist/types/preview/parse/types-pools.d.ts +61 -1
- package/dist/types/preview/simulate/errors.d.ts +6 -12
- package/dist/types/preview/simulate/index.d.ts +0 -1
- package/dist/types/preview/simulate/simulatePoolOperation.d.ts +22 -4
- package/dist/types/preview/simulate/types.d.ts +3 -16
- package/dist/types/sdk/MultichainSDK.d.ts +5 -0
- package/dist/types/sdk/OnchainSDK.d.ts +4 -0
- package/dist/types/sdk/market/MarketRegister.d.ts +15 -6
- package/dist/types/sdk/market/ZapperRegister.d.ts +25 -4
- package/dist/types/sdk/market/zapper/IERC20ZapperContract.d.ts +93 -39
- package/dist/types/sdk/market/zapper/IETHZapperContract.d.ts +93 -39
- package/dist/types/sdk/market/zapper/ZapperContract.d.ts +35 -0
- package/dist/types/sdk/market/zapper/createZapper.d.ts +2 -4
- package/dist/types/sdk/market/zapper/errors.d.ts +10 -0
- package/dist/types/sdk/market/zapper/index.d.ts +3 -1
- package/dist/types/sdk/market/zapper/types.d.ts +64 -0
- package/dist/types/sdk/options.d.ts +10 -5
- package/dist/types/sdk/pools/types.d.ts +3 -3
- package/dist/types/sdk/types/state-human.d.ts +9 -0
- package/dist/types/sdk/types/state.d.ts +7 -0
- package/package.json +3 -3
- package/dist/cjs/preview/simulate/extractERC20Transfers.js +0 -47
- package/dist/cjs/preview/simulate/simulatePoolOpMulticall.js +0 -155
- package/dist/cjs/preview/simulate/simulatePoolOpV1.js +0 -106
- package/dist/cjs/sdk/market/zapper/Zapper.js +0 -47
- package/dist/esm/preview/simulate/constants.js +0 -4
- package/dist/esm/preview/simulate/extractERC20Transfers.js +0 -23
- package/dist/esm/preview/simulate/simulatePoolOpMulticall.js +0 -130
- package/dist/esm/preview/simulate/simulatePoolOpV1.js +0 -82
- package/dist/esm/sdk/market/zapper/Zapper.js +0 -23
- package/dist/types/preview/simulate/constants.d.ts +0 -6
- package/dist/types/preview/simulate/extractERC20Transfers.d.ts +0 -11
- package/dist/types/preview/simulate/simulatePoolOpMulticall.d.ts +0 -28
- package/dist/types/preview/simulate/simulatePoolOpV1.d.ts +0 -14
- package/dist/types/sdk/market/zapper/Zapper.d.ts +0 -13
|
@@ -1,16 +1,46 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CreditFacadeV310Contract,
|
|
3
|
-
PoolV310Contract
|
|
3
|
+
PoolV310Contract,
|
|
4
|
+
ZapperContract
|
|
4
5
|
} from "../../sdk/index.js";
|
|
5
6
|
import { UnsupportedTargetError } from "./errors.js";
|
|
6
7
|
import { parseFacadeOperationCalldata } from "./parseFacadeOperationCalldata.js";
|
|
7
8
|
import { parsePoolOperationCalldata } from "./parsePoolOperationCalldata.js";
|
|
8
9
|
function parseOperationCalldata(input) {
|
|
9
|
-
const { sdk, to, calldata } = input;
|
|
10
|
+
const { sdk, to, calldata, value, sender } = input;
|
|
10
11
|
const contract = sdk.getContract(to);
|
|
11
12
|
if (contract instanceof PoolV310Contract) {
|
|
12
13
|
return parsePoolOperationCalldata({ sdk, pool: contract, calldata });
|
|
13
14
|
}
|
|
15
|
+
if (contract instanceof ZapperContract) {
|
|
16
|
+
const parsed = contract.parseOperation(calldata, value);
|
|
17
|
+
if (parsed.operation === "Deposit") {
|
|
18
|
+
const op2 = {
|
|
19
|
+
operation: "Deposit",
|
|
20
|
+
pool: parsed.pool,
|
|
21
|
+
receiver: parsed.receiver,
|
|
22
|
+
assets: parsed.assets,
|
|
23
|
+
underlying: parsed.underlying,
|
|
24
|
+
tokenIn: parsed.token,
|
|
25
|
+
zapper: parsed.zapper,
|
|
26
|
+
referralCode: parsed.referralCode
|
|
27
|
+
};
|
|
28
|
+
return op2;
|
|
29
|
+
}
|
|
30
|
+
const op = {
|
|
31
|
+
operation: "Redeem",
|
|
32
|
+
pool: parsed.pool,
|
|
33
|
+
receiver: parsed.receiver,
|
|
34
|
+
// The zapper burns the caller's pool shares, so the share owner is the
|
|
35
|
+
// transaction sender.
|
|
36
|
+
owner: sender,
|
|
37
|
+
shares: parsed.shares,
|
|
38
|
+
underlying: parsed.underlying,
|
|
39
|
+
tokenOut: parsed.token,
|
|
40
|
+
zapper: parsed.zapper
|
|
41
|
+
};
|
|
42
|
+
return op;
|
|
43
|
+
}
|
|
14
44
|
if (contract instanceof CreditFacadeV310Contract) {
|
|
15
45
|
return parseFacadeOperationCalldata({
|
|
16
46
|
sdk,
|
|
@@ -14,6 +14,8 @@ function parsePoolOperationCalldata(props) {
|
|
|
14
14
|
receiver: rawArgs.receiver,
|
|
15
15
|
assets: rawArgs.assets,
|
|
16
16
|
underlying,
|
|
17
|
+
tokenIn: underlying,
|
|
18
|
+
zapper: void 0,
|
|
17
19
|
referralCode: functionName === "depositWithReferral" ? rawArgs.referralCode : void 0
|
|
18
20
|
};
|
|
19
21
|
case "mint":
|
|
@@ -24,6 +26,8 @@ function parsePoolOperationCalldata(props) {
|
|
|
24
26
|
receiver: rawArgs.receiver,
|
|
25
27
|
shares: rawArgs.shares,
|
|
26
28
|
underlying,
|
|
29
|
+
tokenIn: underlying,
|
|
30
|
+
zapper: void 0,
|
|
27
31
|
referralCode: functionName === "mintWithReferral" ? rawArgs.referralCode : void 0
|
|
28
32
|
};
|
|
29
33
|
case "withdraw":
|
|
@@ -33,7 +37,9 @@ function parsePoolOperationCalldata(props) {
|
|
|
33
37
|
receiver: rawArgs.receiver,
|
|
34
38
|
owner: rawArgs.owner,
|
|
35
39
|
assets: rawArgs.assets,
|
|
36
|
-
underlying
|
|
40
|
+
underlying,
|
|
41
|
+
tokenOut: underlying,
|
|
42
|
+
zapper: void 0
|
|
37
43
|
};
|
|
38
44
|
case "redeem":
|
|
39
45
|
return {
|
|
@@ -42,7 +48,9 @@ function parsePoolOperationCalldata(props) {
|
|
|
42
48
|
receiver: rawArgs.receiver,
|
|
43
49
|
owner: rawArgs.owner,
|
|
44
50
|
shares: rawArgs.shares,
|
|
45
|
-
underlying
|
|
51
|
+
underlying,
|
|
52
|
+
tokenOut: underlying,
|
|
53
|
+
zapper: void 0
|
|
46
54
|
};
|
|
47
55
|
default:
|
|
48
56
|
throw new UnsupportedPoolFunctionError(pool.address, parsed.functionName);
|
|
@@ -11,6 +11,23 @@ function buildPrerequisites(tx, ctx) {
|
|
|
11
11
|
// here we approximate Mint by its shares amount (a lower bound on assets is
|
|
12
12
|
// not knowable from calldata alone).
|
|
13
13
|
case "Deposit":
|
|
14
|
+
if (tx.zapper) {
|
|
15
|
+
return [
|
|
16
|
+
new AllowancePrerequisite({
|
|
17
|
+
token: tx.tokenIn,
|
|
18
|
+
owner: wallet,
|
|
19
|
+
spender: tx.zapper,
|
|
20
|
+
required: tx.assets,
|
|
21
|
+
title: "Token approved to zapper"
|
|
22
|
+
}),
|
|
23
|
+
new BalancePrerequisite({
|
|
24
|
+
token: tx.tokenIn,
|
|
25
|
+
owner: wallet,
|
|
26
|
+
required: tx.assets,
|
|
27
|
+
title: "Sufficient token balance"
|
|
28
|
+
})
|
|
29
|
+
];
|
|
30
|
+
}
|
|
14
31
|
return [
|
|
15
32
|
new AllowancePrerequisite({
|
|
16
33
|
token: tx.underlying,
|
|
@@ -45,6 +62,23 @@ function buildPrerequisites(tx, ctx) {
|
|
|
45
62
|
// Redeem and Withdraw both burn LP shares from `owner`; they only differ in
|
|
46
63
|
// which side (shares vs assets) the caller specifies.
|
|
47
64
|
case "Redeem": {
|
|
65
|
+
if (tx.zapper) {
|
|
66
|
+
return [
|
|
67
|
+
new BalancePrerequisite({
|
|
68
|
+
token: tx.pool,
|
|
69
|
+
owner: wallet,
|
|
70
|
+
required: tx.shares,
|
|
71
|
+
title: "Sufficient LP token balance"
|
|
72
|
+
}),
|
|
73
|
+
new AllowancePrerequisite({
|
|
74
|
+
token: tx.pool,
|
|
75
|
+
owner: wallet,
|
|
76
|
+
spender: tx.zapper,
|
|
77
|
+
required: tx.shares,
|
|
78
|
+
title: "LP token approved to zapper"
|
|
79
|
+
})
|
|
80
|
+
];
|
|
81
|
+
}
|
|
48
82
|
const prereqs = [
|
|
49
83
|
new BalancePrerequisite({
|
|
50
84
|
token: tx.pool,
|
|
@@ -27,11 +27,6 @@ function asPreviewSimulationError(reason, source) {
|
|
|
27
27
|
{ source, detail: decodeSimulationError({ error }) }
|
|
28
28
|
]);
|
|
29
29
|
}
|
|
30
|
-
function combinePreviewSimulationErrors(...errors) {
|
|
31
|
-
return new PreviewSimulationError(
|
|
32
|
-
errors.filter((e) => e).flatMap((e) => e?.failures ?? [])
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
30
|
function decodeSimulationError(revert) {
|
|
36
31
|
const { error, data } = revert;
|
|
37
32
|
if (data && data !== "0x") {
|
|
@@ -70,6 +65,5 @@ function formatDecodedError(errorName, args) {
|
|
|
70
65
|
export {
|
|
71
66
|
PreviewSimulationError,
|
|
72
67
|
asPreviewSimulationError,
|
|
73
|
-
combinePreviewSimulationErrors,
|
|
74
68
|
decodeSimulationError
|
|
75
69
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { ETH_SIMULATE_V1_NETWORKS } from "./constants.js";
|
|
2
1
|
import { PreviewSimulationError } from "./errors.js";
|
|
3
2
|
import { simulateFacadeOperation } from "./simulateFacadeOperation.js";
|
|
4
3
|
import { simulateOperation } from "./simulateOperation.js";
|
|
5
4
|
import { simulatePoolOperation } from "./simulatePoolOperation.js";
|
|
6
5
|
export {
|
|
7
|
-
ETH_SIMULATE_V1_NETWORKS,
|
|
8
6
|
PreviewSimulationError,
|
|
9
7
|
simulateFacadeOperation,
|
|
10
8
|
simulateOperation,
|
|
@@ -1,41 +1,166 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { iPoolV310Abi } from "../../abi/310/generated.js";
|
|
2
|
+
import { ierc20Abi } from "../../abi/iERC20.js";
|
|
3
|
+
import { iZapperAbi } from "../../abi/iZapper.js";
|
|
4
|
+
import { AddressMap } from "../../sdk/index.js";
|
|
2
5
|
import {
|
|
3
6
|
asPreviewSimulationError,
|
|
4
|
-
|
|
7
|
+
decodeSimulationError,
|
|
8
|
+
PreviewSimulationError
|
|
5
9
|
} from "./errors.js";
|
|
6
|
-
import {
|
|
7
|
-
|
|
10
|
+
import { watchedHolders } from "./holders.js";
|
|
11
|
+
function previewRead(operation) {
|
|
12
|
+
switch (operation.operation) {
|
|
13
|
+
case "Deposit":
|
|
14
|
+
return { functionName: "previewDeposit", amount: operation.assets };
|
|
15
|
+
case "Mint":
|
|
16
|
+
return { functionName: "previewMint", amount: operation.shares };
|
|
17
|
+
case "Withdraw":
|
|
18
|
+
return { functionName: "previewWithdraw", amount: operation.assets };
|
|
19
|
+
case "Redeem":
|
|
20
|
+
return { functionName: "previewRedeem", amount: operation.shares };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function outsideToken(operation) {
|
|
24
|
+
switch (operation.operation) {
|
|
25
|
+
case "Deposit":
|
|
26
|
+
case "Mint":
|
|
27
|
+
return operation.tokenIn;
|
|
28
|
+
case "Withdraw":
|
|
29
|
+
case "Redeem":
|
|
30
|
+
return operation.tokenOut;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function previewContract(operation) {
|
|
34
|
+
const { functionName, amount } = previewRead(operation);
|
|
35
|
+
if (operation.zapper) {
|
|
36
|
+
return {
|
|
37
|
+
address: operation.zapper,
|
|
38
|
+
abi: iZapperAbi,
|
|
39
|
+
functionName,
|
|
40
|
+
args: [amount]
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
address: operation.pool,
|
|
45
|
+
abi: iPoolV310Abi,
|
|
46
|
+
functionName,
|
|
47
|
+
args: [amount]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
8
50
|
async function simulatePoolOperation(input, options = {}) {
|
|
9
|
-
const { sdk } = input;
|
|
10
|
-
const { logger } = options;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
51
|
+
const { sdk, operation, wallet } = input;
|
|
52
|
+
const { blockNumber, logger } = options;
|
|
53
|
+
const { pool } = operation;
|
|
54
|
+
try {
|
|
55
|
+
const holders = watchedHolders(operation, wallet);
|
|
56
|
+
const tokens = [outsideToken(operation), pool];
|
|
57
|
+
const balanceCalls = holders.flatMap(
|
|
58
|
+
(holder) => tokens.map((token) => ({ holder, token }))
|
|
59
|
+
);
|
|
60
|
+
const balanceContracts = balanceCalls.map(
|
|
61
|
+
({ holder, token }) => ({
|
|
62
|
+
address: token,
|
|
63
|
+
abi: ierc20Abi,
|
|
64
|
+
functionName: "balanceOf",
|
|
65
|
+
args: [holder]
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
const preview = previewContract(operation);
|
|
69
|
+
let results;
|
|
70
|
+
try {
|
|
71
|
+
results = await sdk.client.multicall({
|
|
72
|
+
allowFailure: false,
|
|
73
|
+
// `undefined` lets viem read at `latest`; `blockNumber` is only set for
|
|
74
|
+
// testnet forks pinned to a specific block.
|
|
75
|
+
blockNumber,
|
|
76
|
+
contracts: [...balanceContracts, preview]
|
|
77
|
+
});
|
|
78
|
+
} catch (cause) {
|
|
79
|
+
throw new PreviewSimulationError([
|
|
80
|
+
{
|
|
81
|
+
source: "multicall",
|
|
82
|
+
detail: decodeSimulationError({
|
|
83
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
const previewAmount = results[balanceContracts.length];
|
|
89
|
+
const balances = new AddressMap();
|
|
90
|
+
for (const [i, { holder, token }] of balanceCalls.entries()) {
|
|
91
|
+
const tokenBalances = balances.get(holder) ?? new AddressMap();
|
|
92
|
+
tokenBalances.upsert(token, results[i]);
|
|
93
|
+
balances.upsert(holder, tokenBalances);
|
|
94
|
+
}
|
|
95
|
+
const before = (token, holder) => balances.get(holder)?.get(token) ?? 0n;
|
|
96
|
+
return {
|
|
97
|
+
status: "success",
|
|
98
|
+
balanceChanges: computePoolOpBalanceChanges(
|
|
99
|
+
operation,
|
|
100
|
+
wallet,
|
|
101
|
+
previewAmount,
|
|
102
|
+
before
|
|
103
|
+
)
|
|
104
|
+
};
|
|
105
|
+
} catch (cause) {
|
|
106
|
+
const error = asPreviewSimulationError(cause, "multicall");
|
|
107
|
+
logger?.error(error, "pool operation simulation failed");
|
|
108
|
+
return { status: "failure", error };
|
|
22
109
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
110
|
+
}
|
|
111
|
+
function balanceLegs(operation, wallet, previewAmount) {
|
|
112
|
+
const { pool, receiver } = operation;
|
|
113
|
+
switch (operation.operation) {
|
|
114
|
+
case "Deposit":
|
|
115
|
+
return [
|
|
116
|
+
{ address: wallet, token: operation.tokenIn, delta: -operation.assets },
|
|
117
|
+
{ address: receiver, token: pool, delta: previewAmount }
|
|
118
|
+
];
|
|
119
|
+
case "Mint":
|
|
120
|
+
return [
|
|
121
|
+
{ address: wallet, token: operation.tokenIn, delta: -previewAmount },
|
|
122
|
+
{ address: receiver, token: pool, delta: operation.shares }
|
|
123
|
+
];
|
|
124
|
+
case "Withdraw":
|
|
125
|
+
return [
|
|
126
|
+
{ address: operation.owner, token: pool, delta: -previewAmount },
|
|
127
|
+
{
|
|
128
|
+
address: receiver,
|
|
129
|
+
token: operation.tokenOut,
|
|
130
|
+
delta: operation.assets
|
|
131
|
+
}
|
|
132
|
+
];
|
|
133
|
+
case "Redeem":
|
|
134
|
+
return [
|
|
135
|
+
{ address: operation.owner, token: pool, delta: -operation.shares },
|
|
136
|
+
{ address: receiver, token: operation.tokenOut, delta: previewAmount }
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function computePoolOpBalanceChanges(operation, wallet, previewAmount, before) {
|
|
141
|
+
const byAddress = new AddressMap();
|
|
142
|
+
for (const { address, token, delta } of balanceLegs(
|
|
143
|
+
operation,
|
|
144
|
+
wallet,
|
|
145
|
+
previewAmount
|
|
146
|
+
)) {
|
|
147
|
+
const beforeBalance = before(token, address);
|
|
148
|
+
const change = {
|
|
149
|
+
token,
|
|
150
|
+
before: beforeBalance,
|
|
151
|
+
after: beforeBalance + delta,
|
|
152
|
+
delta
|
|
153
|
+
};
|
|
154
|
+
const existing = byAddress.get(address);
|
|
155
|
+
if (existing) {
|
|
156
|
+
existing.changes.push(change);
|
|
157
|
+
} else {
|
|
158
|
+
byAddress.upsert(address, { address, changes: [change] });
|
|
29
159
|
}
|
|
30
|
-
return { status: "success", ...multicall.value };
|
|
31
160
|
}
|
|
32
|
-
|
|
33
|
-
v1.status === "rejected" ? asPreviewSimulationError(v1.reason, "eth_simulateV1") : void 0,
|
|
34
|
-
asPreviewSimulationError(multicall.reason, "multicall")
|
|
35
|
-
);
|
|
36
|
-
logger?.error(error, "pool operation simulation failed");
|
|
37
|
-
return { status: "failure", error };
|
|
161
|
+
return byAddress.values();
|
|
38
162
|
}
|
|
39
163
|
export {
|
|
164
|
+
computePoolOpBalanceChanges,
|
|
40
165
|
simulatePoolOperation
|
|
41
166
|
};
|
|
@@ -126,7 +126,8 @@ class OnchainSDK extends ChainContractsRegister {
|
|
|
126
126
|
ignoreMarkets,
|
|
127
127
|
marketConfigurators: mcs,
|
|
128
128
|
redstone,
|
|
129
|
-
pyth
|
|
129
|
+
pyth,
|
|
130
|
+
loadZappers
|
|
130
131
|
} = options ?? {};
|
|
131
132
|
const marketConfigurators = mcs ?? TypedObjectUtils.keys(
|
|
132
133
|
this.client.chain.defaultMarketConfigurators
|
|
@@ -195,6 +196,9 @@ class OnchainSDK extends ChainContractsRegister {
|
|
|
195
196
|
blockNumber: this.currentBlock,
|
|
196
197
|
gas: this.gasLimit
|
|
197
198
|
});
|
|
199
|
+
if (loadZappers) {
|
|
200
|
+
await this.#marketRegister.loadZappers();
|
|
201
|
+
}
|
|
198
202
|
}
|
|
199
203
|
const pluginsList = TypedObjectUtils.entries(this.plugins);
|
|
200
204
|
const pluginResponse = await Promise.allSettled(
|
|
@@ -247,7 +251,7 @@ class OnchainSDK extends ChainContractsRegister {
|
|
|
247
251
|
`address provider version: ${this.#addressProvider.version}`
|
|
248
252
|
);
|
|
249
253
|
this.#marketRegister = new MarketRegister(this, ignoreMarkets);
|
|
250
|
-
this.#marketRegister.hydrate(state
|
|
254
|
+
this.#marketRegister.hydrate(state);
|
|
251
255
|
this.#rwa = new RWARegistry(this);
|
|
252
256
|
this.#rwa.setState(state.rwa);
|
|
253
257
|
for (const [name, plugin] of TypedObjectUtils.entries(this.plugins)) {
|
|
@@ -312,7 +316,7 @@ class OnchainSDK extends ChainContractsRegister {
|
|
|
312
316
|
currentBlock: this.currentBlock,
|
|
313
317
|
timestamp: this.timestamp,
|
|
314
318
|
addressProvider: this.addressProvider.state,
|
|
315
|
-
|
|
319
|
+
...this.marketRegister.state,
|
|
316
320
|
rwa: this.#rwa.state,
|
|
317
321
|
plugins: Object.fromEntries(
|
|
318
322
|
TypedObjectUtils.entries(this.plugins).map(([name, plugin]) => [
|
|
@@ -35,10 +35,11 @@ class MarketRegister extends ZapperRegister {
|
|
|
35
35
|
* bypassing on-chain reads.
|
|
36
36
|
* @param state - Array of market data snapshots.
|
|
37
37
|
**/
|
|
38
|
-
hydrate(
|
|
39
|
-
const configurators = new Set(
|
|
38
|
+
hydrate({ markets, zappers }) {
|
|
39
|
+
const configurators = new Set(markets.map((m) => m.configurator));
|
|
40
40
|
this.#setMarketFilter([...configurators]);
|
|
41
|
-
this.#setMarkets(
|
|
41
|
+
this.#setMarkets(markets);
|
|
42
|
+
this.hydrateZappers(zappers);
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
45
|
* @internal
|
|
@@ -157,7 +158,10 @@ class MarketRegister extends ZapperRegister {
|
|
|
157
158
|
* Serializable snapshot of all loaded markets, suitable for hydration.
|
|
158
159
|
**/
|
|
159
160
|
get state() {
|
|
160
|
-
return
|
|
161
|
+
return {
|
|
162
|
+
markets: this.markets.map((market) => market.state),
|
|
163
|
+
zappers: this.zappersState
|
|
164
|
+
};
|
|
161
165
|
}
|
|
162
166
|
/**
|
|
163
167
|
* Returns a human-readable snapshot of all markets.
|
|
@@ -165,7 +169,8 @@ class MarketRegister extends ZapperRegister {
|
|
|
165
169
|
**/
|
|
166
170
|
stateHuman(raw = true) {
|
|
167
171
|
return {
|
|
168
|
-
markets: this.markets.map((market) => market.stateHuman(raw))
|
|
172
|
+
markets: this.markets.map((market) => market.stateHuman(raw)),
|
|
173
|
+
zappers: this.zappersStateHuman(raw)
|
|
169
174
|
};
|
|
170
175
|
}
|
|
171
176
|
/**
|
|
@@ -55,6 +55,60 @@ class ZapperRegister extends SDKConstruct {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Serializable snapshot of all loaded zappers, suitable for hydration.
|
|
60
|
+
* Returns `undefined` when zappers were never loaded (i.e. `loadZappers` was
|
|
61
|
+
* not called), so the not-loaded state round-trips cleanly.
|
|
62
|
+
**/
|
|
63
|
+
get zappersState() {
|
|
64
|
+
if (!this.#zappers) {
|
|
65
|
+
return void 0;
|
|
66
|
+
}
|
|
67
|
+
return this.#zappers.values().flatMap(
|
|
68
|
+
(zappers) => zappers.map((z) => ({
|
|
69
|
+
pool: z.pool,
|
|
70
|
+
type: z.type,
|
|
71
|
+
baseParams: z.baseParams,
|
|
72
|
+
tokenIn: z.tokenIn,
|
|
73
|
+
tokenOut: z.tokenOut
|
|
74
|
+
}))
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Restores zapper state from a previously serialized snapshot,
|
|
79
|
+
* bypassing on-chain reads.
|
|
80
|
+
* @param state - Array of zapper data snapshots, or `undefined` when zappers
|
|
81
|
+
* were not loaded in the snapshot (leaves the registry in the not-loaded state).
|
|
82
|
+
**/
|
|
83
|
+
hydrateZappers(state) {
|
|
84
|
+
if (!state) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
this.#zappers = new AddressMap(void 0, "zappers");
|
|
88
|
+
for (const z of state) {
|
|
89
|
+
this.#addZapper(z);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Returns a human-readable snapshot of all loaded zappers.
|
|
94
|
+
* Returns `undefined` when zappers were never loaded.
|
|
95
|
+
* @param raw - When `true`, includes raw/unformatted values.
|
|
96
|
+
**/
|
|
97
|
+
zappersStateHuman(_ = true) {
|
|
98
|
+
if (!this.#zappers) {
|
|
99
|
+
return void 0;
|
|
100
|
+
}
|
|
101
|
+
return this.#zappers.values().flatMap(
|
|
102
|
+
(zappers) => zappers.map((z) => ({
|
|
103
|
+
address: this.labelAddress(z.baseParams.addr),
|
|
104
|
+
contractType: z.contractType,
|
|
105
|
+
type: z.type,
|
|
106
|
+
pool: this.labelAddress(z.pool),
|
|
107
|
+
tokenIn: this.sdk.labelAddress(z.tokenIn.addr),
|
|
108
|
+
tokenOut: this.sdk.labelAddress(z.tokenOut.addr)
|
|
109
|
+
}))
|
|
110
|
+
);
|
|
111
|
+
}
|
|
58
112
|
#addZapper(z) {
|
|
59
113
|
const zapper = createZapper(this.sdk, z);
|
|
60
114
|
const existing = this.zappers.get(z.pool);
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import { ierc20ZapperAbi } from "../../../abi/iERC20Zapper.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ZapperContract } from "./ZapperContract.js";
|
|
3
3
|
const abi = ierc20ZapperAbi;
|
|
4
|
-
class IERC20ZapperContract extends
|
|
5
|
-
pool;
|
|
6
|
-
type;
|
|
7
|
-
baseParams;
|
|
8
|
-
tokenIn;
|
|
9
|
-
tokenOut;
|
|
4
|
+
class IERC20ZapperContract extends ZapperContract {
|
|
10
5
|
constructor(sdk, data) {
|
|
11
|
-
super(sdk,
|
|
12
|
-
addr: data.baseParams.addr,
|
|
13
|
-
abi,
|
|
14
|
-
name: `ERC20Zapper(${sdk.labelAddress(data.baseParams.addr)})`,
|
|
15
|
-
version: data.baseParams.version,
|
|
16
|
-
contractType: data.baseParams.contractType
|
|
17
|
-
});
|
|
18
|
-
this.pool = data.pool;
|
|
19
|
-
this.type = data.type;
|
|
20
|
-
this.baseParams = data.baseParams;
|
|
21
|
-
this.tokenIn = data.tokenIn;
|
|
22
|
-
this.tokenOut = data.tokenOut;
|
|
6
|
+
super(sdk, data, abi, "ERC20Zapper");
|
|
23
7
|
}
|
|
24
8
|
/**
|
|
25
9
|
* Deposits ERC20 tokens into the pool via this zapper.
|
|
@@ -49,25 +33,6 @@ class IERC20ZapperContract extends BaseContract {
|
|
|
49
33
|
args: [tokenInAmount, receiver, referralCode, deadline, v, r, s]
|
|
50
34
|
});
|
|
51
35
|
}
|
|
52
|
-
/**
|
|
53
|
-
* Redeems pool shares (diesel tokens) for the underlying asset via this zapper.
|
|
54
|
-
*/
|
|
55
|
-
redeem(tokenInAmount, receiver) {
|
|
56
|
-
return this.createRawTx({
|
|
57
|
-
functionName: "redeem",
|
|
58
|
-
args: [tokenInAmount, receiver]
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Redeems pool shares via this zapper with an EIP-2612 permit signature,
|
|
63
|
-
* skipping a separate approve transaction.
|
|
64
|
-
*/
|
|
65
|
-
redeemWithPermit(tokenInAmount, receiver, deadline, v, r, s) {
|
|
66
|
-
return this.createRawTx({
|
|
67
|
-
functionName: "redeemWithPermit",
|
|
68
|
-
args: [tokenInAmount, receiver, deadline, v, r, s]
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
36
|
}
|
|
72
37
|
export {
|
|
73
38
|
IERC20ZapperContract
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import { iethZapperAbi } from "../../../abi/iETHZapper.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ZapperContract } from "./ZapperContract.js";
|
|
3
3
|
const abi = iethZapperAbi;
|
|
4
|
-
class IETHZapperContract extends
|
|
5
|
-
pool;
|
|
6
|
-
type;
|
|
7
|
-
baseParams;
|
|
8
|
-
tokenIn;
|
|
9
|
-
tokenOut;
|
|
4
|
+
class IETHZapperContract extends ZapperContract {
|
|
10
5
|
constructor(sdk, data) {
|
|
11
|
-
super(sdk,
|
|
12
|
-
addr: data.baseParams.addr,
|
|
13
|
-
abi,
|
|
14
|
-
name: `ETHZapper(${sdk.labelAddress(data.baseParams.addr)})`,
|
|
15
|
-
version: data.baseParams.version,
|
|
16
|
-
contractType: data.baseParams.contractType
|
|
17
|
-
});
|
|
18
|
-
this.pool = data.pool;
|
|
19
|
-
this.type = data.type;
|
|
20
|
-
this.baseParams = data.baseParams;
|
|
21
|
-
this.tokenIn = data.tokenIn;
|
|
22
|
-
this.tokenOut = data.tokenOut;
|
|
6
|
+
super(sdk, data, abi, "ETHZapper");
|
|
23
7
|
}
|
|
24
8
|
/**
|
|
25
9
|
* Deposits native ETH into the pool via this zapper.
|
|
@@ -40,25 +24,6 @@ class IETHZapperContract extends BaseContract {
|
|
|
40
24
|
args: [receiver, referralCode]
|
|
41
25
|
});
|
|
42
26
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Redeems pool shares (diesel tokens) for the underlying asset via this zapper.
|
|
45
|
-
*/
|
|
46
|
-
redeem(tokenInAmount, receiver) {
|
|
47
|
-
return this.createRawTx({
|
|
48
|
-
functionName: "redeem",
|
|
49
|
-
args: [tokenInAmount, receiver]
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Redeems pool shares via this zapper with an EIP-2612 permit signature,
|
|
54
|
-
* skipping a separate approve transaction.
|
|
55
|
-
*/
|
|
56
|
-
redeemWithPermit(tokenInAmount, receiver, deadline, v, r, s) {
|
|
57
|
-
return this.createRawTx({
|
|
58
|
-
functionName: "redeemWithPermit",
|
|
59
|
-
args: [tokenInAmount, receiver, deadline, v, r, s]
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
27
|
}
|
|
63
28
|
export {
|
|
64
29
|
IETHZapperContract
|