@strkfarm/sdk 1.0.16 → 1.0.18
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/cli.js +18 -5
- package/dist/cli.mjs +18 -11
- package/dist/index.browser.global.js +122 -2349
- package/dist/index.browser.mjs +2592 -0
- package/dist/index.d.ts +91 -42
- package/dist/index.js +129 -20
- package/dist/index.mjs +126 -26
- package/package.json +15 -8
- package/src/global.ts +2 -0
- package/src/interfaces/common.ts +41 -2
- package/src/modules/index.ts +2 -1
- package/src/modules/pricer-from-api.ts +61 -0
- package/src/modules/pricer.ts +7 -19
- package/src/modules/pricerBase.ts +15 -0
- package/src/modules/zkLend.ts +1 -0
- package/src/node/pricer-redis.ts +1 -0
- package/src/strategies/vesu-rebalance.ts +43 -4
|
@@ -0,0 +1,2592 @@
|
|
|
1
|
+
// src/modules/pricer.ts
|
|
2
|
+
import axios2 from "axios";
|
|
3
|
+
|
|
4
|
+
// src/global.ts
|
|
5
|
+
import axios from "axios";
|
|
6
|
+
var logger = {
|
|
7
|
+
...console,
|
|
8
|
+
verbose(message) {
|
|
9
|
+
console.log(`[VERBOSE] ${message}`);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var FatalError = class extends Error {
|
|
13
|
+
constructor(message, err) {
|
|
14
|
+
super(message);
|
|
15
|
+
logger.error(message);
|
|
16
|
+
if (err)
|
|
17
|
+
logger.error(err.message);
|
|
18
|
+
this.name = "FatalError";
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var tokens = [{
|
|
22
|
+
name: "Starknet",
|
|
23
|
+
symbol: "STRK",
|
|
24
|
+
logo: "https://assets.coingecko.com/coins/images/26433/small/starknet.png",
|
|
25
|
+
address: "0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
|
|
26
|
+
decimals: 18,
|
|
27
|
+
coingeckId: "starknet"
|
|
28
|
+
}];
|
|
29
|
+
var Global = class {
|
|
30
|
+
static fatalError(message, err) {
|
|
31
|
+
logger.error(message);
|
|
32
|
+
console.error(message, err);
|
|
33
|
+
if (err)
|
|
34
|
+
console.error(err);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
static httpError(url, err, message) {
|
|
38
|
+
logger.error(`${url}: ${message}`);
|
|
39
|
+
console.error(err);
|
|
40
|
+
}
|
|
41
|
+
static getDefaultTokens() {
|
|
42
|
+
return tokens;
|
|
43
|
+
}
|
|
44
|
+
static async getTokens() {
|
|
45
|
+
if (tokens.length) return tokens;
|
|
46
|
+
const data = await axios.get("https://starknet.api.avnu.fi/v1/starknet/tokens");
|
|
47
|
+
const tokensData = data.data.content;
|
|
48
|
+
tokensData.forEach((token) => {
|
|
49
|
+
if (!token.tags.includes("AVNU") || !token.tags.includes("Verified")) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
tokens.push({
|
|
53
|
+
name: token.name,
|
|
54
|
+
symbol: token.symbol,
|
|
55
|
+
address: token.address,
|
|
56
|
+
decimals: token.decimals,
|
|
57
|
+
logo: token.logoUri,
|
|
58
|
+
coingeckId: token.extensions.coingeckoId
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
console.log(tokens);
|
|
62
|
+
return tokens;
|
|
63
|
+
}
|
|
64
|
+
static assert(condition, message) {
|
|
65
|
+
if (!condition) {
|
|
66
|
+
throw new FatalError(message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/dataTypes/bignumber.ts
|
|
72
|
+
import BigNumber from "bignumber.js";
|
|
73
|
+
var Web3Number = class _Web3Number extends BigNumber {
|
|
74
|
+
constructor(value, decimals) {
|
|
75
|
+
super(value);
|
|
76
|
+
this.decimals = decimals;
|
|
77
|
+
}
|
|
78
|
+
static fromWei(weiNumber, decimals) {
|
|
79
|
+
const bn = new _Web3Number(weiNumber, decimals).dividedBy(10 ** decimals);
|
|
80
|
+
return new _Web3Number(bn.toString(), decimals);
|
|
81
|
+
}
|
|
82
|
+
toWei() {
|
|
83
|
+
return this.mul(10 ** this.decimals).toFixed(0);
|
|
84
|
+
}
|
|
85
|
+
multipliedBy(value) {
|
|
86
|
+
let _value = Number(value).toFixed(6);
|
|
87
|
+
return new _Web3Number(this.mul(_value).toString(), this.decimals);
|
|
88
|
+
}
|
|
89
|
+
dividedBy(value) {
|
|
90
|
+
let _value = Number(value).toFixed(6);
|
|
91
|
+
return new _Web3Number(this.div(_value).toString(), this.decimals);
|
|
92
|
+
}
|
|
93
|
+
plus(value) {
|
|
94
|
+
return new _Web3Number(this.add(value).toString(), this.decimals);
|
|
95
|
+
}
|
|
96
|
+
minus(n, base) {
|
|
97
|
+
return new _Web3Number(super.minus(n, base).toString(), this.decimals);
|
|
98
|
+
}
|
|
99
|
+
toString(base) {
|
|
100
|
+
return super.toString(base);
|
|
101
|
+
}
|
|
102
|
+
// [customInspectSymbol](depth: any, inspectOptions: any, inspect: any) {
|
|
103
|
+
// return this.toString();
|
|
104
|
+
// }
|
|
105
|
+
};
|
|
106
|
+
BigNumber.config({ DECIMAL_PLACES: 18 });
|
|
107
|
+
Web3Number.config({ DECIMAL_PLACES: 18 });
|
|
108
|
+
|
|
109
|
+
// src/dataTypes/address.ts
|
|
110
|
+
import { num } from "starknet";
|
|
111
|
+
var ContractAddr = class _ContractAddr {
|
|
112
|
+
constructor(address) {
|
|
113
|
+
this.address = _ContractAddr.standardise(address);
|
|
114
|
+
}
|
|
115
|
+
static from(address) {
|
|
116
|
+
return new _ContractAddr(address);
|
|
117
|
+
}
|
|
118
|
+
eq(other) {
|
|
119
|
+
return this.address === other.address;
|
|
120
|
+
}
|
|
121
|
+
eqString(other) {
|
|
122
|
+
return this.address === _ContractAddr.standardise(other);
|
|
123
|
+
}
|
|
124
|
+
static standardise(address) {
|
|
125
|
+
let _a = address;
|
|
126
|
+
if (!address) {
|
|
127
|
+
_a = "0";
|
|
128
|
+
}
|
|
129
|
+
const a = num.getHexString(num.getDecimalString(_a.toString()));
|
|
130
|
+
return a;
|
|
131
|
+
}
|
|
132
|
+
static eqString(a, b) {
|
|
133
|
+
return _ContractAddr.standardise(a) === _ContractAddr.standardise(b);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/modules/pricerBase.ts
|
|
138
|
+
var PricerBase = class {
|
|
139
|
+
constructor(config, tokens2) {
|
|
140
|
+
this.config = config;
|
|
141
|
+
this.tokens = tokens2;
|
|
142
|
+
}
|
|
143
|
+
async getPrice(tokenSymbol) {
|
|
144
|
+
throw new Error("Method not implemented");
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/modules/pricer.ts
|
|
149
|
+
var Pricer = class extends PricerBase {
|
|
150
|
+
// e.g. ETH/USDC
|
|
151
|
+
constructor(config, tokens2) {
|
|
152
|
+
super(config, tokens2);
|
|
153
|
+
this.prices = {};
|
|
154
|
+
// code populates this map during runtime to determine which method to use for a given token
|
|
155
|
+
// The method set will be the first one to try after first attempt
|
|
156
|
+
this.methodToUse = {};
|
|
157
|
+
/**
|
|
158
|
+
* TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
|
|
159
|
+
*/
|
|
160
|
+
this.PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
|
|
161
|
+
this.EKUBO_API = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8";
|
|
162
|
+
}
|
|
163
|
+
isReady() {
|
|
164
|
+
const allPricesExist = Object.keys(this.prices).length === this.tokens.length;
|
|
165
|
+
if (!allPricesExist) return false;
|
|
166
|
+
let atleastOneStale = false;
|
|
167
|
+
for (let token of this.tokens) {
|
|
168
|
+
const priceInfo = this.prices[token.symbol];
|
|
169
|
+
const isStale = this.isStale(priceInfo.timestamp, token.symbol);
|
|
170
|
+
if (isStale) {
|
|
171
|
+
atleastOneStale = true;
|
|
172
|
+
logger.warn(`Atleast one stale: ${token.symbol}: ${JSON.stringify(this.prices[token.symbol])}`);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return allPricesExist && !atleastOneStale;
|
|
177
|
+
}
|
|
178
|
+
waitTillReady() {
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const interval = setInterval(() => {
|
|
181
|
+
logger.verbose(`Waiting for pricer to initialise`);
|
|
182
|
+
if (this.isReady()) {
|
|
183
|
+
logger.verbose(`Pricer initialised`);
|
|
184
|
+
clearInterval(interval);
|
|
185
|
+
resolve();
|
|
186
|
+
}
|
|
187
|
+
}, 1e3);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
start() {
|
|
191
|
+
this._loadPrices();
|
|
192
|
+
setInterval(() => {
|
|
193
|
+
this._loadPrices();
|
|
194
|
+
}, 3e4);
|
|
195
|
+
}
|
|
196
|
+
isStale(timestamp, tokenName) {
|
|
197
|
+
const STALE_TIME = 6e4;
|
|
198
|
+
return (/* @__PURE__ */ new Date()).getTime() - timestamp.getTime() > STALE_TIME;
|
|
199
|
+
}
|
|
200
|
+
assertNotStale(timestamp, tokenName) {
|
|
201
|
+
Global.assert(!this.isStale(timestamp, tokenName), `Price of ${tokenName} is stale`);
|
|
202
|
+
}
|
|
203
|
+
async getPrice(tokenSymbol) {
|
|
204
|
+
Global.assert(this.prices[tokenSymbol], `Price of ${tokenSymbol} not found`);
|
|
205
|
+
this.assertNotStale(this.prices[tokenSymbol].timestamp, tokenSymbol);
|
|
206
|
+
return this.prices[tokenSymbol];
|
|
207
|
+
}
|
|
208
|
+
_loadPrices(onUpdate = () => {
|
|
209
|
+
}) {
|
|
210
|
+
this.tokens.forEach(async (token) => {
|
|
211
|
+
const MAX_RETRIES = 10;
|
|
212
|
+
let retry = 0;
|
|
213
|
+
while (retry < MAX_RETRIES) {
|
|
214
|
+
try {
|
|
215
|
+
if (token.symbol === "USDT") {
|
|
216
|
+
this.prices[token.symbol] = {
|
|
217
|
+
price: 1,
|
|
218
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
219
|
+
};
|
|
220
|
+
onUpdate(token.symbol);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const price = await this._getPrice(token);
|
|
224
|
+
this.prices[token.symbol] = {
|
|
225
|
+
price,
|
|
226
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
227
|
+
};
|
|
228
|
+
onUpdate(token.symbol);
|
|
229
|
+
logger.verbose(`Fetched price of ${token.name} as ${price}`);
|
|
230
|
+
break;
|
|
231
|
+
} catch (error) {
|
|
232
|
+
if (retry < MAX_RETRIES) {
|
|
233
|
+
logger.warn(`Error fetching data from ${token.name}, retry: ${retry}`);
|
|
234
|
+
logger.warn(error);
|
|
235
|
+
retry++;
|
|
236
|
+
await new Promise((resolve) => setTimeout(resolve, retry * 2e3));
|
|
237
|
+
} else {
|
|
238
|
+
throw new FatalError(`Error fetching data from ${token.name}`, error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
if (this.isReady() && this.config.heartbeatUrl) {
|
|
244
|
+
console.log(`sending beat`);
|
|
245
|
+
axios2.get(this.config.heartbeatUrl).catch((err) => {
|
|
246
|
+
console.error("Pricer: Heartbeat err", err);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async _getPrice(token, defaultMethod = "all") {
|
|
251
|
+
const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
|
|
252
|
+
logger.info(`Fetching price of ${token.symbol} using ${methodToUse}`);
|
|
253
|
+
switch (methodToUse) {
|
|
254
|
+
case "Coinbase":
|
|
255
|
+
try {
|
|
256
|
+
const result = await this._getPriceCoinbase(token);
|
|
257
|
+
this.methodToUse[token.symbol] = "Coinbase";
|
|
258
|
+
return result;
|
|
259
|
+
} catch (error) {
|
|
260
|
+
console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
|
|
261
|
+
}
|
|
262
|
+
case "Coinmarketcap":
|
|
263
|
+
try {
|
|
264
|
+
const result = await this._getPriceCoinMarketCap(token);
|
|
265
|
+
this.methodToUse[token.symbol] = "Coinmarketcap";
|
|
266
|
+
return result;
|
|
267
|
+
} catch (error) {
|
|
268
|
+
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
|
|
269
|
+
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
|
|
270
|
+
}
|
|
271
|
+
case "Ekubo":
|
|
272
|
+
try {
|
|
273
|
+
const result = await this._getPriceEkubo(token);
|
|
274
|
+
this.methodToUse[token.symbol] = "Ekubo";
|
|
275
|
+
return result;
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
|
|
278
|
+
console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (defaultMethod == "all") {
|
|
282
|
+
return await this._getPrice(token, "Coinbase");
|
|
283
|
+
}
|
|
284
|
+
throw new FatalError(`Price not found for ${token.symbol}`);
|
|
285
|
+
}
|
|
286
|
+
async _getPriceCoinbase(token) {
|
|
287
|
+
const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
|
|
288
|
+
const result = await axios2.get(url);
|
|
289
|
+
const data = result.data;
|
|
290
|
+
return Number(data.data.amount);
|
|
291
|
+
}
|
|
292
|
+
async _getPriceCoinMarketCap(token) {
|
|
293
|
+
throw new Error("Not implemented");
|
|
294
|
+
}
|
|
295
|
+
async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
|
|
296
|
+
const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address).replace("{{AMOUNT}}", amountIn.toWei());
|
|
297
|
+
const result = await axios2.get(url);
|
|
298
|
+
const data = result.data;
|
|
299
|
+
const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6));
|
|
300
|
+
logger.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
|
|
301
|
+
if (outputUSDC === 0 && retry < 3) {
|
|
302
|
+
const amountIn2 = new Web3Number(100, token.decimals);
|
|
303
|
+
return await this._getPriceEkubo(token, amountIn2, retry + 1);
|
|
304
|
+
}
|
|
305
|
+
const usdcPrice = 1;
|
|
306
|
+
logger.verbose(`USDC Price: ${usdcPrice}`);
|
|
307
|
+
return outputUSDC * usdcPrice;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
// src/modules/pragma.ts
|
|
312
|
+
import { Contract } from "starknet";
|
|
313
|
+
|
|
314
|
+
// src/data/pragma.abi.json
|
|
315
|
+
var pragma_abi_default = [
|
|
316
|
+
{
|
|
317
|
+
data: [
|
|
318
|
+
{
|
|
319
|
+
name: "previousOwner",
|
|
320
|
+
type: "felt"
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: "newOwner",
|
|
324
|
+
type: "felt"
|
|
325
|
+
}
|
|
326
|
+
],
|
|
327
|
+
keys: [],
|
|
328
|
+
name: "OwnershipTransferred",
|
|
329
|
+
type: "event"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
data: [
|
|
333
|
+
{
|
|
334
|
+
name: "token",
|
|
335
|
+
type: "felt"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: "source",
|
|
339
|
+
type: "felt"
|
|
340
|
+
}
|
|
341
|
+
],
|
|
342
|
+
keys: [],
|
|
343
|
+
name: "TokenSourceChanged",
|
|
344
|
+
type: "event"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: "constructor",
|
|
348
|
+
type: "constructor",
|
|
349
|
+
inputs: [
|
|
350
|
+
{
|
|
351
|
+
name: "owner",
|
|
352
|
+
type: "felt"
|
|
353
|
+
}
|
|
354
|
+
],
|
|
355
|
+
outputs: []
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: "get_price",
|
|
359
|
+
type: "function",
|
|
360
|
+
inputs: [
|
|
361
|
+
{
|
|
362
|
+
name: "token",
|
|
363
|
+
type: "felt"
|
|
364
|
+
}
|
|
365
|
+
],
|
|
366
|
+
outputs: [
|
|
367
|
+
{
|
|
368
|
+
name: "price",
|
|
369
|
+
type: "felt"
|
|
370
|
+
}
|
|
371
|
+
],
|
|
372
|
+
stateMutability: "view"
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: "get_price_with_time",
|
|
376
|
+
type: "function",
|
|
377
|
+
inputs: [
|
|
378
|
+
{
|
|
379
|
+
name: "token",
|
|
380
|
+
type: "felt"
|
|
381
|
+
}
|
|
382
|
+
],
|
|
383
|
+
outputs: [
|
|
384
|
+
{
|
|
385
|
+
name: "price",
|
|
386
|
+
type: "felt"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
name: "update_time",
|
|
390
|
+
type: "felt"
|
|
391
|
+
}
|
|
392
|
+
],
|
|
393
|
+
stateMutability: "view"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: "set_token_source",
|
|
397
|
+
type: "function",
|
|
398
|
+
inputs: [
|
|
399
|
+
{
|
|
400
|
+
name: "token",
|
|
401
|
+
type: "felt"
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
name: "source",
|
|
405
|
+
type: "felt"
|
|
406
|
+
}
|
|
407
|
+
],
|
|
408
|
+
outputs: []
|
|
409
|
+
}
|
|
410
|
+
];
|
|
411
|
+
|
|
412
|
+
// src/modules/pragma.ts
|
|
413
|
+
var Pragma = class {
|
|
414
|
+
constructor(provider) {
|
|
415
|
+
this.contractAddr = "0x023fb3afbff2c0e3399f896dcf7400acf1a161941cfb386e34a123f228c62832";
|
|
416
|
+
this.contract = new Contract(pragma_abi_default, this.contractAddr, provider);
|
|
417
|
+
}
|
|
418
|
+
async getPrice(tokenAddr) {
|
|
419
|
+
if (!tokenAddr) {
|
|
420
|
+
throw new Error(`Pragma:getPrice - no token`);
|
|
421
|
+
}
|
|
422
|
+
const result = await this.contract.call("get_price", [tokenAddr]);
|
|
423
|
+
const price = Number(result.price) / 10 ** 8;
|
|
424
|
+
logger.verbose(`Pragma:${tokenAddr}: ${price}`);
|
|
425
|
+
return price;
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
// src/modules/zkLend.ts
|
|
430
|
+
import axios3 from "axios";
|
|
431
|
+
|
|
432
|
+
// src/interfaces/lending.ts
|
|
433
|
+
var MarginType = /* @__PURE__ */ ((MarginType2) => {
|
|
434
|
+
MarginType2["SHARED"] = "shared";
|
|
435
|
+
MarginType2["NONE"] = "none";
|
|
436
|
+
return MarginType2;
|
|
437
|
+
})(MarginType || {});
|
|
438
|
+
var ILending = class {
|
|
439
|
+
constructor(config, metadata) {
|
|
440
|
+
this.tokens = [];
|
|
441
|
+
this.initialised = false;
|
|
442
|
+
this.metadata = metadata;
|
|
443
|
+
this.config = config;
|
|
444
|
+
this.init();
|
|
445
|
+
}
|
|
446
|
+
/** Wait for initialisation */
|
|
447
|
+
waitForInitilisation() {
|
|
448
|
+
return new Promise((resolve, reject) => {
|
|
449
|
+
const interval = setInterval(() => {
|
|
450
|
+
logger.verbose(`Waiting for ${this.metadata.name} to initialise`);
|
|
451
|
+
if (this.initialised) {
|
|
452
|
+
logger.verbose(`${this.metadata.name} initialised`);
|
|
453
|
+
clearInterval(interval);
|
|
454
|
+
resolve();
|
|
455
|
+
}
|
|
456
|
+
}, 1e3);
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
// src/modules/zkLend.ts
|
|
462
|
+
var _ZkLend = class _ZkLend extends ILending {
|
|
463
|
+
constructor(config, pricer) {
|
|
464
|
+
super(config, {
|
|
465
|
+
name: "zkLend",
|
|
466
|
+
logo: "https://app.zklend.com/favicon.ico"
|
|
467
|
+
});
|
|
468
|
+
this.POSITION_URL = "https://app.zklend.com/api/users/{{USER_ADDR}}/all";
|
|
469
|
+
this.pricer = pricer;
|
|
470
|
+
}
|
|
471
|
+
async init() {
|
|
472
|
+
try {
|
|
473
|
+
logger.verbose(`Initialising ${this.metadata.name}`);
|
|
474
|
+
const result = await axios3.get(_ZkLend.POOLS_URL);
|
|
475
|
+
const data = result.data;
|
|
476
|
+
const savedTokens = await Global.getTokens();
|
|
477
|
+
data.forEach((pool) => {
|
|
478
|
+
let collareralFactor = new Web3Number(0, 0);
|
|
479
|
+
if (pool.collateral_factor) {
|
|
480
|
+
collareralFactor = Web3Number.fromWei(pool.collateral_factor.value, pool.collateral_factor.decimals);
|
|
481
|
+
}
|
|
482
|
+
const savedTokenInfo = savedTokens.find((t) => t.symbol == pool.token.symbol);
|
|
483
|
+
const token = {
|
|
484
|
+
name: pool.token.name,
|
|
485
|
+
symbol: pool.token.symbol,
|
|
486
|
+
address: savedTokenInfo?.address || "",
|
|
487
|
+
logo: "",
|
|
488
|
+
decimals: pool.token.decimals,
|
|
489
|
+
borrowFactor: Web3Number.fromWei(pool.borrow_factor.value, pool.borrow_factor.decimals),
|
|
490
|
+
collareralFactor
|
|
491
|
+
};
|
|
492
|
+
this.tokens.push(token);
|
|
493
|
+
});
|
|
494
|
+
logger.info(`Initialised ${this.metadata.name} with ${this.tokens.length} tokens`);
|
|
495
|
+
this.initialised = true;
|
|
496
|
+
} catch (error) {
|
|
497
|
+
return Global.httpError(_ZkLend.POOLS_URL, error);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* @description Get the health factor of the user for given lending and debt tokens
|
|
502
|
+
* @param lending_tokens
|
|
503
|
+
* @param debt_tokens
|
|
504
|
+
* @param user
|
|
505
|
+
* @returns hf (e.g. returns 1.5 for 150% health factor)
|
|
506
|
+
*/
|
|
507
|
+
async get_health_factor_tokenwise(lending_tokens, debt_tokens, user) {
|
|
508
|
+
const positions = await this.getPositions(user);
|
|
509
|
+
logger.verbose(`${this.metadata.name}:: Positions: ${JSON.stringify(positions)}`);
|
|
510
|
+
let effectiveDebt = new Web3Number(0, 6);
|
|
511
|
+
positions.filter((pos) => {
|
|
512
|
+
return debt_tokens.find((t) => t.symbol === pos.tokenSymbol);
|
|
513
|
+
}).forEach((pos) => {
|
|
514
|
+
const token = this.tokens.find((t) => t.symbol === pos.tokenSymbol);
|
|
515
|
+
if (!token) {
|
|
516
|
+
throw new FatalError(`Token ${pos.tokenName} not found in ${this.metadata.name}`);
|
|
517
|
+
}
|
|
518
|
+
effectiveDebt = effectiveDebt.plus(pos.debtUSD.dividedBy(token.borrowFactor.toFixed(6)).toString());
|
|
519
|
+
});
|
|
520
|
+
logger.verbose(`${this.metadata.name}:: Effective debt: ${effectiveDebt}`);
|
|
521
|
+
if (effectiveDebt.isZero()) {
|
|
522
|
+
return Infinity;
|
|
523
|
+
}
|
|
524
|
+
let effectiveCollateral = new Web3Number(0, 6);
|
|
525
|
+
positions.filter((pos) => {
|
|
526
|
+
const exp1 = lending_tokens.find((t) => t.symbol === pos.tokenSymbol);
|
|
527
|
+
const exp2 = pos.marginType === "shared" /* SHARED */;
|
|
528
|
+
return exp1 && exp2;
|
|
529
|
+
}).forEach((pos) => {
|
|
530
|
+
const token = this.tokens.find((t) => t.symbol === pos.tokenSymbol);
|
|
531
|
+
if (!token) {
|
|
532
|
+
throw new FatalError(`Token ${pos.tokenName} not found in ${this.metadata.name}`);
|
|
533
|
+
}
|
|
534
|
+
logger.verbose(`${this.metadata.name}:: Token: ${pos.tokenName}, Collateral factor: ${token.collareralFactor.toFixed(6)}`);
|
|
535
|
+
effectiveCollateral = effectiveCollateral.plus(pos.supplyUSD.multipliedBy(token.collareralFactor.toFixed(6)).toString());
|
|
536
|
+
});
|
|
537
|
+
logger.verbose(`${this.metadata.name}:: Effective collateral: ${effectiveCollateral}`);
|
|
538
|
+
const healthFactor = effectiveCollateral.dividedBy(effectiveDebt.toFixed(6)).toNumber();
|
|
539
|
+
logger.verbose(`${this.metadata.name}:: Health factor: ${healthFactor}`);
|
|
540
|
+
return healthFactor;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* @description Get the health factor of the user
|
|
544
|
+
* - Considers all tokens for collateral and debt
|
|
545
|
+
*/
|
|
546
|
+
async get_health_factor(user) {
|
|
547
|
+
return this.get_health_factor_tokenwise(this.tokens, this.tokens, user);
|
|
548
|
+
}
|
|
549
|
+
async getPositionsSummary(user) {
|
|
550
|
+
const pos = await this.getPositions(user);
|
|
551
|
+
const collateralUSD = pos.reduce((acc, p) => acc + p.supplyUSD.toNumber(), 0);
|
|
552
|
+
const debtUSD = pos.reduce((acc, p) => acc + p.debtUSD.toNumber(), 0);
|
|
553
|
+
return {
|
|
554
|
+
collateralUSD,
|
|
555
|
+
debtUSD
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* @description Get the token-wise collateral and debt positions of the user
|
|
560
|
+
* @param user Contract address of the user
|
|
561
|
+
* @returns Promise<ILendingPosition[]>
|
|
562
|
+
*/
|
|
563
|
+
async getPositions(user) {
|
|
564
|
+
const url = this.POSITION_URL.replace("{{USER_ADDR}}", user.address);
|
|
565
|
+
const result = await axios3.get(url);
|
|
566
|
+
const data = result.data;
|
|
567
|
+
const lendingPosition = [];
|
|
568
|
+
logger.verbose(`${this.metadata.name}:: Positions: ${JSON.stringify(data)}`);
|
|
569
|
+
for (let i = 0; i < data.pools.length; i++) {
|
|
570
|
+
const pool = data.pools[i];
|
|
571
|
+
const token = this.tokens.find((t) => {
|
|
572
|
+
return t.symbol === pool.token_symbol;
|
|
573
|
+
});
|
|
574
|
+
if (!token) {
|
|
575
|
+
throw new FatalError(`Token ${pool.token_symbol} not found in ${this.metadata.name}`);
|
|
576
|
+
}
|
|
577
|
+
const debtAmount = Web3Number.fromWei(pool.data.debt_amount, token.decimals);
|
|
578
|
+
const supplyAmount = Web3Number.fromWei(pool.data.supply_amount, token.decimals);
|
|
579
|
+
const price = (await this.pricer.getPrice(token.symbol)).price;
|
|
580
|
+
lendingPosition.push({
|
|
581
|
+
tokenName: token.name,
|
|
582
|
+
tokenSymbol: token.symbol,
|
|
583
|
+
marginType: pool.data.is_collateral ? "shared" /* SHARED */ : "none" /* NONE */,
|
|
584
|
+
debtAmount,
|
|
585
|
+
debtUSD: debtAmount.multipliedBy(price.toFixed(6)),
|
|
586
|
+
supplyAmount,
|
|
587
|
+
supplyUSD: supplyAmount.multipliedBy(price.toFixed(6))
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
;
|
|
591
|
+
return lendingPosition;
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
_ZkLend.POOLS_URL = "https://app.zklend.com/api/pools";
|
|
595
|
+
var ZkLend = _ZkLend;
|
|
596
|
+
|
|
597
|
+
// src/modules/pricer-from-api.ts
|
|
598
|
+
import axios4 from "axios";
|
|
599
|
+
var PricerFromApi = class extends PricerBase {
|
|
600
|
+
constructor(config, tokens2) {
|
|
601
|
+
super(config, tokens2);
|
|
602
|
+
}
|
|
603
|
+
async getPrice(tokenSymbol) {
|
|
604
|
+
try {
|
|
605
|
+
return await this.getPriceFromMyAPI(tokenSymbol);
|
|
606
|
+
} catch (e) {
|
|
607
|
+
logger.warn("getPriceFromMyAPI error", e);
|
|
608
|
+
}
|
|
609
|
+
logger.log("getPrice coinbase", tokenSymbol);
|
|
610
|
+
let retry = 0;
|
|
611
|
+
const MAX_RETRIES = 5;
|
|
612
|
+
for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
|
|
613
|
+
try {
|
|
614
|
+
const priceInfo = await axios4.get(
|
|
615
|
+
`https://api.coinbase.com/v2/prices/${tokenSymbol}-USDT/spot`
|
|
616
|
+
);
|
|
617
|
+
if (!priceInfo) {
|
|
618
|
+
throw new Error("Failed to fetch price");
|
|
619
|
+
}
|
|
620
|
+
const data = await priceInfo.data;
|
|
621
|
+
const price = Number(data.data.amount);
|
|
622
|
+
return {
|
|
623
|
+
price,
|
|
624
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
625
|
+
};
|
|
626
|
+
} catch (e) {
|
|
627
|
+
logger.warn("getPrice coinbase error", e, retry);
|
|
628
|
+
await new Promise((resolve) => setTimeout(resolve, retry * 1e3));
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
throw new Error(`Failed to fetch price for ${tokenSymbol}`);
|
|
632
|
+
}
|
|
633
|
+
async getPriceFromMyAPI(tokenSymbol) {
|
|
634
|
+
logger.verbose(`getPrice from redis: ${tokenSymbol}`);
|
|
635
|
+
const endpoint = "https://app.strkfarm.com";
|
|
636
|
+
const url = `${endpoint}/api/price/${tokenSymbol}`;
|
|
637
|
+
const priceInfoRes = await fetch(url);
|
|
638
|
+
const priceInfo = await priceInfoRes.json();
|
|
639
|
+
const now = /* @__PURE__ */ new Date();
|
|
640
|
+
const priceTime = new Date(priceInfo.timestamp);
|
|
641
|
+
if (now.getTime() - priceTime.getTime() > 9e5) {
|
|
642
|
+
throw new Error("Price is stale");
|
|
643
|
+
}
|
|
644
|
+
const price = Number(priceInfo.price);
|
|
645
|
+
return {
|
|
646
|
+
price,
|
|
647
|
+
timestamp: new Date(priceInfo.timestamp)
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
// src/interfaces/common.ts
|
|
653
|
+
import { RpcProvider as RpcProvider2 } from "starknet";
|
|
654
|
+
var RiskType = /* @__PURE__ */ ((RiskType2) => {
|
|
655
|
+
RiskType2["MARKET_RISK"] = "MARKET_RISK";
|
|
656
|
+
RiskType2["IMPERMANENT_LOSS"] = "IMPERMANENT_LOSS";
|
|
657
|
+
RiskType2["LIQUIDITY_RISK"] = "LIQUIDITY_RISK";
|
|
658
|
+
RiskType2["SMART_CONTRACT_RISK"] = "SMART_CONTRACT_RISK";
|
|
659
|
+
RiskType2["TECHNICAL_RISK"] = "TECHNICAL_RISK";
|
|
660
|
+
RiskType2["COUNTERPARTY_RISK"] = "COUNTERPARTY_RISK";
|
|
661
|
+
return RiskType2;
|
|
662
|
+
})(RiskType || {});
|
|
663
|
+
var Network = /* @__PURE__ */ ((Network2) => {
|
|
664
|
+
Network2["mainnet"] = "mainnet";
|
|
665
|
+
Network2["sepolia"] = "sepolia";
|
|
666
|
+
Network2["devnet"] = "devnet";
|
|
667
|
+
return Network2;
|
|
668
|
+
})(Network || {});
|
|
669
|
+
var FlowChartColors = /* @__PURE__ */ ((FlowChartColors2) => {
|
|
670
|
+
FlowChartColors2["Green"] = "purple";
|
|
671
|
+
FlowChartColors2["Blue"] = "#35484f";
|
|
672
|
+
FlowChartColors2["Purple"] = "#6e53dc";
|
|
673
|
+
return FlowChartColors2;
|
|
674
|
+
})(FlowChartColors || {});
|
|
675
|
+
function getMainnetConfig(rpcUrl = "https://starknet-mainnet.public.blastapi.io", blockIdentifier = "pending") {
|
|
676
|
+
return {
|
|
677
|
+
provider: new RpcProvider2({
|
|
678
|
+
nodeUrl: rpcUrl,
|
|
679
|
+
blockIdentifier
|
|
680
|
+
}),
|
|
681
|
+
stage: "production",
|
|
682
|
+
network: "mainnet" /* mainnet */
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/interfaces/initializable.ts
|
|
687
|
+
var Initializable = class {
|
|
688
|
+
constructor() {
|
|
689
|
+
this.initialized = false;
|
|
690
|
+
}
|
|
691
|
+
async waitForInitilisation() {
|
|
692
|
+
return new Promise((resolve, reject) => {
|
|
693
|
+
const interval = setInterval(() => {
|
|
694
|
+
if (this.initialized) {
|
|
695
|
+
console.log("Initialised");
|
|
696
|
+
clearInterval(interval);
|
|
697
|
+
resolve();
|
|
698
|
+
}
|
|
699
|
+
}, 1e3);
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
// src/strategies/autoCompounderStrk.ts
|
|
705
|
+
import { Contract as Contract2, uint256 } from "starknet";
|
|
706
|
+
var AutoCompounderSTRK = class {
|
|
707
|
+
constructor(config, pricer) {
|
|
708
|
+
this.addr = ContractAddr.from("0x541681b9ad63dff1b35f79c78d8477f64857de29a27902f7298f7b620838ea");
|
|
709
|
+
this.initialized = false;
|
|
710
|
+
this.contract = null;
|
|
711
|
+
this.metadata = {
|
|
712
|
+
decimals: 18,
|
|
713
|
+
underlying: {
|
|
714
|
+
// zSTRK
|
|
715
|
+
address: ContractAddr.from("0x06d8fa671ef84f791b7f601fa79fea8f6ceb70b5fa84189e3159d532162efc21"),
|
|
716
|
+
name: "STRK",
|
|
717
|
+
symbol: "STRK"
|
|
718
|
+
},
|
|
719
|
+
name: "AutoCompounderSTRK"
|
|
720
|
+
};
|
|
721
|
+
this.config = config;
|
|
722
|
+
this.pricer = pricer;
|
|
723
|
+
this.init();
|
|
724
|
+
}
|
|
725
|
+
async init() {
|
|
726
|
+
const provider = this.config.provider;
|
|
727
|
+
const cls = await provider.getClassAt(this.addr.address);
|
|
728
|
+
this.contract = new Contract2(cls.abi, this.addr.address, provider);
|
|
729
|
+
this.initialized = true;
|
|
730
|
+
}
|
|
731
|
+
async waitForInitilisation() {
|
|
732
|
+
return new Promise((resolve, reject) => {
|
|
733
|
+
const interval = setInterval(() => {
|
|
734
|
+
if (this.initialized) {
|
|
735
|
+
clearInterval(interval);
|
|
736
|
+
resolve();
|
|
737
|
+
}
|
|
738
|
+
}, 1e3);
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
/** Returns shares of user */
|
|
742
|
+
async balanceOf(user) {
|
|
743
|
+
const result = await this.contract.balanceOf(user.address);
|
|
744
|
+
return Web3Number.fromWei(result.toString(), this.metadata.decimals);
|
|
745
|
+
}
|
|
746
|
+
/** Returns underlying assets of user */
|
|
747
|
+
async balanceOfUnderlying(user) {
|
|
748
|
+
const balanceShares = await this.balanceOf(user);
|
|
749
|
+
const assets = await this.contract.convert_to_assets(uint256.bnToUint256(balanceShares.toWei()));
|
|
750
|
+
return Web3Number.fromWei(assets.toString(), this.metadata.decimals);
|
|
751
|
+
}
|
|
752
|
+
/** Returns usd value of assets */
|
|
753
|
+
async usdBalanceOfUnderlying(user) {
|
|
754
|
+
const assets = await this.balanceOfUnderlying(user);
|
|
755
|
+
const price = await this.pricer.getPrice(this.metadata.underlying.name);
|
|
756
|
+
const usd = assets.multipliedBy(price.price.toFixed(6));
|
|
757
|
+
return {
|
|
758
|
+
usd,
|
|
759
|
+
assets
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
// src/strategies/vesu-rebalance.ts
|
|
765
|
+
import { CairoCustomEnum, Contract as Contract3, num as num2, uint256 as uint2562 } from "starknet";
|
|
766
|
+
|
|
767
|
+
// src/data/vesu-rebalance.abi.json
|
|
768
|
+
var vesu_rebalance_abi_default = [
|
|
769
|
+
{
|
|
770
|
+
type: "impl",
|
|
771
|
+
name: "ExternalImpl",
|
|
772
|
+
interface_name: "strkfarm_contracts::strategies::vesu_rebalance::interface::IVesuRebal"
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
type: "enum",
|
|
776
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::interface::Feature",
|
|
777
|
+
variants: [
|
|
778
|
+
{
|
|
779
|
+
name: "DEPOSIT",
|
|
780
|
+
type: "()"
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
name: "WITHDRAW",
|
|
784
|
+
type: "()"
|
|
785
|
+
}
|
|
786
|
+
]
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
type: "struct",
|
|
790
|
+
name: "core::integer::u256",
|
|
791
|
+
members: [
|
|
792
|
+
{
|
|
793
|
+
name: "low",
|
|
794
|
+
type: "core::integer::u128"
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
name: "high",
|
|
798
|
+
type: "core::integer::u128"
|
|
799
|
+
}
|
|
800
|
+
]
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
type: "struct",
|
|
804
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::interface::Action",
|
|
805
|
+
members: [
|
|
806
|
+
{
|
|
807
|
+
name: "pool_id",
|
|
808
|
+
type: "core::felt252"
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
name: "feature",
|
|
812
|
+
type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Feature"
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
name: "token",
|
|
816
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
name: "amount",
|
|
820
|
+
type: "core::integer::u256"
|
|
821
|
+
}
|
|
822
|
+
]
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
type: "struct",
|
|
826
|
+
name: "strkfarm_contracts::interfaces::IEkuboDistributor::Claim",
|
|
827
|
+
members: [
|
|
828
|
+
{
|
|
829
|
+
name: "id",
|
|
830
|
+
type: "core::integer::u64"
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
name: "claimee",
|
|
834
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
name: "amount",
|
|
838
|
+
type: "core::integer::u128"
|
|
839
|
+
}
|
|
840
|
+
]
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
type: "struct",
|
|
844
|
+
name: "core::array::Span::<core::felt252>",
|
|
845
|
+
members: [
|
|
846
|
+
{
|
|
847
|
+
name: "snapshot",
|
|
848
|
+
type: "@core::array::Array::<core::felt252>"
|
|
849
|
+
}
|
|
850
|
+
]
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
type: "struct",
|
|
854
|
+
name: "strkfarm_contracts::components::swap::Route",
|
|
855
|
+
members: [
|
|
856
|
+
{
|
|
857
|
+
name: "token_from",
|
|
858
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
name: "token_to",
|
|
862
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
name: "exchange_address",
|
|
866
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
name: "percent",
|
|
870
|
+
type: "core::integer::u128"
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
name: "additional_swap_params",
|
|
874
|
+
type: "core::array::Array::<core::felt252>"
|
|
875
|
+
}
|
|
876
|
+
]
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
type: "struct",
|
|
880
|
+
name: "strkfarm_contracts::components::swap::AvnuMultiRouteSwap",
|
|
881
|
+
members: [
|
|
882
|
+
{
|
|
883
|
+
name: "token_from_address",
|
|
884
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
name: "token_from_amount",
|
|
888
|
+
type: "core::integer::u256"
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
name: "token_to_address",
|
|
892
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
name: "token_to_amount",
|
|
896
|
+
type: "core::integer::u256"
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
name: "token_to_min_amount",
|
|
900
|
+
type: "core::integer::u256"
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
name: "beneficiary",
|
|
904
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
name: "integrator_fee_amount_bps",
|
|
908
|
+
type: "core::integer::u128"
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
name: "integrator_fee_recipient",
|
|
912
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
name: "routes",
|
|
916
|
+
type: "core::array::Array::<strkfarm_contracts::components::swap::Route>"
|
|
917
|
+
}
|
|
918
|
+
]
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
type: "struct",
|
|
922
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings",
|
|
923
|
+
members: [
|
|
924
|
+
{
|
|
925
|
+
name: "default_pool_index",
|
|
926
|
+
type: "core::integer::u8"
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
name: "fee_bps",
|
|
930
|
+
type: "core::integer::u32"
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
name: "fee_receiver",
|
|
934
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
935
|
+
}
|
|
936
|
+
]
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
type: "struct",
|
|
940
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps",
|
|
941
|
+
members: [
|
|
942
|
+
{
|
|
943
|
+
name: "pool_id",
|
|
944
|
+
type: "core::felt252"
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
name: "max_weight",
|
|
948
|
+
type: "core::integer::u32"
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
name: "v_token",
|
|
952
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
953
|
+
}
|
|
954
|
+
]
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
type: "interface",
|
|
958
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::interface::IVesuRebal",
|
|
959
|
+
items: [
|
|
960
|
+
{
|
|
961
|
+
type: "function",
|
|
962
|
+
name: "rebalance",
|
|
963
|
+
inputs: [
|
|
964
|
+
{
|
|
965
|
+
name: "actions",
|
|
966
|
+
type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::Action>"
|
|
967
|
+
}
|
|
968
|
+
],
|
|
969
|
+
outputs: [],
|
|
970
|
+
state_mutability: "external"
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
type: "function",
|
|
974
|
+
name: "rebalance_weights",
|
|
975
|
+
inputs: [
|
|
976
|
+
{
|
|
977
|
+
name: "actions",
|
|
978
|
+
type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::Action>"
|
|
979
|
+
}
|
|
980
|
+
],
|
|
981
|
+
outputs: [],
|
|
982
|
+
state_mutability: "external"
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
type: "function",
|
|
986
|
+
name: "emergency_withdraw",
|
|
987
|
+
inputs: [],
|
|
988
|
+
outputs: [],
|
|
989
|
+
state_mutability: "external"
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
type: "function",
|
|
993
|
+
name: "emergency_withdraw_pool",
|
|
994
|
+
inputs: [
|
|
995
|
+
{
|
|
996
|
+
name: "pool_index",
|
|
997
|
+
type: "core::integer::u32"
|
|
998
|
+
}
|
|
999
|
+
],
|
|
1000
|
+
outputs: [],
|
|
1001
|
+
state_mutability: "external"
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
type: "function",
|
|
1005
|
+
name: "compute_yield",
|
|
1006
|
+
inputs: [],
|
|
1007
|
+
outputs: [
|
|
1008
|
+
{
|
|
1009
|
+
type: "(core::integer::u256, core::integer::u256)"
|
|
1010
|
+
}
|
|
1011
|
+
],
|
|
1012
|
+
state_mutability: "view"
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
type: "function",
|
|
1016
|
+
name: "harvest",
|
|
1017
|
+
inputs: [
|
|
1018
|
+
{
|
|
1019
|
+
name: "rewardsContract",
|
|
1020
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
name: "claim",
|
|
1024
|
+
type: "strkfarm_contracts::interfaces::IEkuboDistributor::Claim"
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
name: "proof",
|
|
1028
|
+
type: "core::array::Span::<core::felt252>"
|
|
1029
|
+
},
|
|
1030
|
+
{
|
|
1031
|
+
name: "swapInfo",
|
|
1032
|
+
type: "strkfarm_contracts::components::swap::AvnuMultiRouteSwap"
|
|
1033
|
+
}
|
|
1034
|
+
],
|
|
1035
|
+
outputs: [],
|
|
1036
|
+
state_mutability: "external"
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
type: "function",
|
|
1040
|
+
name: "set_settings",
|
|
1041
|
+
inputs: [
|
|
1042
|
+
{
|
|
1043
|
+
name: "settings",
|
|
1044
|
+
type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings"
|
|
1045
|
+
}
|
|
1046
|
+
],
|
|
1047
|
+
outputs: [],
|
|
1048
|
+
state_mutability: "external"
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
type: "function",
|
|
1052
|
+
name: "set_allowed_pools",
|
|
1053
|
+
inputs: [
|
|
1054
|
+
{
|
|
1055
|
+
name: "pools",
|
|
1056
|
+
type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps>"
|
|
1057
|
+
}
|
|
1058
|
+
],
|
|
1059
|
+
outputs: [],
|
|
1060
|
+
state_mutability: "external"
|
|
1061
|
+
},
|
|
1062
|
+
{
|
|
1063
|
+
type: "function",
|
|
1064
|
+
name: "set_incentives_off",
|
|
1065
|
+
inputs: [],
|
|
1066
|
+
outputs: [],
|
|
1067
|
+
state_mutability: "external"
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
type: "function",
|
|
1071
|
+
name: "get_settings",
|
|
1072
|
+
inputs: [],
|
|
1073
|
+
outputs: [
|
|
1074
|
+
{
|
|
1075
|
+
type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings"
|
|
1076
|
+
}
|
|
1077
|
+
],
|
|
1078
|
+
state_mutability: "view"
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
type: "function",
|
|
1082
|
+
name: "get_allowed_pools",
|
|
1083
|
+
inputs: [],
|
|
1084
|
+
outputs: [
|
|
1085
|
+
{
|
|
1086
|
+
type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps>"
|
|
1087
|
+
}
|
|
1088
|
+
],
|
|
1089
|
+
state_mutability: "view"
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
type: "function",
|
|
1093
|
+
name: "get_previous_index",
|
|
1094
|
+
inputs: [],
|
|
1095
|
+
outputs: [
|
|
1096
|
+
{
|
|
1097
|
+
type: "core::integer::u128"
|
|
1098
|
+
}
|
|
1099
|
+
],
|
|
1100
|
+
state_mutability: "view"
|
|
1101
|
+
}
|
|
1102
|
+
]
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
type: "impl",
|
|
1106
|
+
name: "VesuERC4626Impl",
|
|
1107
|
+
interface_name: "strkfarm_contracts::interfaces::IERC4626::IERC4626"
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
type: "interface",
|
|
1111
|
+
name: "strkfarm_contracts::interfaces::IERC4626::IERC4626",
|
|
1112
|
+
items: [
|
|
1113
|
+
{
|
|
1114
|
+
type: "function",
|
|
1115
|
+
name: "asset",
|
|
1116
|
+
inputs: [],
|
|
1117
|
+
outputs: [
|
|
1118
|
+
{
|
|
1119
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1120
|
+
}
|
|
1121
|
+
],
|
|
1122
|
+
state_mutability: "view"
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
type: "function",
|
|
1126
|
+
name: "total_assets",
|
|
1127
|
+
inputs: [],
|
|
1128
|
+
outputs: [
|
|
1129
|
+
{
|
|
1130
|
+
type: "core::integer::u256"
|
|
1131
|
+
}
|
|
1132
|
+
],
|
|
1133
|
+
state_mutability: "view"
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
type: "function",
|
|
1137
|
+
name: "convert_to_shares",
|
|
1138
|
+
inputs: [
|
|
1139
|
+
{
|
|
1140
|
+
name: "assets",
|
|
1141
|
+
type: "core::integer::u256"
|
|
1142
|
+
}
|
|
1143
|
+
],
|
|
1144
|
+
outputs: [
|
|
1145
|
+
{
|
|
1146
|
+
type: "core::integer::u256"
|
|
1147
|
+
}
|
|
1148
|
+
],
|
|
1149
|
+
state_mutability: "view"
|
|
1150
|
+
},
|
|
1151
|
+
{
|
|
1152
|
+
type: "function",
|
|
1153
|
+
name: "convert_to_assets",
|
|
1154
|
+
inputs: [
|
|
1155
|
+
{
|
|
1156
|
+
name: "shares",
|
|
1157
|
+
type: "core::integer::u256"
|
|
1158
|
+
}
|
|
1159
|
+
],
|
|
1160
|
+
outputs: [
|
|
1161
|
+
{
|
|
1162
|
+
type: "core::integer::u256"
|
|
1163
|
+
}
|
|
1164
|
+
],
|
|
1165
|
+
state_mutability: "view"
|
|
1166
|
+
},
|
|
1167
|
+
{
|
|
1168
|
+
type: "function",
|
|
1169
|
+
name: "max_deposit",
|
|
1170
|
+
inputs: [
|
|
1171
|
+
{
|
|
1172
|
+
name: "receiver",
|
|
1173
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1174
|
+
}
|
|
1175
|
+
],
|
|
1176
|
+
outputs: [
|
|
1177
|
+
{
|
|
1178
|
+
type: "core::integer::u256"
|
|
1179
|
+
}
|
|
1180
|
+
],
|
|
1181
|
+
state_mutability: "view"
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
type: "function",
|
|
1185
|
+
name: "preview_deposit",
|
|
1186
|
+
inputs: [
|
|
1187
|
+
{
|
|
1188
|
+
name: "assets",
|
|
1189
|
+
type: "core::integer::u256"
|
|
1190
|
+
}
|
|
1191
|
+
],
|
|
1192
|
+
outputs: [
|
|
1193
|
+
{
|
|
1194
|
+
type: "core::integer::u256"
|
|
1195
|
+
}
|
|
1196
|
+
],
|
|
1197
|
+
state_mutability: "view"
|
|
1198
|
+
},
|
|
1199
|
+
{
|
|
1200
|
+
type: "function",
|
|
1201
|
+
name: "deposit",
|
|
1202
|
+
inputs: [
|
|
1203
|
+
{
|
|
1204
|
+
name: "assets",
|
|
1205
|
+
type: "core::integer::u256"
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
name: "receiver",
|
|
1209
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1210
|
+
}
|
|
1211
|
+
],
|
|
1212
|
+
outputs: [
|
|
1213
|
+
{
|
|
1214
|
+
type: "core::integer::u256"
|
|
1215
|
+
}
|
|
1216
|
+
],
|
|
1217
|
+
state_mutability: "external"
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
type: "function",
|
|
1221
|
+
name: "max_mint",
|
|
1222
|
+
inputs: [
|
|
1223
|
+
{
|
|
1224
|
+
name: "receiver",
|
|
1225
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1226
|
+
}
|
|
1227
|
+
],
|
|
1228
|
+
outputs: [
|
|
1229
|
+
{
|
|
1230
|
+
type: "core::integer::u256"
|
|
1231
|
+
}
|
|
1232
|
+
],
|
|
1233
|
+
state_mutability: "view"
|
|
1234
|
+
},
|
|
1235
|
+
{
|
|
1236
|
+
type: "function",
|
|
1237
|
+
name: "preview_mint",
|
|
1238
|
+
inputs: [
|
|
1239
|
+
{
|
|
1240
|
+
name: "shares",
|
|
1241
|
+
type: "core::integer::u256"
|
|
1242
|
+
}
|
|
1243
|
+
],
|
|
1244
|
+
outputs: [
|
|
1245
|
+
{
|
|
1246
|
+
type: "core::integer::u256"
|
|
1247
|
+
}
|
|
1248
|
+
],
|
|
1249
|
+
state_mutability: "view"
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
type: "function",
|
|
1253
|
+
name: "mint",
|
|
1254
|
+
inputs: [
|
|
1255
|
+
{
|
|
1256
|
+
name: "shares",
|
|
1257
|
+
type: "core::integer::u256"
|
|
1258
|
+
},
|
|
1259
|
+
{
|
|
1260
|
+
name: "receiver",
|
|
1261
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1262
|
+
}
|
|
1263
|
+
],
|
|
1264
|
+
outputs: [
|
|
1265
|
+
{
|
|
1266
|
+
type: "core::integer::u256"
|
|
1267
|
+
}
|
|
1268
|
+
],
|
|
1269
|
+
state_mutability: "external"
|
|
1270
|
+
},
|
|
1271
|
+
{
|
|
1272
|
+
type: "function",
|
|
1273
|
+
name: "max_withdraw",
|
|
1274
|
+
inputs: [
|
|
1275
|
+
{
|
|
1276
|
+
name: "owner",
|
|
1277
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1278
|
+
}
|
|
1279
|
+
],
|
|
1280
|
+
outputs: [
|
|
1281
|
+
{
|
|
1282
|
+
type: "core::integer::u256"
|
|
1283
|
+
}
|
|
1284
|
+
],
|
|
1285
|
+
state_mutability: "view"
|
|
1286
|
+
},
|
|
1287
|
+
{
|
|
1288
|
+
type: "function",
|
|
1289
|
+
name: "preview_withdraw",
|
|
1290
|
+
inputs: [
|
|
1291
|
+
{
|
|
1292
|
+
name: "assets",
|
|
1293
|
+
type: "core::integer::u256"
|
|
1294
|
+
}
|
|
1295
|
+
],
|
|
1296
|
+
outputs: [
|
|
1297
|
+
{
|
|
1298
|
+
type: "core::integer::u256"
|
|
1299
|
+
}
|
|
1300
|
+
],
|
|
1301
|
+
state_mutability: "view"
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
type: "function",
|
|
1305
|
+
name: "withdraw",
|
|
1306
|
+
inputs: [
|
|
1307
|
+
{
|
|
1308
|
+
name: "assets",
|
|
1309
|
+
type: "core::integer::u256"
|
|
1310
|
+
},
|
|
1311
|
+
{
|
|
1312
|
+
name: "receiver",
|
|
1313
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
name: "owner",
|
|
1317
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1318
|
+
}
|
|
1319
|
+
],
|
|
1320
|
+
outputs: [
|
|
1321
|
+
{
|
|
1322
|
+
type: "core::integer::u256"
|
|
1323
|
+
}
|
|
1324
|
+
],
|
|
1325
|
+
state_mutability: "external"
|
|
1326
|
+
},
|
|
1327
|
+
{
|
|
1328
|
+
type: "function",
|
|
1329
|
+
name: "max_redeem",
|
|
1330
|
+
inputs: [
|
|
1331
|
+
{
|
|
1332
|
+
name: "owner",
|
|
1333
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1334
|
+
}
|
|
1335
|
+
],
|
|
1336
|
+
outputs: [
|
|
1337
|
+
{
|
|
1338
|
+
type: "core::integer::u256"
|
|
1339
|
+
}
|
|
1340
|
+
],
|
|
1341
|
+
state_mutability: "view"
|
|
1342
|
+
},
|
|
1343
|
+
{
|
|
1344
|
+
type: "function",
|
|
1345
|
+
name: "preview_redeem",
|
|
1346
|
+
inputs: [
|
|
1347
|
+
{
|
|
1348
|
+
name: "shares",
|
|
1349
|
+
type: "core::integer::u256"
|
|
1350
|
+
}
|
|
1351
|
+
],
|
|
1352
|
+
outputs: [
|
|
1353
|
+
{
|
|
1354
|
+
type: "core::integer::u256"
|
|
1355
|
+
}
|
|
1356
|
+
],
|
|
1357
|
+
state_mutability: "view"
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
type: "function",
|
|
1361
|
+
name: "redeem",
|
|
1362
|
+
inputs: [
|
|
1363
|
+
{
|
|
1364
|
+
name: "shares",
|
|
1365
|
+
type: "core::integer::u256"
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
name: "receiver",
|
|
1369
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
name: "owner",
|
|
1373
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1374
|
+
}
|
|
1375
|
+
],
|
|
1376
|
+
outputs: [
|
|
1377
|
+
{
|
|
1378
|
+
type: "core::integer::u256"
|
|
1379
|
+
}
|
|
1380
|
+
],
|
|
1381
|
+
state_mutability: "external"
|
|
1382
|
+
}
|
|
1383
|
+
]
|
|
1384
|
+
},
|
|
1385
|
+
{
|
|
1386
|
+
type: "impl",
|
|
1387
|
+
name: "VesuERC20Impl",
|
|
1388
|
+
interface_name: "openzeppelin_token::erc20::interface::IERC20Mixin"
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
type: "enum",
|
|
1392
|
+
name: "core::bool",
|
|
1393
|
+
variants: [
|
|
1394
|
+
{
|
|
1395
|
+
name: "False",
|
|
1396
|
+
type: "()"
|
|
1397
|
+
},
|
|
1398
|
+
{
|
|
1399
|
+
name: "True",
|
|
1400
|
+
type: "()"
|
|
1401
|
+
}
|
|
1402
|
+
]
|
|
1403
|
+
},
|
|
1404
|
+
{
|
|
1405
|
+
type: "struct",
|
|
1406
|
+
name: "core::byte_array::ByteArray",
|
|
1407
|
+
members: [
|
|
1408
|
+
{
|
|
1409
|
+
name: "data",
|
|
1410
|
+
type: "core::array::Array::<core::bytes_31::bytes31>"
|
|
1411
|
+
},
|
|
1412
|
+
{
|
|
1413
|
+
name: "pending_word",
|
|
1414
|
+
type: "core::felt252"
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
name: "pending_word_len",
|
|
1418
|
+
type: "core::integer::u32"
|
|
1419
|
+
}
|
|
1420
|
+
]
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
type: "interface",
|
|
1424
|
+
name: "openzeppelin_token::erc20::interface::IERC20Mixin",
|
|
1425
|
+
items: [
|
|
1426
|
+
{
|
|
1427
|
+
type: "function",
|
|
1428
|
+
name: "total_supply",
|
|
1429
|
+
inputs: [],
|
|
1430
|
+
outputs: [
|
|
1431
|
+
{
|
|
1432
|
+
type: "core::integer::u256"
|
|
1433
|
+
}
|
|
1434
|
+
],
|
|
1435
|
+
state_mutability: "view"
|
|
1436
|
+
},
|
|
1437
|
+
{
|
|
1438
|
+
type: "function",
|
|
1439
|
+
name: "balance_of",
|
|
1440
|
+
inputs: [
|
|
1441
|
+
{
|
|
1442
|
+
name: "account",
|
|
1443
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1444
|
+
}
|
|
1445
|
+
],
|
|
1446
|
+
outputs: [
|
|
1447
|
+
{
|
|
1448
|
+
type: "core::integer::u256"
|
|
1449
|
+
}
|
|
1450
|
+
],
|
|
1451
|
+
state_mutability: "view"
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
type: "function",
|
|
1455
|
+
name: "allowance",
|
|
1456
|
+
inputs: [
|
|
1457
|
+
{
|
|
1458
|
+
name: "owner",
|
|
1459
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
name: "spender",
|
|
1463
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1464
|
+
}
|
|
1465
|
+
],
|
|
1466
|
+
outputs: [
|
|
1467
|
+
{
|
|
1468
|
+
type: "core::integer::u256"
|
|
1469
|
+
}
|
|
1470
|
+
],
|
|
1471
|
+
state_mutability: "view"
|
|
1472
|
+
},
|
|
1473
|
+
{
|
|
1474
|
+
type: "function",
|
|
1475
|
+
name: "transfer",
|
|
1476
|
+
inputs: [
|
|
1477
|
+
{
|
|
1478
|
+
name: "recipient",
|
|
1479
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1480
|
+
},
|
|
1481
|
+
{
|
|
1482
|
+
name: "amount",
|
|
1483
|
+
type: "core::integer::u256"
|
|
1484
|
+
}
|
|
1485
|
+
],
|
|
1486
|
+
outputs: [
|
|
1487
|
+
{
|
|
1488
|
+
type: "core::bool"
|
|
1489
|
+
}
|
|
1490
|
+
],
|
|
1491
|
+
state_mutability: "external"
|
|
1492
|
+
},
|
|
1493
|
+
{
|
|
1494
|
+
type: "function",
|
|
1495
|
+
name: "transfer_from",
|
|
1496
|
+
inputs: [
|
|
1497
|
+
{
|
|
1498
|
+
name: "sender",
|
|
1499
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
name: "recipient",
|
|
1503
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1504
|
+
},
|
|
1505
|
+
{
|
|
1506
|
+
name: "amount",
|
|
1507
|
+
type: "core::integer::u256"
|
|
1508
|
+
}
|
|
1509
|
+
],
|
|
1510
|
+
outputs: [
|
|
1511
|
+
{
|
|
1512
|
+
type: "core::bool"
|
|
1513
|
+
}
|
|
1514
|
+
],
|
|
1515
|
+
state_mutability: "external"
|
|
1516
|
+
},
|
|
1517
|
+
{
|
|
1518
|
+
type: "function",
|
|
1519
|
+
name: "approve",
|
|
1520
|
+
inputs: [
|
|
1521
|
+
{
|
|
1522
|
+
name: "spender",
|
|
1523
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1524
|
+
},
|
|
1525
|
+
{
|
|
1526
|
+
name: "amount",
|
|
1527
|
+
type: "core::integer::u256"
|
|
1528
|
+
}
|
|
1529
|
+
],
|
|
1530
|
+
outputs: [
|
|
1531
|
+
{
|
|
1532
|
+
type: "core::bool"
|
|
1533
|
+
}
|
|
1534
|
+
],
|
|
1535
|
+
state_mutability: "external"
|
|
1536
|
+
},
|
|
1537
|
+
{
|
|
1538
|
+
type: "function",
|
|
1539
|
+
name: "name",
|
|
1540
|
+
inputs: [],
|
|
1541
|
+
outputs: [
|
|
1542
|
+
{
|
|
1543
|
+
type: "core::byte_array::ByteArray"
|
|
1544
|
+
}
|
|
1545
|
+
],
|
|
1546
|
+
state_mutability: "view"
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
type: "function",
|
|
1550
|
+
name: "symbol",
|
|
1551
|
+
inputs: [],
|
|
1552
|
+
outputs: [
|
|
1553
|
+
{
|
|
1554
|
+
type: "core::byte_array::ByteArray"
|
|
1555
|
+
}
|
|
1556
|
+
],
|
|
1557
|
+
state_mutability: "view"
|
|
1558
|
+
},
|
|
1559
|
+
{
|
|
1560
|
+
type: "function",
|
|
1561
|
+
name: "decimals",
|
|
1562
|
+
inputs: [],
|
|
1563
|
+
outputs: [
|
|
1564
|
+
{
|
|
1565
|
+
type: "core::integer::u8"
|
|
1566
|
+
}
|
|
1567
|
+
],
|
|
1568
|
+
state_mutability: "view"
|
|
1569
|
+
},
|
|
1570
|
+
{
|
|
1571
|
+
type: "function",
|
|
1572
|
+
name: "totalSupply",
|
|
1573
|
+
inputs: [],
|
|
1574
|
+
outputs: [
|
|
1575
|
+
{
|
|
1576
|
+
type: "core::integer::u256"
|
|
1577
|
+
}
|
|
1578
|
+
],
|
|
1579
|
+
state_mutability: "view"
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
type: "function",
|
|
1583
|
+
name: "balanceOf",
|
|
1584
|
+
inputs: [
|
|
1585
|
+
{
|
|
1586
|
+
name: "account",
|
|
1587
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1588
|
+
}
|
|
1589
|
+
],
|
|
1590
|
+
outputs: [
|
|
1591
|
+
{
|
|
1592
|
+
type: "core::integer::u256"
|
|
1593
|
+
}
|
|
1594
|
+
],
|
|
1595
|
+
state_mutability: "view"
|
|
1596
|
+
},
|
|
1597
|
+
{
|
|
1598
|
+
type: "function",
|
|
1599
|
+
name: "transferFrom",
|
|
1600
|
+
inputs: [
|
|
1601
|
+
{
|
|
1602
|
+
name: "sender",
|
|
1603
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
name: "recipient",
|
|
1607
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1608
|
+
},
|
|
1609
|
+
{
|
|
1610
|
+
name: "amount",
|
|
1611
|
+
type: "core::integer::u256"
|
|
1612
|
+
}
|
|
1613
|
+
],
|
|
1614
|
+
outputs: [
|
|
1615
|
+
{
|
|
1616
|
+
type: "core::bool"
|
|
1617
|
+
}
|
|
1618
|
+
],
|
|
1619
|
+
state_mutability: "external"
|
|
1620
|
+
}
|
|
1621
|
+
]
|
|
1622
|
+
},
|
|
1623
|
+
{
|
|
1624
|
+
type: "impl",
|
|
1625
|
+
name: "CommonCompImpl",
|
|
1626
|
+
interface_name: "strkfarm_contracts::interfaces::common::ICommon"
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
type: "interface",
|
|
1630
|
+
name: "strkfarm_contracts::interfaces::common::ICommon",
|
|
1631
|
+
items: [
|
|
1632
|
+
{
|
|
1633
|
+
type: "function",
|
|
1634
|
+
name: "upgrade",
|
|
1635
|
+
inputs: [
|
|
1636
|
+
{
|
|
1637
|
+
name: "new_class",
|
|
1638
|
+
type: "core::starknet::class_hash::ClassHash"
|
|
1639
|
+
}
|
|
1640
|
+
],
|
|
1641
|
+
outputs: [],
|
|
1642
|
+
state_mutability: "external"
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
type: "function",
|
|
1646
|
+
name: "pause",
|
|
1647
|
+
inputs: [],
|
|
1648
|
+
outputs: [],
|
|
1649
|
+
state_mutability: "external"
|
|
1650
|
+
},
|
|
1651
|
+
{
|
|
1652
|
+
type: "function",
|
|
1653
|
+
name: "unpause",
|
|
1654
|
+
inputs: [],
|
|
1655
|
+
outputs: [],
|
|
1656
|
+
state_mutability: "external"
|
|
1657
|
+
},
|
|
1658
|
+
{
|
|
1659
|
+
type: "function",
|
|
1660
|
+
name: "is_paused",
|
|
1661
|
+
inputs: [],
|
|
1662
|
+
outputs: [
|
|
1663
|
+
{
|
|
1664
|
+
type: "core::bool"
|
|
1665
|
+
}
|
|
1666
|
+
],
|
|
1667
|
+
state_mutability: "view"
|
|
1668
|
+
}
|
|
1669
|
+
]
|
|
1670
|
+
},
|
|
1671
|
+
{
|
|
1672
|
+
type: "impl",
|
|
1673
|
+
name: "RewardShareImpl",
|
|
1674
|
+
interface_name: "strkfarm_contracts::components::harvester::reward_shares::IRewardShare"
|
|
1675
|
+
},
|
|
1676
|
+
{
|
|
1677
|
+
type: "struct",
|
|
1678
|
+
name: "strkfarm_contracts::components::harvester::reward_shares::UserRewardsInfo",
|
|
1679
|
+
members: [
|
|
1680
|
+
{
|
|
1681
|
+
name: "pending_round_points",
|
|
1682
|
+
type: "core::integer::u128"
|
|
1683
|
+
},
|
|
1684
|
+
{
|
|
1685
|
+
name: "shares_owned",
|
|
1686
|
+
type: "core::integer::u128"
|
|
1687
|
+
},
|
|
1688
|
+
{
|
|
1689
|
+
name: "block_number",
|
|
1690
|
+
type: "core::integer::u64"
|
|
1691
|
+
},
|
|
1692
|
+
{
|
|
1693
|
+
name: "index",
|
|
1694
|
+
type: "core::integer::u32"
|
|
1695
|
+
}
|
|
1696
|
+
]
|
|
1697
|
+
},
|
|
1698
|
+
{
|
|
1699
|
+
type: "struct",
|
|
1700
|
+
name: "strkfarm_contracts::components::harvester::reward_shares::RewardsInfo",
|
|
1701
|
+
members: [
|
|
1702
|
+
{
|
|
1703
|
+
name: "amount",
|
|
1704
|
+
type: "core::integer::u128"
|
|
1705
|
+
},
|
|
1706
|
+
{
|
|
1707
|
+
name: "shares",
|
|
1708
|
+
type: "core::integer::u128"
|
|
1709
|
+
},
|
|
1710
|
+
{
|
|
1711
|
+
name: "total_round_points",
|
|
1712
|
+
type: "core::integer::u128"
|
|
1713
|
+
},
|
|
1714
|
+
{
|
|
1715
|
+
name: "block_number",
|
|
1716
|
+
type: "core::integer::u64"
|
|
1717
|
+
}
|
|
1718
|
+
]
|
|
1719
|
+
},
|
|
1720
|
+
{
|
|
1721
|
+
type: "interface",
|
|
1722
|
+
name: "strkfarm_contracts::components::harvester::reward_shares::IRewardShare",
|
|
1723
|
+
items: [
|
|
1724
|
+
{
|
|
1725
|
+
type: "function",
|
|
1726
|
+
name: "get_user_reward_info",
|
|
1727
|
+
inputs: [
|
|
1728
|
+
{
|
|
1729
|
+
name: "user",
|
|
1730
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1731
|
+
}
|
|
1732
|
+
],
|
|
1733
|
+
outputs: [
|
|
1734
|
+
{
|
|
1735
|
+
type: "strkfarm_contracts::components::harvester::reward_shares::UserRewardsInfo"
|
|
1736
|
+
}
|
|
1737
|
+
],
|
|
1738
|
+
state_mutability: "view"
|
|
1739
|
+
},
|
|
1740
|
+
{
|
|
1741
|
+
type: "function",
|
|
1742
|
+
name: "get_rewards_info",
|
|
1743
|
+
inputs: [
|
|
1744
|
+
{
|
|
1745
|
+
name: "index",
|
|
1746
|
+
type: "core::integer::u32"
|
|
1747
|
+
}
|
|
1748
|
+
],
|
|
1749
|
+
outputs: [
|
|
1750
|
+
{
|
|
1751
|
+
type: "strkfarm_contracts::components::harvester::reward_shares::RewardsInfo"
|
|
1752
|
+
}
|
|
1753
|
+
],
|
|
1754
|
+
state_mutability: "view"
|
|
1755
|
+
},
|
|
1756
|
+
{
|
|
1757
|
+
type: "function",
|
|
1758
|
+
name: "get_total_rewards",
|
|
1759
|
+
inputs: [],
|
|
1760
|
+
outputs: [
|
|
1761
|
+
{
|
|
1762
|
+
type: "core::integer::u32"
|
|
1763
|
+
}
|
|
1764
|
+
],
|
|
1765
|
+
state_mutability: "view"
|
|
1766
|
+
},
|
|
1767
|
+
{
|
|
1768
|
+
type: "function",
|
|
1769
|
+
name: "get_total_unminted_shares",
|
|
1770
|
+
inputs: [],
|
|
1771
|
+
outputs: [
|
|
1772
|
+
{
|
|
1773
|
+
type: "core::integer::u128"
|
|
1774
|
+
}
|
|
1775
|
+
],
|
|
1776
|
+
state_mutability: "view"
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
type: "function",
|
|
1780
|
+
name: "get_additional_shares",
|
|
1781
|
+
inputs: [
|
|
1782
|
+
{
|
|
1783
|
+
name: "user",
|
|
1784
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1785
|
+
}
|
|
1786
|
+
],
|
|
1787
|
+
outputs: [
|
|
1788
|
+
{
|
|
1789
|
+
type: "(core::integer::u128, core::integer::u64, core::integer::u128)"
|
|
1790
|
+
}
|
|
1791
|
+
],
|
|
1792
|
+
state_mutability: "view"
|
|
1793
|
+
}
|
|
1794
|
+
]
|
|
1795
|
+
},
|
|
1796
|
+
{
|
|
1797
|
+
type: "struct",
|
|
1798
|
+
name: "strkfarm_contracts::interfaces::IVesu::IStonDispatcher",
|
|
1799
|
+
members: [
|
|
1800
|
+
{
|
|
1801
|
+
name: "contract_address",
|
|
1802
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1803
|
+
}
|
|
1804
|
+
]
|
|
1805
|
+
},
|
|
1806
|
+
{
|
|
1807
|
+
type: "struct",
|
|
1808
|
+
name: "strkfarm_contracts::components::vesu::vesuStruct",
|
|
1809
|
+
members: [
|
|
1810
|
+
{
|
|
1811
|
+
name: "singleton",
|
|
1812
|
+
type: "strkfarm_contracts::interfaces::IVesu::IStonDispatcher"
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
name: "pool_id",
|
|
1816
|
+
type: "core::felt252"
|
|
1817
|
+
},
|
|
1818
|
+
{
|
|
1819
|
+
name: "debt",
|
|
1820
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1821
|
+
},
|
|
1822
|
+
{
|
|
1823
|
+
name: "col",
|
|
1824
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1825
|
+
},
|
|
1826
|
+
{
|
|
1827
|
+
name: "oracle",
|
|
1828
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1829
|
+
}
|
|
1830
|
+
]
|
|
1831
|
+
},
|
|
1832
|
+
{
|
|
1833
|
+
type: "constructor",
|
|
1834
|
+
name: "constructor",
|
|
1835
|
+
inputs: [
|
|
1836
|
+
{
|
|
1837
|
+
name: "asset",
|
|
1838
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
name: "access_control",
|
|
1842
|
+
type: "core::starknet::contract_address::ContractAddress"
|
|
1843
|
+
},
|
|
1844
|
+
{
|
|
1845
|
+
name: "allowed_pools",
|
|
1846
|
+
type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps>"
|
|
1847
|
+
},
|
|
1848
|
+
{
|
|
1849
|
+
name: "settings",
|
|
1850
|
+
type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings"
|
|
1851
|
+
},
|
|
1852
|
+
{
|
|
1853
|
+
name: "vesu_settings",
|
|
1854
|
+
type: "strkfarm_contracts::components::vesu::vesuStruct"
|
|
1855
|
+
}
|
|
1856
|
+
]
|
|
1857
|
+
},
|
|
1858
|
+
{
|
|
1859
|
+
type: "event",
|
|
1860
|
+
name: "openzeppelin_security::reentrancyguard::ReentrancyGuardComponent::Event",
|
|
1861
|
+
kind: "enum",
|
|
1862
|
+
variants: []
|
|
1863
|
+
},
|
|
1864
|
+
{
|
|
1865
|
+
type: "event",
|
|
1866
|
+
name: "strkfarm_contracts::components::erc4626::ERC4626Component::Deposit",
|
|
1867
|
+
kind: "struct",
|
|
1868
|
+
members: [
|
|
1869
|
+
{
|
|
1870
|
+
name: "sender",
|
|
1871
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
1872
|
+
kind: "key"
|
|
1873
|
+
},
|
|
1874
|
+
{
|
|
1875
|
+
name: "owner",
|
|
1876
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
1877
|
+
kind: "key"
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
name: "assets",
|
|
1881
|
+
type: "core::integer::u256",
|
|
1882
|
+
kind: "data"
|
|
1883
|
+
},
|
|
1884
|
+
{
|
|
1885
|
+
name: "shares",
|
|
1886
|
+
type: "core::integer::u256",
|
|
1887
|
+
kind: "data"
|
|
1888
|
+
}
|
|
1889
|
+
]
|
|
1890
|
+
},
|
|
1891
|
+
{
|
|
1892
|
+
type: "event",
|
|
1893
|
+
name: "strkfarm_contracts::components::erc4626::ERC4626Component::Withdraw",
|
|
1894
|
+
kind: "struct",
|
|
1895
|
+
members: [
|
|
1896
|
+
{
|
|
1897
|
+
name: "sender",
|
|
1898
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
1899
|
+
kind: "key"
|
|
1900
|
+
},
|
|
1901
|
+
{
|
|
1902
|
+
name: "receiver",
|
|
1903
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
1904
|
+
kind: "key"
|
|
1905
|
+
},
|
|
1906
|
+
{
|
|
1907
|
+
name: "owner",
|
|
1908
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
1909
|
+
kind: "key"
|
|
1910
|
+
},
|
|
1911
|
+
{
|
|
1912
|
+
name: "assets",
|
|
1913
|
+
type: "core::integer::u256",
|
|
1914
|
+
kind: "data"
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
name: "shares",
|
|
1918
|
+
type: "core::integer::u256",
|
|
1919
|
+
kind: "data"
|
|
1920
|
+
}
|
|
1921
|
+
]
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
type: "event",
|
|
1925
|
+
name: "strkfarm_contracts::components::erc4626::ERC4626Component::Event",
|
|
1926
|
+
kind: "enum",
|
|
1927
|
+
variants: [
|
|
1928
|
+
{
|
|
1929
|
+
name: "Deposit",
|
|
1930
|
+
type: "strkfarm_contracts::components::erc4626::ERC4626Component::Deposit",
|
|
1931
|
+
kind: "nested"
|
|
1932
|
+
},
|
|
1933
|
+
{
|
|
1934
|
+
name: "Withdraw",
|
|
1935
|
+
type: "strkfarm_contracts::components::erc4626::ERC4626Component::Withdraw",
|
|
1936
|
+
kind: "nested"
|
|
1937
|
+
}
|
|
1938
|
+
]
|
|
1939
|
+
},
|
|
1940
|
+
{
|
|
1941
|
+
type: "event",
|
|
1942
|
+
name: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Rewards",
|
|
1943
|
+
kind: "struct",
|
|
1944
|
+
members: [
|
|
1945
|
+
{
|
|
1946
|
+
name: "index",
|
|
1947
|
+
type: "core::integer::u32",
|
|
1948
|
+
kind: "data"
|
|
1949
|
+
},
|
|
1950
|
+
{
|
|
1951
|
+
name: "info",
|
|
1952
|
+
type: "strkfarm_contracts::components::harvester::reward_shares::RewardsInfo",
|
|
1953
|
+
kind: "data"
|
|
1954
|
+
},
|
|
1955
|
+
{
|
|
1956
|
+
name: "total_reward_shares",
|
|
1957
|
+
type: "core::integer::u128",
|
|
1958
|
+
kind: "data"
|
|
1959
|
+
},
|
|
1960
|
+
{
|
|
1961
|
+
name: "timestamp",
|
|
1962
|
+
type: "core::integer::u64",
|
|
1963
|
+
kind: "data"
|
|
1964
|
+
}
|
|
1965
|
+
]
|
|
1966
|
+
},
|
|
1967
|
+
{
|
|
1968
|
+
type: "event",
|
|
1969
|
+
name: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::UserRewards",
|
|
1970
|
+
kind: "struct",
|
|
1971
|
+
members: [
|
|
1972
|
+
{
|
|
1973
|
+
name: "user",
|
|
1974
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
1975
|
+
kind: "key"
|
|
1976
|
+
},
|
|
1977
|
+
{
|
|
1978
|
+
name: "info",
|
|
1979
|
+
type: "strkfarm_contracts::components::harvester::reward_shares::UserRewardsInfo",
|
|
1980
|
+
kind: "data"
|
|
1981
|
+
},
|
|
1982
|
+
{
|
|
1983
|
+
name: "total_reward_shares",
|
|
1984
|
+
type: "core::integer::u128",
|
|
1985
|
+
kind: "data"
|
|
1986
|
+
},
|
|
1987
|
+
{
|
|
1988
|
+
name: "timestamp",
|
|
1989
|
+
type: "core::integer::u64",
|
|
1990
|
+
kind: "data"
|
|
1991
|
+
}
|
|
1992
|
+
]
|
|
1993
|
+
},
|
|
1994
|
+
{
|
|
1995
|
+
type: "event",
|
|
1996
|
+
name: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Event",
|
|
1997
|
+
kind: "enum",
|
|
1998
|
+
variants: [
|
|
1999
|
+
{
|
|
2000
|
+
name: "Rewards",
|
|
2001
|
+
type: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Rewards",
|
|
2002
|
+
kind: "nested"
|
|
2003
|
+
},
|
|
2004
|
+
{
|
|
2005
|
+
name: "UserRewards",
|
|
2006
|
+
type: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::UserRewards",
|
|
2007
|
+
kind: "nested"
|
|
2008
|
+
}
|
|
2009
|
+
]
|
|
2010
|
+
},
|
|
2011
|
+
{
|
|
2012
|
+
type: "event",
|
|
2013
|
+
name: "openzeppelin_token::erc20::erc20::ERC20Component::Transfer",
|
|
2014
|
+
kind: "struct",
|
|
2015
|
+
members: [
|
|
2016
|
+
{
|
|
2017
|
+
name: "from",
|
|
2018
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
2019
|
+
kind: "key"
|
|
2020
|
+
},
|
|
2021
|
+
{
|
|
2022
|
+
name: "to",
|
|
2023
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
2024
|
+
kind: "key"
|
|
2025
|
+
},
|
|
2026
|
+
{
|
|
2027
|
+
name: "value",
|
|
2028
|
+
type: "core::integer::u256",
|
|
2029
|
+
kind: "data"
|
|
2030
|
+
}
|
|
2031
|
+
]
|
|
2032
|
+
},
|
|
2033
|
+
{
|
|
2034
|
+
type: "event",
|
|
2035
|
+
name: "openzeppelin_token::erc20::erc20::ERC20Component::Approval",
|
|
2036
|
+
kind: "struct",
|
|
2037
|
+
members: [
|
|
2038
|
+
{
|
|
2039
|
+
name: "owner",
|
|
2040
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
2041
|
+
kind: "key"
|
|
2042
|
+
},
|
|
2043
|
+
{
|
|
2044
|
+
name: "spender",
|
|
2045
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
2046
|
+
kind: "key"
|
|
2047
|
+
},
|
|
2048
|
+
{
|
|
2049
|
+
name: "value",
|
|
2050
|
+
type: "core::integer::u256",
|
|
2051
|
+
kind: "data"
|
|
2052
|
+
}
|
|
2053
|
+
]
|
|
2054
|
+
},
|
|
2055
|
+
{
|
|
2056
|
+
type: "event",
|
|
2057
|
+
name: "openzeppelin_token::erc20::erc20::ERC20Component::Event",
|
|
2058
|
+
kind: "enum",
|
|
2059
|
+
variants: [
|
|
2060
|
+
{
|
|
2061
|
+
name: "Transfer",
|
|
2062
|
+
type: "openzeppelin_token::erc20::erc20::ERC20Component::Transfer",
|
|
2063
|
+
kind: "nested"
|
|
2064
|
+
},
|
|
2065
|
+
{
|
|
2066
|
+
name: "Approval",
|
|
2067
|
+
type: "openzeppelin_token::erc20::erc20::ERC20Component::Approval",
|
|
2068
|
+
kind: "nested"
|
|
2069
|
+
}
|
|
2070
|
+
]
|
|
2071
|
+
},
|
|
2072
|
+
{
|
|
2073
|
+
type: "event",
|
|
2074
|
+
name: "openzeppelin_introspection::src5::SRC5Component::Event",
|
|
2075
|
+
kind: "enum",
|
|
2076
|
+
variants: []
|
|
2077
|
+
},
|
|
2078
|
+
{
|
|
2079
|
+
type: "event",
|
|
2080
|
+
name: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded",
|
|
2081
|
+
kind: "struct",
|
|
2082
|
+
members: [
|
|
2083
|
+
{
|
|
2084
|
+
name: "class_hash",
|
|
2085
|
+
type: "core::starknet::class_hash::ClassHash",
|
|
2086
|
+
kind: "data"
|
|
2087
|
+
}
|
|
2088
|
+
]
|
|
2089
|
+
},
|
|
2090
|
+
{
|
|
2091
|
+
type: "event",
|
|
2092
|
+
name: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event",
|
|
2093
|
+
kind: "enum",
|
|
2094
|
+
variants: [
|
|
2095
|
+
{
|
|
2096
|
+
name: "Upgraded",
|
|
2097
|
+
type: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded",
|
|
2098
|
+
kind: "nested"
|
|
2099
|
+
}
|
|
2100
|
+
]
|
|
2101
|
+
},
|
|
2102
|
+
{
|
|
2103
|
+
type: "event",
|
|
2104
|
+
name: "openzeppelin_security::pausable::PausableComponent::Paused",
|
|
2105
|
+
kind: "struct",
|
|
2106
|
+
members: [
|
|
2107
|
+
{
|
|
2108
|
+
name: "account",
|
|
2109
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
2110
|
+
kind: "data"
|
|
2111
|
+
}
|
|
2112
|
+
]
|
|
2113
|
+
},
|
|
2114
|
+
{
|
|
2115
|
+
type: "event",
|
|
2116
|
+
name: "openzeppelin_security::pausable::PausableComponent::Unpaused",
|
|
2117
|
+
kind: "struct",
|
|
2118
|
+
members: [
|
|
2119
|
+
{
|
|
2120
|
+
name: "account",
|
|
2121
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
2122
|
+
kind: "data"
|
|
2123
|
+
}
|
|
2124
|
+
]
|
|
2125
|
+
},
|
|
2126
|
+
{
|
|
2127
|
+
type: "event",
|
|
2128
|
+
name: "openzeppelin_security::pausable::PausableComponent::Event",
|
|
2129
|
+
kind: "enum",
|
|
2130
|
+
variants: [
|
|
2131
|
+
{
|
|
2132
|
+
name: "Paused",
|
|
2133
|
+
type: "openzeppelin_security::pausable::PausableComponent::Paused",
|
|
2134
|
+
kind: "nested"
|
|
2135
|
+
},
|
|
2136
|
+
{
|
|
2137
|
+
name: "Unpaused",
|
|
2138
|
+
type: "openzeppelin_security::pausable::PausableComponent::Unpaused",
|
|
2139
|
+
kind: "nested"
|
|
2140
|
+
}
|
|
2141
|
+
]
|
|
2142
|
+
},
|
|
2143
|
+
{
|
|
2144
|
+
type: "event",
|
|
2145
|
+
name: "strkfarm_contracts::components::common::CommonComp::Event",
|
|
2146
|
+
kind: "enum",
|
|
2147
|
+
variants: []
|
|
2148
|
+
},
|
|
2149
|
+
{
|
|
2150
|
+
type: "event",
|
|
2151
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::Rebalance",
|
|
2152
|
+
kind: "struct",
|
|
2153
|
+
members: [
|
|
2154
|
+
{
|
|
2155
|
+
name: "yield_before",
|
|
2156
|
+
type: "core::integer::u128",
|
|
2157
|
+
kind: "data"
|
|
2158
|
+
},
|
|
2159
|
+
{
|
|
2160
|
+
name: "yield_after",
|
|
2161
|
+
type: "core::integer::u128",
|
|
2162
|
+
kind: "data"
|
|
2163
|
+
}
|
|
2164
|
+
]
|
|
2165
|
+
},
|
|
2166
|
+
{
|
|
2167
|
+
type: "event",
|
|
2168
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::CollectFees",
|
|
2169
|
+
kind: "struct",
|
|
2170
|
+
members: [
|
|
2171
|
+
{
|
|
2172
|
+
name: "fee_collected",
|
|
2173
|
+
type: "core::integer::u128",
|
|
2174
|
+
kind: "data"
|
|
2175
|
+
},
|
|
2176
|
+
{
|
|
2177
|
+
name: "fee_collector",
|
|
2178
|
+
type: "core::starknet::contract_address::ContractAddress",
|
|
2179
|
+
kind: "data"
|
|
2180
|
+
}
|
|
2181
|
+
]
|
|
2182
|
+
},
|
|
2183
|
+
{
|
|
2184
|
+
type: "event",
|
|
2185
|
+
name: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::Event",
|
|
2186
|
+
kind: "enum",
|
|
2187
|
+
variants: [
|
|
2188
|
+
{
|
|
2189
|
+
name: "ReentrancyGuardEvent",
|
|
2190
|
+
type: "openzeppelin_security::reentrancyguard::ReentrancyGuardComponent::Event",
|
|
2191
|
+
kind: "flat"
|
|
2192
|
+
},
|
|
2193
|
+
{
|
|
2194
|
+
name: "ERC4626Event",
|
|
2195
|
+
type: "strkfarm_contracts::components::erc4626::ERC4626Component::Event",
|
|
2196
|
+
kind: "flat"
|
|
2197
|
+
},
|
|
2198
|
+
{
|
|
2199
|
+
name: "RewardShareEvent",
|
|
2200
|
+
type: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Event",
|
|
2201
|
+
kind: "flat"
|
|
2202
|
+
},
|
|
2203
|
+
{
|
|
2204
|
+
name: "ERC20Event",
|
|
2205
|
+
type: "openzeppelin_token::erc20::erc20::ERC20Component::Event",
|
|
2206
|
+
kind: "flat"
|
|
2207
|
+
},
|
|
2208
|
+
{
|
|
2209
|
+
name: "SRC5Event",
|
|
2210
|
+
type: "openzeppelin_introspection::src5::SRC5Component::Event",
|
|
2211
|
+
kind: "flat"
|
|
2212
|
+
},
|
|
2213
|
+
{
|
|
2214
|
+
name: "UpgradeableEvent",
|
|
2215
|
+
type: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event",
|
|
2216
|
+
kind: "flat"
|
|
2217
|
+
},
|
|
2218
|
+
{
|
|
2219
|
+
name: "PausableEvent",
|
|
2220
|
+
type: "openzeppelin_security::pausable::PausableComponent::Event",
|
|
2221
|
+
kind: "flat"
|
|
2222
|
+
},
|
|
2223
|
+
{
|
|
2224
|
+
name: "CommonCompEvent",
|
|
2225
|
+
type: "strkfarm_contracts::components::common::CommonComp::Event",
|
|
2226
|
+
kind: "flat"
|
|
2227
|
+
},
|
|
2228
|
+
{
|
|
2229
|
+
name: "Rebalance",
|
|
2230
|
+
type: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::Rebalance",
|
|
2231
|
+
kind: "nested"
|
|
2232
|
+
},
|
|
2233
|
+
{
|
|
2234
|
+
name: "CollectFees",
|
|
2235
|
+
type: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::CollectFees",
|
|
2236
|
+
kind: "nested"
|
|
2237
|
+
}
|
|
2238
|
+
]
|
|
2239
|
+
}
|
|
2240
|
+
];
|
|
2241
|
+
|
|
2242
|
+
// src/utils/index.ts
|
|
2243
|
+
function assert(condition, message) {
|
|
2244
|
+
if (!condition) {
|
|
2245
|
+
throw new Error(message);
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
// src/strategies/vesu-rebalance.ts
|
|
2250
|
+
import axios5 from "axios";
|
|
2251
|
+
var VesuRebalance = class _VesuRebalance {
|
|
2252
|
+
// 10000 bps = 100%
|
|
2253
|
+
/**
|
|
2254
|
+
* Creates a new VesuRebalance strategy instance.
|
|
2255
|
+
* @param config - Configuration object containing provider and other settings
|
|
2256
|
+
* @param pricer - Pricer instance for token price calculations
|
|
2257
|
+
* @param metadata - Strategy metadata including deposit tokens and address
|
|
2258
|
+
* @throws {Error} If more than one deposit token is specified
|
|
2259
|
+
*/
|
|
2260
|
+
constructor(config, pricer, metadata) {
|
|
2261
|
+
this.BASE_WEIGHT = 1e4;
|
|
2262
|
+
this.config = config;
|
|
2263
|
+
this.pricer = pricer;
|
|
2264
|
+
assert(metadata.depositTokens.length === 1, "VesuRebalance only supports 1 deposit token");
|
|
2265
|
+
this.metadata = metadata;
|
|
2266
|
+
this.address = metadata.address;
|
|
2267
|
+
this.contract = new Contract3(vesu_rebalance_abi_default, this.address.address, this.config.provider);
|
|
2268
|
+
}
|
|
2269
|
+
/**
|
|
2270
|
+
* Creates a deposit call to the strategy contract.
|
|
2271
|
+
* @param assets - Amount of assets to deposit
|
|
2272
|
+
* @param receiver - Address that will receive the strategy tokens
|
|
2273
|
+
* @returns Populated contract call for deposit
|
|
2274
|
+
*/
|
|
2275
|
+
depositCall(assets, receiver) {
|
|
2276
|
+
const assetContract = new Contract3(vesu_rebalance_abi_default, this.metadata.depositTokens[0].address, this.config.provider);
|
|
2277
|
+
const call1 = assetContract.populate("approve", [this.address.address, uint2562.bnToUint256(assets.toWei())]);
|
|
2278
|
+
const call2 = this.contract.populate("deposit", [uint2562.bnToUint256(assets.toWei()), receiver.address]);
|
|
2279
|
+
return [call1, call2];
|
|
2280
|
+
}
|
|
2281
|
+
/**
|
|
2282
|
+
* Creates a withdrawal call to the strategy contract.
|
|
2283
|
+
* @param assets - Amount of assets to withdraw
|
|
2284
|
+
* @param receiver - Address that will receive the withdrawn assets
|
|
2285
|
+
* @param owner - Address that owns the strategy tokens
|
|
2286
|
+
* @returns Populated contract call for withdrawal
|
|
2287
|
+
*/
|
|
2288
|
+
withdrawCall(assets, receiver, owner) {
|
|
2289
|
+
return [this.contract.populate("withdraw", [uint2562.bnToUint256(assets.toWei()), receiver.address, owner.address])];
|
|
2290
|
+
}
|
|
2291
|
+
/**
|
|
2292
|
+
* Returns the underlying asset token of the strategy.
|
|
2293
|
+
* @returns The deposit token supported by this strategy
|
|
2294
|
+
*/
|
|
2295
|
+
asset() {
|
|
2296
|
+
return this.metadata.depositTokens[0];
|
|
2297
|
+
}
|
|
2298
|
+
/**
|
|
2299
|
+
* Returns the number of decimals used by the strategy token.
|
|
2300
|
+
* @returns Number of decimals (same as the underlying token)
|
|
2301
|
+
*/
|
|
2302
|
+
decimals() {
|
|
2303
|
+
return this.metadata.depositTokens[0].decimals;
|
|
2304
|
+
}
|
|
2305
|
+
/**
|
|
2306
|
+
* Calculates the Total Value Locked (TVL) for a specific user.
|
|
2307
|
+
* @param user - Address of the user
|
|
2308
|
+
* @returns Object containing the amount in token units and USD value
|
|
2309
|
+
*/
|
|
2310
|
+
async getUserTVL(user) {
|
|
2311
|
+
const shares = await this.contract.balanceOf(user.address);
|
|
2312
|
+
const assets = await this.contract.convert_to_assets(uint2562.bnToUint256(shares));
|
|
2313
|
+
const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
|
|
2314
|
+
let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
|
|
2315
|
+
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
2316
|
+
return {
|
|
2317
|
+
amount,
|
|
2318
|
+
usdValue
|
|
2319
|
+
};
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Calculates the total TVL of the strategy.
|
|
2323
|
+
* @returns Object containing the total amount in token units and USD value
|
|
2324
|
+
*/
|
|
2325
|
+
async getTVL() {
|
|
2326
|
+
const assets = await this.contract.total_assets();
|
|
2327
|
+
const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
|
|
2328
|
+
let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
|
|
2329
|
+
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
2330
|
+
return {
|
|
2331
|
+
amount,
|
|
2332
|
+
usdValue
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
/**
|
|
2336
|
+
* Retrieves the list of allowed pools and their detailed information from multiple sources:
|
|
2337
|
+
* 1. Contract's allowed pools
|
|
2338
|
+
* 2. Vesu positions API for current positions
|
|
2339
|
+
* 3. Vesu pools API for APY and utilization data
|
|
2340
|
+
*
|
|
2341
|
+
* @returns {Promise<{
|
|
2342
|
+
* data: Array<PoolInfoFull>,
|
|
2343
|
+
* isErrorPositionsAPI: boolean
|
|
2344
|
+
* }>} Object containing:
|
|
2345
|
+
* - data: Array of pool information including IDs, weights, amounts, APYs and utilization
|
|
2346
|
+
* - isErrorPositionsAPI: Boolean indicating if there was an error fetching position data
|
|
2347
|
+
*/
|
|
2348
|
+
async getPools() {
|
|
2349
|
+
const allowedPools = (await this.contract.get_allowed_pools()).map((p) => ({
|
|
2350
|
+
pool_id: ContractAddr.from(p.pool_id),
|
|
2351
|
+
max_weight: Number(p.max_weight) / this.BASE_WEIGHT,
|
|
2352
|
+
v_token: ContractAddr.from(p.v_token)
|
|
2353
|
+
}));
|
|
2354
|
+
let isErrorPositionsAPI = false;
|
|
2355
|
+
let vesuPositions = [];
|
|
2356
|
+
try {
|
|
2357
|
+
const res = await axios5.get(`https://api.vesu.xyz/positions?walletAddress=${this.address.address}`);
|
|
2358
|
+
const data2 = await res.data;
|
|
2359
|
+
vesuPositions = data2.data;
|
|
2360
|
+
} catch (e) {
|
|
2361
|
+
console.error(`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}`, e);
|
|
2362
|
+
isErrorPositionsAPI = true;
|
|
2363
|
+
}
|
|
2364
|
+
let isErrorPoolsAPI = false;
|
|
2365
|
+
let pools = [];
|
|
2366
|
+
try {
|
|
2367
|
+
const res = await axios5.get(`https://api.vesu.xyz/pools`);
|
|
2368
|
+
const data2 = await res.data;
|
|
2369
|
+
pools = data2.data;
|
|
2370
|
+
} catch (e) {
|
|
2371
|
+
console.error(`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}`, e);
|
|
2372
|
+
isErrorPoolsAPI = true;
|
|
2373
|
+
}
|
|
2374
|
+
const totalAssets = (await this.getTVL()).amount;
|
|
2375
|
+
const info = allowedPools.map(async (p) => {
|
|
2376
|
+
const vesuPosition = vesuPositions.find((d) => d.pool.id.toString() === num2.getDecimalString(p.pool_id.address.toString()));
|
|
2377
|
+
const pool = pools.find((d) => d.id == num2.getDecimalString(p.pool_id.address));
|
|
2378
|
+
const assetInfo = pool?.assets.find((d) => ContractAddr.from(this.asset().address).eqString(d.address));
|
|
2379
|
+
let vTokenContract = new Contract3(vesu_rebalance_abi_default, p.v_token.address, this.config.provider);
|
|
2380
|
+
const bal = await vTokenContract.balanceOf(this.address.address);
|
|
2381
|
+
const assets = await vTokenContract.convert_to_assets(uint2562.bnToUint256(bal.toString()));
|
|
2382
|
+
const item = {
|
|
2383
|
+
pool_id: p.pool_id,
|
|
2384
|
+
pool_name: pool.name,
|
|
2385
|
+
max_weight: p.max_weight,
|
|
2386
|
+
current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)),
|
|
2387
|
+
v_token: p.v_token,
|
|
2388
|
+
amount: Web3Number.fromWei(assets.toString(), this.decimals()),
|
|
2389
|
+
usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(vesuPosition.collateral.usdPrice.value, vesuPosition.collateral.usdPrice.decimals),
|
|
2390
|
+
APY: isErrorPoolsAPI || !assetInfo ? {
|
|
2391
|
+
baseApy: 0,
|
|
2392
|
+
defiSpringApy: 0,
|
|
2393
|
+
netApy: 0
|
|
2394
|
+
} : {
|
|
2395
|
+
baseApy: Number(Web3Number.fromWei(assetInfo.stats.supplyApy.value, assetInfo.stats.supplyApy.decimals).toFixed(6)),
|
|
2396
|
+
defiSpringApy: Number(Web3Number.fromWei(assetInfo.stats.defiSpringSupplyApr.value, assetInfo.stats.defiSpringSupplyApr.decimals).toFixed(6)),
|
|
2397
|
+
netApy: 0
|
|
2398
|
+
},
|
|
2399
|
+
currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.stats.currentUtilization.value, assetInfo.stats.currentUtilization.decimals).toFixed(6)),
|
|
2400
|
+
maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.config.maxUtilization.value, assetInfo.config.maxUtilization.decimals).toFixed(6))
|
|
2401
|
+
};
|
|
2402
|
+
item.APY.netApy = item.APY.baseApy + item.APY.defiSpringApy;
|
|
2403
|
+
return item;
|
|
2404
|
+
});
|
|
2405
|
+
const data = await Promise.all(info);
|
|
2406
|
+
return {
|
|
2407
|
+
data,
|
|
2408
|
+
isErrorPositionsAPI,
|
|
2409
|
+
isErrorPoolsAPI,
|
|
2410
|
+
isError: isErrorPositionsAPI || isErrorPoolsAPI
|
|
2411
|
+
};
|
|
2412
|
+
}
|
|
2413
|
+
/**
|
|
2414
|
+
* Calculates the weighted average APY across all pools based on USD value.
|
|
2415
|
+
* @returns {Promise<number>} The weighted average APY across all pools
|
|
2416
|
+
*/
|
|
2417
|
+
async netAPY() {
|
|
2418
|
+
const { data: pools } = await this.getPools();
|
|
2419
|
+
return this.netAPYGivenPools(pools);
|
|
2420
|
+
}
|
|
2421
|
+
/**
|
|
2422
|
+
* Calculates the weighted average APY across all pools based on USD value.
|
|
2423
|
+
* @returns {Promise<number>} The weighted average APY across all pools
|
|
2424
|
+
*/
|
|
2425
|
+
netAPYGivenPools(pools) {
|
|
2426
|
+
const weightedApy = pools.reduce((acc, curr) => {
|
|
2427
|
+
const weight = curr.current_weight;
|
|
2428
|
+
return acc + curr.APY.netApy * weight;
|
|
2429
|
+
}, 0);
|
|
2430
|
+
return weightedApy;
|
|
2431
|
+
}
|
|
2432
|
+
/**
|
|
2433
|
+
* Calculates optimal position changes to maximize APY while respecting max weights.
|
|
2434
|
+
* The algorithm:
|
|
2435
|
+
* 1. Sorts pools by APY (highest first)
|
|
2436
|
+
* 2. Calculates target amounts based on max weights
|
|
2437
|
+
* 3. For each pool that needs more funds:
|
|
2438
|
+
* - Takes funds from lowest APY pools that are over their target
|
|
2439
|
+
* 4. Validates that total assets remain constant
|
|
2440
|
+
*
|
|
2441
|
+
* @returns {Promise<{
|
|
2442
|
+
* changes: Change[],
|
|
2443
|
+
* finalPools: PoolInfoFull[],
|
|
2444
|
+
* isAnyPoolOverMaxWeight: boolean
|
|
2445
|
+
* }>} Object containing:
|
|
2446
|
+
* - changes: Array of position changes
|
|
2447
|
+
* - finalPools: Array of pool information after rebalance
|
|
2448
|
+
* @throws Error if rebalance is not possible while maintaining constraints
|
|
2449
|
+
*/
|
|
2450
|
+
async getRebalancedPositions() {
|
|
2451
|
+
const { data: pools } = await this.getPools();
|
|
2452
|
+
const totalAssets = (await this.getTVL()).amount;
|
|
2453
|
+
if (totalAssets.eq(0)) return {
|
|
2454
|
+
changes: [],
|
|
2455
|
+
finalPools: []
|
|
2456
|
+
};
|
|
2457
|
+
const sumPools = pools.reduce((acc, curr) => acc.plus(curr.amount.toString()), Web3Number.fromWei("0", this.decimals()));
|
|
2458
|
+
assert(sumPools.lte(totalAssets), "Sum of pools.amount must be less than or equal to totalAssets");
|
|
2459
|
+
const sortedPools = [...pools].sort((a, b) => b.APY.netApy - a.APY.netApy);
|
|
2460
|
+
const targetAmounts = {};
|
|
2461
|
+
let remainingAssets = totalAssets;
|
|
2462
|
+
let isAnyPoolOverMaxWeight = false;
|
|
2463
|
+
for (const pool of sortedPools) {
|
|
2464
|
+
const maxAmount = totalAssets.multipliedBy(pool.max_weight * 0.9);
|
|
2465
|
+
const targetAmount = remainingAssets.gte(maxAmount) ? maxAmount : remainingAssets;
|
|
2466
|
+
targetAmounts[pool.pool_id.address.toString()] = targetAmount;
|
|
2467
|
+
remainingAssets = remainingAssets.minus(targetAmount.toString());
|
|
2468
|
+
if (pool.current_weight > pool.max_weight) {
|
|
2469
|
+
isAnyPoolOverMaxWeight = true;
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
assert(remainingAssets.lt(1e-5), "Remaining assets must be 0");
|
|
2473
|
+
const changes = sortedPools.map((pool) => {
|
|
2474
|
+
const target = targetAmounts[pool.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
|
|
2475
|
+
const change = Web3Number.fromWei(target.minus(pool.amount.toString()).toWei(), this.decimals());
|
|
2476
|
+
return {
|
|
2477
|
+
pool_id: pool.pool_id,
|
|
2478
|
+
changeAmt: change,
|
|
2479
|
+
finalAmt: target,
|
|
2480
|
+
isDeposit: change.gt(0)
|
|
2481
|
+
};
|
|
2482
|
+
});
|
|
2483
|
+
const sumChanges = changes.reduce((sum, c) => sum.plus(c.changeAmt.toString()), Web3Number.fromWei("0", this.decimals()));
|
|
2484
|
+
const sumFinal = changes.reduce((sum, c) => sum.plus(c.finalAmt.toString()), Web3Number.fromWei("0", this.decimals()));
|
|
2485
|
+
const hasChanges = changes.some((c) => !c.changeAmt.eq(0));
|
|
2486
|
+
if (!sumChanges.eq(0)) throw new Error("Sum of changes must be zero");
|
|
2487
|
+
if (!sumFinal.eq(totalAssets)) throw new Error("Sum of final amounts must equal total assets");
|
|
2488
|
+
if (!hasChanges) throw new Error("No changes required");
|
|
2489
|
+
const finalPools = pools.map((p) => {
|
|
2490
|
+
const target = targetAmounts[p.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
|
|
2491
|
+
return {
|
|
2492
|
+
...p,
|
|
2493
|
+
amount: target,
|
|
2494
|
+
usdValue: Web3Number.fromWei("0", this.decimals())
|
|
2495
|
+
};
|
|
2496
|
+
});
|
|
2497
|
+
return {
|
|
2498
|
+
changes,
|
|
2499
|
+
finalPools,
|
|
2500
|
+
isAnyPoolOverMaxWeight
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
/**
|
|
2504
|
+
* Creates a rebalance Call object for the strategy contract
|
|
2505
|
+
* @param pools - Array of pool information including IDs, weights, amounts, APYs and utilization
|
|
2506
|
+
* @returns Populated contract call for rebalance
|
|
2507
|
+
*/
|
|
2508
|
+
async getRebalanceCall(pools, isOverWeightAdjustment) {
|
|
2509
|
+
const actions = [];
|
|
2510
|
+
pools.sort((a, b) => b.isDeposit ? -1 : 1);
|
|
2511
|
+
console.log("pools", pools);
|
|
2512
|
+
pools.forEach((p) => {
|
|
2513
|
+
if (p.changeAmt.eq(0)) return null;
|
|
2514
|
+
actions.push({
|
|
2515
|
+
pool_id: p.pool_id.address,
|
|
2516
|
+
feature: new CairoCustomEnum(p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }),
|
|
2517
|
+
token: this.asset().address,
|
|
2518
|
+
amount: uint2562.bnToUint256(p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei())
|
|
2519
|
+
});
|
|
2520
|
+
});
|
|
2521
|
+
if (actions.length === 0) return null;
|
|
2522
|
+
if (isOverWeightAdjustment) {
|
|
2523
|
+
return this.contract.populate("rebalance_weights", [actions]);
|
|
2524
|
+
}
|
|
2525
|
+
return this.contract.populate("rebalance", [actions]);
|
|
2526
|
+
}
|
|
2527
|
+
async getInvestmentFlows(pools) {
|
|
2528
|
+
const netYield = this.netAPYGivenPools(pools);
|
|
2529
|
+
const baseFlow = {
|
|
2530
|
+
title: "Your Deposit",
|
|
2531
|
+
subItems: [{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` }],
|
|
2532
|
+
linkedFlows: [],
|
|
2533
|
+
style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
|
|
2534
|
+
};
|
|
2535
|
+
let _pools = [...pools];
|
|
2536
|
+
_pools = _pools.sort((a, b) => Number(b.amount.toString()) - Number(a.amount.toString()));
|
|
2537
|
+
_pools.forEach((p) => {
|
|
2538
|
+
const flow = {
|
|
2539
|
+
title: `Pool name: ${p.pool_name}`,
|
|
2540
|
+
subItems: [
|
|
2541
|
+
{ key: `APY`, value: `${(p.APY.netApy * 100).toFixed(2)}%` },
|
|
2542
|
+
{ key: "Weight", value: `${(p.current_weight * 100).toFixed(2)} / ${(p.max_weight * 100).toFixed(2)}%` }
|
|
2543
|
+
],
|
|
2544
|
+
linkedFlows: [],
|
|
2545
|
+
style: p.amount.greaterThan(0) ? { backgroundColor: "#35484f" /* Blue */.valueOf() } : { color: "gray" }
|
|
2546
|
+
};
|
|
2547
|
+
baseFlow.linkedFlows.push(flow);
|
|
2548
|
+
});
|
|
2549
|
+
return [baseFlow];
|
|
2550
|
+
}
|
|
2551
|
+
};
|
|
2552
|
+
var _description = "Automatically diversify {{TOKEN}} holdings into different Vesu pools while reducing risk and maximizing yield. Defi spring STRK Rewards are auto-compounded as well.";
|
|
2553
|
+
var _protocol = { name: "Vesu", logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png" };
|
|
2554
|
+
var _riskFactor = [
|
|
2555
|
+
{ type: "SMART_CONTRACT_RISK" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
|
|
2556
|
+
{ type: "TECHNICAL_RISK" /* TECHNICAL_RISK */, value: 0.5, weight: 25 },
|
|
2557
|
+
{ type: "COUNTERPARTY_RISK" /* COUNTERPARTY_RISK */, value: 1, weight: 50 }
|
|
2558
|
+
];
|
|
2559
|
+
var VesuRebalanceStrategies = [{
|
|
2560
|
+
name: "Vesu STRK",
|
|
2561
|
+
description: _description.replace("{{TOKEN}}", "STRK"),
|
|
2562
|
+
address: ContractAddr.from("0xeeb729d554ae486387147b13a9c8871bc7991d454e8b5ff570d4bf94de71e1"),
|
|
2563
|
+
type: "ERC4626",
|
|
2564
|
+
depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "STRK")],
|
|
2565
|
+
protocols: [_protocol],
|
|
2566
|
+
maxTVL: Web3Number.fromWei("0", 18),
|
|
2567
|
+
risk: {
|
|
2568
|
+
riskFactor: _riskFactor,
|
|
2569
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / 100
|
|
2570
|
+
}
|
|
2571
|
+
}];
|
|
2572
|
+
export {
|
|
2573
|
+
AutoCompounderSTRK,
|
|
2574
|
+
ContractAddr,
|
|
2575
|
+
FatalError,
|
|
2576
|
+
FlowChartColors,
|
|
2577
|
+
Global,
|
|
2578
|
+
ILending,
|
|
2579
|
+
Initializable,
|
|
2580
|
+
MarginType,
|
|
2581
|
+
Network,
|
|
2582
|
+
Pragma,
|
|
2583
|
+
Pricer,
|
|
2584
|
+
PricerFromApi,
|
|
2585
|
+
RiskType,
|
|
2586
|
+
VesuRebalance,
|
|
2587
|
+
VesuRebalanceStrategies,
|
|
2588
|
+
Web3Number,
|
|
2589
|
+
ZkLend,
|
|
2590
|
+
getMainnetConfig,
|
|
2591
|
+
logger
|
|
2592
|
+
};
|