@gearbox-protocol/sdk 12.7.2 → 13.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/dist/cjs/{sdk/pools/PoolServiceV310.js → abi/iStateSerializer.js} +14 -8
- package/dist/cjs/sdk/base/TokensMeta.js +100 -31
- package/dist/cjs/sdk/base/index.js +2 -0
- package/dist/cjs/sdk/{constants/phantom-tokens.js → base/token-types.js} +9 -3
- package/dist/cjs/sdk/chain/chains.js +2 -1
- package/dist/cjs/sdk/constants/index.js +0 -2
- package/dist/cjs/sdk/market/MarketSuite.js +3 -0
- package/dist/cjs/sdk/pools/PoolService.js +310 -0
- package/dist/cjs/sdk/pools/index.js +2 -4
- package/dist/esm/abi/iStateSerializer.js +12 -0
- package/dist/esm/sdk/base/TokensMeta.js +108 -33
- package/dist/esm/sdk/base/index.js +1 -0
- package/dist/esm/sdk/{constants/phantom-tokens.js → base/token-types.js} +4 -0
- package/dist/esm/sdk/chain/chains.js +2 -1
- package/dist/esm/sdk/constants/index.js +0 -1
- package/dist/esm/sdk/market/MarketSuite.js +3 -0
- package/dist/esm/sdk/pools/PoolService.js +296 -0
- package/dist/esm/sdk/pools/index.js +1 -2
- package/dist/types/abi/iStateSerializer.d.ts +11 -0
- package/dist/types/sdk/base/TokensMeta.d.ts +9 -18
- package/dist/types/sdk/base/index.d.ts +1 -0
- package/dist/types/sdk/base/token-types.d.ts +25 -0
- package/dist/types/sdk/base/types.d.ts +0 -1
- package/dist/types/sdk/chain/chains.d.ts +1 -1
- package/dist/types/sdk/constants/index.d.ts +0 -1
- package/dist/types/sdk/market/MarketSuite.d.ts +1 -0
- package/dist/types/sdk/pools/PoolService.d.ts +19 -0
- package/dist/types/sdk/pools/extraZappers.d.ts +9 -0
- package/dist/types/sdk/pools/index.d.ts +1 -2
- package/dist/types/sdk/pools/types.d.ts +73 -57
- package/dist/types/sdk/sdk-legacy/payload/pool.d.ts +3 -2
- package/package.json +3 -3
- package/dist/cjs/plugins/zappers/ZappersPlugin.js +0 -143
- package/dist/cjs/plugins/zappers/index.js +0 -26
- package/dist/cjs/plugins/zappers/package.json +0 -1
- package/dist/cjs/plugins/zappers/types.js +0 -16
- package/dist/cjs/sdk/pools/AbstractPoolService.js +0 -137
- package/dist/cjs/sdk/pools/PoolServiceV300.js +0 -30
- package/dist/cjs/sdk/pools/createPoolService.js +0 -39
- package/dist/esm/plugins/zappers/ZappersPlugin.js +0 -125
- package/dist/esm/plugins/zappers/index.js +0 -3
- package/dist/esm/plugins/zappers/package.json +0 -1
- package/dist/esm/plugins/zappers/types.js +0 -0
- package/dist/esm/sdk/pools/AbstractPoolService.js +0 -113
- package/dist/esm/sdk/pools/PoolServiceV300.js +0 -6
- package/dist/esm/sdk/pools/PoolServiceV310.js +0 -6
- package/dist/esm/sdk/pools/createPoolService.js +0 -15
- package/dist/types/plugins/zappers/ZappersPlugin.d.ts +0 -18
- package/dist/types/plugins/zappers/extraZappers.d.ts +0 -6
- package/dist/types/plugins/zappers/index.d.ts +0 -3
- package/dist/types/plugins/zappers/types.d.ts +0 -12
- package/dist/types/sdk/constants/phantom-tokens.d.ts +0 -2
- package/dist/types/sdk/pools/AbstractPoolService.d.ts +0 -9
- package/dist/types/sdk/pools/PoolServiceV300.d.ts +0 -4
- package/dist/types/sdk/pools/PoolServiceV310.d.ts +0 -4
- package/dist/types/sdk/pools/createPoolService.d.ts +0 -8
- /package/dist/cjs/{plugins/zappers → sdk/pools}/extraZappers.js +0 -0
- /package/dist/esm/{plugins/zappers → sdk/pools}/extraZappers.js +0 -0
|
@@ -1,16 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeAbiParameters
|
|
3
|
+
} from "viem";
|
|
4
|
+
import { iStateSerializerAbi } from "../../abi/iStateSerializer.js";
|
|
1
5
|
import { iVersionAbi } from "../../abi/iVersion.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
6
|
+
import {
|
|
7
|
+
bytes32ToString,
|
|
8
|
+
KYC_UNDERLYING_DEFAULT,
|
|
9
|
+
KYC_UNDERLYING_ON_DEMAND
|
|
10
|
+
} from "../index.js";
|
|
11
|
+
import { AddressMap, formatBN } from "../utils/index.js";
|
|
4
12
|
class TokensMeta extends AddressMap {
|
|
5
13
|
#client;
|
|
6
|
-
#
|
|
14
|
+
#tokenDataLoaded = false;
|
|
7
15
|
constructor(client) {
|
|
8
16
|
super(void 0, "tokensMeta");
|
|
9
17
|
this.#client = client;
|
|
10
18
|
}
|
|
11
19
|
reset() {
|
|
12
20
|
this.clear();
|
|
13
|
-
this.#
|
|
21
|
+
this.#tokenDataLoaded = false;
|
|
14
22
|
}
|
|
15
23
|
symbol(token) {
|
|
16
24
|
return this.mustGet(token).symbol;
|
|
@@ -18,28 +26,39 @@ class TokensMeta extends AddressMap {
|
|
|
18
26
|
decimals(token) {
|
|
19
27
|
return this.mustGet(token).decimals;
|
|
20
28
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
*/
|
|
25
|
-
phantomTokenType(token) {
|
|
26
|
-
if (!this.#phantomTokensLoaded?.has(token)) {
|
|
27
|
-
throw new Error("phantom token data not loaded");
|
|
29
|
+
isPhantomToken(t) {
|
|
30
|
+
if (!this.#tokenDataLoaded) {
|
|
31
|
+
throw new Error("extended token data not loaded");
|
|
28
32
|
}
|
|
29
|
-
return
|
|
33
|
+
return "contractType" in t && t.contractType.startsWith("PHANTOM_TOKEN::");
|
|
34
|
+
}
|
|
35
|
+
isKYCUnderlying(t) {
|
|
36
|
+
if (!this.#tokenDataLoaded) {
|
|
37
|
+
throw new Error("extended token data not loaded");
|
|
38
|
+
}
|
|
39
|
+
return "contractType" in t && t.contractType.startsWith("KYC_UNDERLYING::");
|
|
30
40
|
}
|
|
31
41
|
/**
|
|
32
42
|
* Returns a map of all phantom tokens
|
|
33
43
|
* Throws if the phantom token data is not loaded
|
|
34
44
|
*/
|
|
35
45
|
get phantomTokens() {
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
const result = new AddressMap();
|
|
47
|
+
for (const [token, meta] of this.entries()) {
|
|
48
|
+
if (this.isPhantomToken(meta)) {
|
|
49
|
+
result.upsert(token, meta);
|
|
50
|
+
}
|
|
38
51
|
}
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
);
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
get kycUnderlyings() {
|
|
55
|
+
const result = new AddressMap();
|
|
56
|
+
for (const [token, meta] of this.entries()) {
|
|
57
|
+
if (this.isKYCUnderlying(meta)) {
|
|
58
|
+
result.upsert(token, meta);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
43
62
|
}
|
|
44
63
|
formatBN(arg0, arg1, arg2) {
|
|
45
64
|
const token = typeof arg0 === "object" ? arg0.token : arg0;
|
|
@@ -60,30 +79,86 @@ class TokensMeta extends AddressMap {
|
|
|
60
79
|
return meta;
|
|
61
80
|
}
|
|
62
81
|
/**
|
|
63
|
-
* Loads phantom token
|
|
82
|
+
* Loads token information about phantom token and KYC underlying tokens
|
|
64
83
|
*/
|
|
65
|
-
async
|
|
66
|
-
this.#phantomTokensLoaded = new AddressSet();
|
|
84
|
+
async loadTokenData() {
|
|
67
85
|
const tokens = this.keys();
|
|
68
86
|
const resp = await this.#client.multicall({
|
|
69
|
-
contracts: tokens.
|
|
70
|
-
(t) =>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
87
|
+
contracts: tokens.flatMap(
|
|
88
|
+
(t) => [
|
|
89
|
+
{
|
|
90
|
+
address: t,
|
|
91
|
+
abi: iVersionAbi,
|
|
92
|
+
functionName: "contractType"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
address: t,
|
|
96
|
+
abi: iStateSerializerAbi,
|
|
97
|
+
functionName: "serialize"
|
|
98
|
+
}
|
|
99
|
+
]
|
|
75
100
|
),
|
|
76
101
|
allowFailure: true,
|
|
77
102
|
batchSize: 0
|
|
78
103
|
});
|
|
79
|
-
for (let i = 0; i <
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
104
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
105
|
+
this.#overrideTokenMeta(tokens[i], resp[i], resp[i + 1]);
|
|
106
|
+
}
|
|
107
|
+
this.#tokenDataLoaded = true;
|
|
108
|
+
}
|
|
109
|
+
#overrideTokenMeta(token, contractTypeResp, serializeResp) {
|
|
110
|
+
const meta = this.mustGet(token);
|
|
111
|
+
if (contractTypeResp.status === "success") {
|
|
112
|
+
const contractType = bytes32ToString(contractTypeResp.result);
|
|
113
|
+
if (contractType.startsWith("KYC_UNDERLYING::")) {
|
|
114
|
+
if (serializeResp.status === "success") {
|
|
115
|
+
this.#overrideKYCUnderlying(meta, contractType, serializeResp.result);
|
|
116
|
+
} else {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`token ${meta.symbol} (${token}) is ${contractType} but serialize failed: ${serializeResp.error}`
|
|
119
|
+
);
|
|
84
120
|
}
|
|
121
|
+
} else if (contractType.startsWith("PHANTOM_TOKEN::")) {
|
|
122
|
+
this.upsert(token, {
|
|
123
|
+
...meta,
|
|
124
|
+
contractType
|
|
125
|
+
});
|
|
85
126
|
}
|
|
86
|
-
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
#overrideKYCUnderlying(meta, contractType, serialized) {
|
|
130
|
+
if (contractType === KYC_UNDERLYING_DEFAULT) {
|
|
131
|
+
const decoded = decodeAbiParameters(
|
|
132
|
+
[
|
|
133
|
+
{ type: "address", name: "kycFactory" },
|
|
134
|
+
{ type: "address", name: "asset" }
|
|
135
|
+
],
|
|
136
|
+
serialized
|
|
137
|
+
);
|
|
138
|
+
this.upsert(meta.addr, {
|
|
139
|
+
...meta,
|
|
140
|
+
contractType,
|
|
141
|
+
kycFactory: decoded[0],
|
|
142
|
+
asset: decoded[1]
|
|
143
|
+
});
|
|
144
|
+
} else if (contractType === KYC_UNDERLYING_ON_DEMAND) {
|
|
145
|
+
const decoded = decodeAbiParameters(
|
|
146
|
+
[
|
|
147
|
+
{ type: "address", name: "kycFactory" },
|
|
148
|
+
{ type: "address", name: "asset" },
|
|
149
|
+
{ type: "address", name: "pool" },
|
|
150
|
+
{ type: "address", name: "liquidityProvider" }
|
|
151
|
+
],
|
|
152
|
+
serialized
|
|
153
|
+
);
|
|
154
|
+
this.upsert(meta.addr, {
|
|
155
|
+
...meta,
|
|
156
|
+
contractType,
|
|
157
|
+
kycFactory: decoded[0],
|
|
158
|
+
asset: decoded[1],
|
|
159
|
+
pool: decoded[2],
|
|
160
|
+
liquidityProvider: decoded[3]
|
|
161
|
+
});
|
|
87
162
|
}
|
|
88
163
|
}
|
|
89
164
|
}
|
|
@@ -7,6 +7,10 @@ const PHANTOM_TOKEN_CONTRACT_TYPES = [
|
|
|
7
7
|
"PHANTOM_TOKEN::STAKING_REWARDS",
|
|
8
8
|
"PHANTOM_TOKEN::UPSHIFT_WITHDRAW"
|
|
9
9
|
];
|
|
10
|
+
const KYC_UNDERLYING_DEFAULT = "KYC_UNDERLYING::DEFAULT";
|
|
11
|
+
const KYC_UNDERLYING_ON_DEMAND = "KYC_UNDERLYING::ON_DEMAND";
|
|
10
12
|
export {
|
|
13
|
+
KYC_UNDERLYING_DEFAULT,
|
|
14
|
+
KYC_UNDERLYING_ON_DEMAND,
|
|
11
15
|
PHANTOM_TOKEN_CONTRACT_TYPES
|
|
12
16
|
};
|
|
@@ -62,7 +62,8 @@ const chains = {
|
|
|
62
62
|
"0x7a133fbd01736fd076158307c9476cc3877f1af5": "Invariant Group",
|
|
63
63
|
"0x09d8305F49374AEA6A78aF6C996df2913e8f3b19": "Tulipa",
|
|
64
64
|
"0x1b265b97eb169fb6668e3258007c3b0242c7bdbe": "kpk",
|
|
65
|
-
"0x9dddd1b9ce0ac8aa0c80e4ec141600b9bf0101c3": "Edge UltraYield"
|
|
65
|
+
"0x9dddd1b9ce0ac8aa0c80e4ec141600b9bf0101c3": "Edge UltraYield",
|
|
66
|
+
"0x601067eba24bb5b558a184fc082525637e96a42d": "Gami Labs"
|
|
66
67
|
},
|
|
67
68
|
testMarketConfigurators: {
|
|
68
69
|
"0x99df7330bf42d596af2e9d9836d4fc2077c574aa": "M11 Credit"
|
|
@@ -41,6 +41,9 @@ class MarketSuite extends SDKConstruct {
|
|
|
41
41
|
this.priceOracle = getOrCreatePriceOracle(sdk, marketData.priceOracle);
|
|
42
42
|
this.lossPolicy = createLossPolicy(sdk, marketData.lossPolicy);
|
|
43
43
|
}
|
|
44
|
+
get underlying() {
|
|
45
|
+
return this.pool.underlying;
|
|
46
|
+
}
|
|
44
47
|
get dirty() {
|
|
45
48
|
return this.configurator.dirty || this.pool.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
|
|
46
49
|
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { peripheryCompressorAbi } from "../../abi/compressors/peripheryCompressor.js";
|
|
2
|
+
import { ierc20Abi } from "../../abi/iERC20.js";
|
|
3
|
+
import { ierc20ZapperDepositsAbi } from "../../abi/iERC20ZapperDeposits.js";
|
|
4
|
+
import { iethZapperDepositsAbi } from "../../abi/iETHZapperDeposits.js";
|
|
5
|
+
import { iZapperAbi } from "../../abi/iZapper.js";
|
|
6
|
+
import { iPoolV300Abi } from "../../abi/v300.js";
|
|
7
|
+
import {
|
|
8
|
+
KYC_UNDERLYING_DEFAULT,
|
|
9
|
+
KYC_UNDERLYING_ON_DEMAND,
|
|
10
|
+
SDKConstruct
|
|
11
|
+
} from "../base/index.js";
|
|
12
|
+
import {
|
|
13
|
+
AddressMap,
|
|
14
|
+
AddressSet,
|
|
15
|
+
AP_PERIPHERY_COMPRESSOR,
|
|
16
|
+
hexEq,
|
|
17
|
+
VERSION_RANGE_310
|
|
18
|
+
} from "../index.js";
|
|
19
|
+
import { extraZappers } from "./extraZappers.js";
|
|
20
|
+
const NATIVE_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
21
|
+
class PoolService extends SDKConstruct {
|
|
22
|
+
#zappers;
|
|
23
|
+
get zappers() {
|
|
24
|
+
if (!this.#zappers) {
|
|
25
|
+
throw new Error("zappers not loaded, call loadZappers first");
|
|
26
|
+
}
|
|
27
|
+
return this.#zappers;
|
|
28
|
+
}
|
|
29
|
+
async loadZappers(force) {
|
|
30
|
+
if (!force && this.#zappers) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const [pcAddr] = this.sdk.addressProvider.mustGetLatest(
|
|
34
|
+
AP_PERIPHERY_COMPRESSOR,
|
|
35
|
+
VERSION_RANGE_310
|
|
36
|
+
);
|
|
37
|
+
this.logger?.debug(`loading zappers with periphery compressor ${pcAddr}`);
|
|
38
|
+
const markets = this.sdk.marketRegister.markets;
|
|
39
|
+
const resp = await this.client.multicall({
|
|
40
|
+
contracts: markets.map(
|
|
41
|
+
(m) => ({
|
|
42
|
+
abi: peripheryCompressorAbi,
|
|
43
|
+
address: pcAddr,
|
|
44
|
+
functionName: "getZappers",
|
|
45
|
+
args: [m.configurator.address, m.pool.pool.address]
|
|
46
|
+
})
|
|
47
|
+
),
|
|
48
|
+
allowFailure: true,
|
|
49
|
+
batchSize: 0
|
|
50
|
+
});
|
|
51
|
+
this.#zappers = new AddressMap(void 0, "zappers");
|
|
52
|
+
for (let i = 0; i < resp.length; i++) {
|
|
53
|
+
const { status, result, error } = resp[i];
|
|
54
|
+
const marketConfigurator = markets[i].configurator.address;
|
|
55
|
+
const pool = markets[i].pool.pool.address;
|
|
56
|
+
if (status === "success") {
|
|
57
|
+
for (const z of result) {
|
|
58
|
+
this.#addZapper({ ...z, pool });
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
this.sdk.logger?.error(
|
|
62
|
+
`failed to load zapper for market configurator ${this.labelAddress(
|
|
63
|
+
marketConfigurator
|
|
64
|
+
)} and pool ${this.labelAddress(pool)}: ${error}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const z of extraZappers[this.networkType] ?? []) {
|
|
69
|
+
this.#addZapper(z);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
getDepositTokensIn(pool) {
|
|
73
|
+
const underlying = this.#describeUnderlying(pool);
|
|
74
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
75
|
+
switch (underlying.contractType) {
|
|
76
|
+
case KYC_UNDERLYING_DEFAULT:
|
|
77
|
+
return this.depositTokensIn(pool, false);
|
|
78
|
+
case KYC_UNDERLYING_ON_DEMAND:
|
|
79
|
+
return [underlying.asset];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return this.depositTokensIn(pool, true);
|
|
83
|
+
}
|
|
84
|
+
getDepositTokensOut(pool, tokenIn) {
|
|
85
|
+
const underlying = this.#describeUnderlying(pool);
|
|
86
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
87
|
+
switch (underlying.contractType) {
|
|
88
|
+
case KYC_UNDERLYING_DEFAULT:
|
|
89
|
+
return this.depositTokensOut(pool, tokenIn, false);
|
|
90
|
+
case KYC_UNDERLYING_ON_DEMAND:
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return this.depositTokensOut(pool, tokenIn, true);
|
|
95
|
+
}
|
|
96
|
+
getDepositMetadata(pool, tokenIn, tokenOut) {
|
|
97
|
+
const underlying = this.#describeUnderlying(pool);
|
|
98
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
99
|
+
switch (underlying.contractType) {
|
|
100
|
+
case KYC_UNDERLYING_DEFAULT: {
|
|
101
|
+
return this.depositMetadata(pool, tokenIn, tokenOut, false);
|
|
102
|
+
}
|
|
103
|
+
case KYC_UNDERLYING_ON_DEMAND:
|
|
104
|
+
return {
|
|
105
|
+
zapper: void 0,
|
|
106
|
+
approveTarget: underlying.liquidityProvider,
|
|
107
|
+
permissible: false
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return this.depositMetadata(pool, tokenIn, tokenOut, true);
|
|
112
|
+
}
|
|
113
|
+
addLiquidity(props) {
|
|
114
|
+
const { collateral, meta, permit, referralCode, pool, wallet } = props;
|
|
115
|
+
const underlying = this.#describeUnderlying(pool);
|
|
116
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
117
|
+
if (underlying.contractType === KYC_UNDERLYING_ON_DEMAND) {
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const { zapper } = meta;
|
|
122
|
+
if (zapper?.tokenIn.addr === NATIVE_ADDRESS) {
|
|
123
|
+
return {
|
|
124
|
+
target: zapper.baseParams.addr,
|
|
125
|
+
abi: iethZapperDepositsAbi,
|
|
126
|
+
functionName: "depositWithReferral",
|
|
127
|
+
args: [wallet, referralCode],
|
|
128
|
+
value: collateral.balance
|
|
129
|
+
};
|
|
130
|
+
} else if (zapper) {
|
|
131
|
+
return permit ? {
|
|
132
|
+
target: zapper.baseParams.addr,
|
|
133
|
+
abi: ierc20ZapperDepositsAbi,
|
|
134
|
+
functionName: "depositWithReferralAndPermit",
|
|
135
|
+
args: [
|
|
136
|
+
collateral.balance,
|
|
137
|
+
wallet,
|
|
138
|
+
referralCode,
|
|
139
|
+
permit.deadline,
|
|
140
|
+
permit.v,
|
|
141
|
+
permit.r,
|
|
142
|
+
permit.s
|
|
143
|
+
]
|
|
144
|
+
} : {
|
|
145
|
+
target: zapper.baseParams.addr,
|
|
146
|
+
abi: ierc20ZapperDepositsAbi,
|
|
147
|
+
functionName: "depositWithReferral",
|
|
148
|
+
args: [collateral.balance, wallet, referralCode]
|
|
149
|
+
};
|
|
150
|
+
} else {
|
|
151
|
+
return {
|
|
152
|
+
target: pool,
|
|
153
|
+
abi: iPoolV300Abi,
|
|
154
|
+
functionName: "depositWithReferral",
|
|
155
|
+
args: [collateral.balance, wallet, referralCode]
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
removeLiquidity(props) {
|
|
160
|
+
const { pool, amount, account, zapper, permit } = props;
|
|
161
|
+
const underlying = this.#describeUnderlying(pool);
|
|
162
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
163
|
+
if (underlying.contractType === KYC_UNDERLYING_ON_DEMAND) {
|
|
164
|
+
return {
|
|
165
|
+
abi: ierc20Abi,
|
|
166
|
+
functionName: "approve",
|
|
167
|
+
args: [underlying.liquidityProvider, 0n],
|
|
168
|
+
target: underlying.asset
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (zapper) {
|
|
173
|
+
return permit ? {
|
|
174
|
+
target: zapper.zapper,
|
|
175
|
+
abi: iZapperAbi,
|
|
176
|
+
functionName: "redeemWithPermit",
|
|
177
|
+
args: [
|
|
178
|
+
amount,
|
|
179
|
+
account,
|
|
180
|
+
permit.deadline,
|
|
181
|
+
permit.v,
|
|
182
|
+
permit.r,
|
|
183
|
+
permit.s
|
|
184
|
+
]
|
|
185
|
+
} : {
|
|
186
|
+
target: zapper.zapper,
|
|
187
|
+
abi: iZapperAbi,
|
|
188
|
+
functionName: "redeem",
|
|
189
|
+
args: [amount, account]
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
target: pool,
|
|
194
|
+
abi: iPoolV300Abi,
|
|
195
|
+
functionName: "redeem",
|
|
196
|
+
args: [amount, account, account]
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
depositTokensIn(poolAddr, allowDirectDeposit) {
|
|
200
|
+
const { pool } = this.sdk.marketRegister.findByPool(poolAddr);
|
|
201
|
+
const result = new AddressSet();
|
|
202
|
+
if (allowDirectDeposit) {
|
|
203
|
+
result.add(pool.underlying);
|
|
204
|
+
}
|
|
205
|
+
const zappers = this.zappers.get(poolAddr) ?? [];
|
|
206
|
+
for (const z of zappers) {
|
|
207
|
+
if (hexEq(z.tokenOut.addr, poolAddr)) {
|
|
208
|
+
result.add(z.tokenIn.addr);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (result.size === 0) {
|
|
212
|
+
throw new Error(
|
|
213
|
+
`No tokensIn found for pool ${this.labelAddress(poolAddr)}`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
return result.asArray();
|
|
217
|
+
}
|
|
218
|
+
depositTokensOut(poolAddr, tokenIn, allowDirectDeposit) {
|
|
219
|
+
const result = new AddressSet();
|
|
220
|
+
const { pool } = this.sdk.marketRegister.findByPool(poolAddr);
|
|
221
|
+
const zappers = this.zappers.get(poolAddr) ?? [];
|
|
222
|
+
for (const z of zappers) {
|
|
223
|
+
if (hexEq(z.tokenIn.addr, tokenIn)) {
|
|
224
|
+
result.add(z.tokenOut.addr);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (allowDirectDeposit && hexEq(tokenIn, pool.underlying)) {
|
|
228
|
+
result.add(poolAddr);
|
|
229
|
+
}
|
|
230
|
+
if (result.size === 0) {
|
|
231
|
+
throw new Error(
|
|
232
|
+
`No tokensOut found for tokenIn ${this.labelAddress(tokenIn)} on pool ${this.labelAddress(poolAddr)}`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
return result.asArray();
|
|
236
|
+
}
|
|
237
|
+
depositMetadata(poolAddr, tokenIn, tokenOut, allowDirectDeposit) {
|
|
238
|
+
if (!tokenOut) {
|
|
239
|
+
throw new Error("tokenOut is required for classic pool deposit");
|
|
240
|
+
}
|
|
241
|
+
const { pool } = this.sdk.marketRegister.findByPool(poolAddr);
|
|
242
|
+
const zapper = this.getZapper(poolAddr, tokenIn, tokenOut);
|
|
243
|
+
if (!zapper && !allowDirectDeposit) {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`No zapper found for tokenIn ${this.labelAddress(tokenIn)} and tokenOut ${this.labelAddress(tokenOut)} on pool ${this.labelAddress(poolAddr)}`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
zapper,
|
|
250
|
+
// zapper or pool itself
|
|
251
|
+
approveTarget: zapper?.baseParams.addr ?? pool.pool.address,
|
|
252
|
+
// TODO: instead of permissible, return permitType зависимости от tokenIn
|
|
253
|
+
// "none" | "eip2612" | "dai_like";
|
|
254
|
+
permissible: !!zapper && tokenIn !== NATIVE_ADDRESS
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
getZapper(pool, tokenIn, tokenOut) {
|
|
258
|
+
return this.zappers.get(pool)?.find(
|
|
259
|
+
(z) => hexEq(z.tokenIn.addr, tokenIn) && hexEq(z.tokenOut.addr, tokenOut)
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
mustGetZapper(poolAddr, tokenIn, tokenOut) {
|
|
263
|
+
const result = this.getZapper(poolAddr, tokenIn, tokenOut);
|
|
264
|
+
if (!result) {
|
|
265
|
+
throw new Error(
|
|
266
|
+
`No zapper found for tokenIn ${this.labelAddress(tokenIn)} and tokenOut ${this.labelAddress(tokenOut)} on pool ${this.labelAddress(poolAddr)}`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
#addZapper(z) {
|
|
272
|
+
const existing = this.zappers.get(z.pool);
|
|
273
|
+
if (existing) {
|
|
274
|
+
const hasZapper = existing.some(
|
|
275
|
+
(zz) => hexEq(zz.baseParams.addr, z.baseParams.addr)
|
|
276
|
+
);
|
|
277
|
+
if (!hasZapper) {
|
|
278
|
+
existing.push(z);
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
this.zappers.upsert(z.pool, [z]);
|
|
282
|
+
}
|
|
283
|
+
const zappersTokens = [z.tokenIn, z.tokenOut];
|
|
284
|
+
for (const t of zappersTokens) {
|
|
285
|
+
this.sdk.tokensMeta.upsert(t.addr, t);
|
|
286
|
+
this.sdk.setAddressLabel(t.addr, t.symbol);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
#describeUnderlying(pool) {
|
|
290
|
+
const market = this.sdk.marketRegister.findByPool(pool);
|
|
291
|
+
return this.sdk.tokensMeta.mustGet(market.underlying);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
export {
|
|
295
|
+
PoolService
|
|
296
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const iStateSerializerAbi: readonly [{
|
|
2
|
+
readonly type: "function";
|
|
3
|
+
readonly inputs: readonly [];
|
|
4
|
+
readonly name: "serialize";
|
|
5
|
+
readonly outputs: readonly [{
|
|
6
|
+
readonly name: "serializedData";
|
|
7
|
+
readonly internalType: "bytes";
|
|
8
|
+
readonly type: "bytes";
|
|
9
|
+
}];
|
|
10
|
+
readonly stateMutability: "view";
|
|
11
|
+
}];
|
|
@@ -1,40 +1,31 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { type PhantomTokenContractType } from "../index.js";
|
|
1
|
+
import { type Address, type Chain, type PublicClient, type Transport } from "viem";
|
|
3
2
|
import type { Asset } from "../router/index.js";
|
|
4
3
|
import { AddressMap } from "../utils/index.js";
|
|
5
|
-
import type { TokenMetaData } from "./types.js";
|
|
4
|
+
import type { KYCTokenMeta, PhantomTokenMeta, TokenMetaData } from "./token-types.js";
|
|
6
5
|
export interface FormatBNOptions {
|
|
7
6
|
precision?: number;
|
|
8
7
|
symbol?: boolean;
|
|
9
8
|
}
|
|
10
|
-
export
|
|
11
|
-
/**
|
|
12
|
-
* Undefined if token is not a phantom token
|
|
13
|
-
*/
|
|
14
|
-
phantomTokenType?: PhantomTokenContractType;
|
|
15
|
-
}
|
|
16
|
-
export declare class TokensMeta extends AddressMap<TokenMetaDataExtended> {
|
|
9
|
+
export declare class TokensMeta extends AddressMap<TokenMetaData> {
|
|
17
10
|
#private;
|
|
18
11
|
constructor(client: PublicClient<Transport, Chain>);
|
|
19
12
|
reset(): void;
|
|
20
13
|
symbol(token: Address): string;
|
|
21
14
|
decimals(token: Address): number;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* Throws if the phantom token data is not loaded
|
|
25
|
-
*/
|
|
26
|
-
phantomTokenType(token: Address): PhantomTokenContractType | undefined;
|
|
15
|
+
isPhantomToken(t: TokenMetaData): t is PhantomTokenMeta;
|
|
16
|
+
isKYCUnderlying(t: TokenMetaData): t is KYCTokenMeta;
|
|
27
17
|
/**
|
|
28
18
|
* Returns a map of all phantom tokens
|
|
29
19
|
* Throws if the phantom token data is not loaded
|
|
30
20
|
*/
|
|
31
|
-
get phantomTokens(): AddressMap<
|
|
21
|
+
get phantomTokens(): AddressMap<PhantomTokenMeta>;
|
|
22
|
+
get kycUnderlyings(): AddressMap<KYCTokenMeta>;
|
|
32
23
|
formatBN(asset: Asset, options?: FormatBNOptions): string;
|
|
33
24
|
formatBN(token: Address, amount: number | bigint | string | undefined, options?: FormatBNOptions): string;
|
|
34
25
|
findBySymbol(symbol: string): TokenMetaData | undefined;
|
|
35
26
|
mustFindBySymbol(symbol: string): TokenMetaData;
|
|
36
27
|
/**
|
|
37
|
-
* Loads phantom token
|
|
28
|
+
* Loads token information about phantom token and KYC underlying tokens
|
|
38
29
|
*/
|
|
39
|
-
|
|
30
|
+
loadTokenData(): Promise<void>;
|
|
40
31
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Address } from "viem";
|
|
2
|
+
import type { MarketData, Unarray } from "./types.js";
|
|
3
|
+
export type SimpleTokenMeta = Unarray<MarketData["tokens"]>;
|
|
4
|
+
export declare const PHANTOM_TOKEN_CONTRACT_TYPES: readonly ["PHANTOM_TOKEN::CONVEX", "PHANTOM_TOKEN::INFINIFI_UNWIND", "PHANTOM_TOKEN::INFRARED", "PHANTOM_TOKEN::MELLOW_WITHDRAWAL", "PHANTOM_TOKEN::MIDAS_REDEMPTION", "PHANTOM_TOKEN::STAKING_REWARDS", "PHANTOM_TOKEN::UPSHIFT_WITHDRAW"];
|
|
5
|
+
export declare const KYC_UNDERLYING_DEFAULT = "KYC_UNDERLYING::DEFAULT";
|
|
6
|
+
export declare const KYC_UNDERLYING_ON_DEMAND = "KYC_UNDERLYING::ON_DEMAND";
|
|
7
|
+
export type KYCUnderlyingContractType = typeof KYC_UNDERLYING_DEFAULT | typeof KYC_UNDERLYING_ON_DEMAND;
|
|
8
|
+
export type PhantomTokenContractType = (typeof PHANTOM_TOKEN_CONTRACT_TYPES)[number];
|
|
9
|
+
export type PhantomTokenMeta = SimpleTokenMeta & {
|
|
10
|
+
contractType: PhantomTokenContractType;
|
|
11
|
+
};
|
|
12
|
+
export type KYCDefaultTokenMeta = SimpleTokenMeta & {
|
|
13
|
+
contractType: typeof KYC_UNDERLYING_DEFAULT;
|
|
14
|
+
kycFactory: Address;
|
|
15
|
+
asset: Address;
|
|
16
|
+
};
|
|
17
|
+
export type KYCOnDemandTokenMeta = SimpleTokenMeta & {
|
|
18
|
+
contractType: typeof KYC_UNDERLYING_ON_DEMAND;
|
|
19
|
+
kycFactory: Address;
|
|
20
|
+
asset: Address;
|
|
21
|
+
pool: Address;
|
|
22
|
+
liquidityProvider: Address;
|
|
23
|
+
};
|
|
24
|
+
export type KYCTokenMeta = KYCDefaultTokenMeta | KYCOnDemandTokenMeta;
|
|
25
|
+
export type TokenMetaData = SimpleTokenMeta | PhantomTokenMeta | KYCTokenMeta;
|
|
@@ -26,7 +26,6 @@ export type CreditManagerState = CreditSuiteState["creditManager"];
|
|
|
26
26
|
export type CreditFacadeState = CreditSuiteState["creditFacade"];
|
|
27
27
|
export type CreditConfiguratorState = CreditSuiteState["creditConfigurator"];
|
|
28
28
|
export type AdapterData = Unarray<CreditSuiteState["adapters"]>;
|
|
29
|
-
export type TokenMetaData = Unarray<MarketData["tokens"]>;
|
|
30
29
|
export type PoolState = MarketData["pool"];
|
|
31
30
|
export type QuotaKeeperState = MarketData["quotaKeeper"];
|
|
32
31
|
export type QuotaState = Unarray<QuotaKeeperState["quotas"]>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Address, Chain } from "viem";
|
|
2
2
|
import { z } from "zod/v4";
|
|
3
|
-
export type Curator = "Chaos Labs" | "K3" | "cp0x" | "Re7" | "Invariant Group" | "Tulipa" | "M11 Credit" | "kpk" | "Hyperithm" | "Edge UltraYield" | "TelosC";
|
|
3
|
+
export type Curator = "Chaos Labs" | "K3" | "cp0x" | "Re7" | "Invariant Group" | "Tulipa" | "M11 Credit" | "kpk" | "Hyperithm" | "Edge UltraYield" | "TelosC" | "Gami Labs";
|
|
4
4
|
export interface GearboxChain extends Chain {
|
|
5
5
|
network: NetworkType;
|
|
6
6
|
defaultMarketConfigurators: Record<Address, Curator>;
|
|
@@ -21,6 +21,7 @@ export declare class MarketSuite extends SDKConstruct {
|
|
|
21
21
|
*/
|
|
22
22
|
readonly state: MarketData;
|
|
23
23
|
constructor(sdk: GearboxSDK, marketData: MarketData);
|
|
24
|
+
get underlying(): Address;
|
|
24
25
|
get dirty(): boolean;
|
|
25
26
|
get watchAddresses(): Set<Address>;
|
|
26
27
|
stateHuman(raw?: boolean): MarketStateHuman;
|