@strkfarm/sdk 1.0.14 → 1.0.16

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/index.js CHANGED
@@ -41,11 +41,15 @@ __export(src_exports, {
41
41
  PasswordJsonCryptoUtil: () => PasswordJsonCryptoUtil,
42
42
  Pragma: () => Pragma,
43
43
  Pricer: () => Pricer,
44
+ PricerBase: () => PricerBase,
44
45
  PricerRedis: () => PricerRedis,
45
46
  Store: () => Store,
46
47
  TelegramNotif: () => TelegramNotif,
48
+ VesuRebalance: () => VesuRebalance,
49
+ VesuRebalanceStrategies: () => VesuRebalanceStrategies,
47
50
  Web3Number: () => Web3Number,
48
51
  ZkLend: () => ZkLend,
52
+ assert: () => assert,
49
53
  getDefaultStoreConfig: () => getDefaultStoreConfig,
50
54
  getMainnetConfig: () => getMainnetConfig,
51
55
  logger: () => logger
@@ -72,7 +76,13 @@ var FatalError = class extends Error {
72
76
  this.name = "FatalError";
73
77
  }
74
78
  };
75
- var tokens = [];
79
+ var tokens = [{
80
+ name: "Starknet",
81
+ symbol: "STRK",
82
+ address: "0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
83
+ decimals: 18,
84
+ coingeckId: "starknet"
85
+ }];
76
86
  var Global = class {
77
87
  static fatalError(message, err) {
78
88
  logger.error(message);
@@ -85,6 +95,9 @@ var Global = class {
85
95
  logger.error(`${url}: ${message}`);
86
96
  console.error(err);
87
97
  }
98
+ static getDefaultTokens() {
99
+ return tokens;
100
+ }
88
101
  static async getTokens() {
89
102
  if (tokens.length) return tokens;
90
103
  const data = await import_axios.default.get("https://starknet.api.avnu.fi/v1/starknet/tokens");
@@ -126,10 +139,12 @@ var Web3Number = class _Web3Number extends import_bignumber.default {
126
139
  return this.mul(10 ** this.decimals).toFixed(0);
127
140
  }
128
141
  multipliedBy(value) {
129
- return new _Web3Number(this.mul(value).toString(), this.decimals);
142
+ let _value = Number(value).toFixed(6);
143
+ return new _Web3Number(this.mul(_value).toString(), this.decimals);
130
144
  }
131
145
  dividedBy(value) {
132
- return new _Web3Number(this.div(value).toString(), this.decimals);
146
+ let _value = Number(value).toFixed(6);
147
+ return new _Web3Number(this.div(_value).toString(), this.decimals);
133
148
  }
134
149
  plus(value) {
135
150
  return new _Web3Number(this.add(value).toString(), this.decimals);
@@ -177,6 +192,11 @@ var ContractAddr = class _ContractAddr {
177
192
 
178
193
  // src/modules/pricer.ts
179
194
  var CoinMarketCap = require("coinmarketcap-api");
195
+ var PricerBase = class {
196
+ async getPrice(tokenSymbol) {
197
+ throw new Error("Method not implemented");
198
+ }
199
+ };
180
200
  var Pricer = class {
181
201
  constructor(config, tokens2) {
182
202
  this.tokens = [];
@@ -235,10 +255,10 @@ var Pricer = class {
235
255
  assertNotStale(timestamp, tokenName) {
236
256
  Global.assert(!this.isStale(timestamp, tokenName), `Price of ${tokenName} is stale`);
237
257
  }
238
- async getPrice(tokenName) {
239
- Global.assert(this.prices[tokenName], `Price of ${tokenName} not found`);
240
- this.assertNotStale(this.prices[tokenName].timestamp, tokenName);
241
- return this.prices[tokenName];
258
+ async getPrice(tokenSymbol) {
259
+ Global.assert(this.prices[tokenSymbol], `Price of ${tokenSymbol} not found`);
260
+ this.assertNotStale(this.prices[tokenSymbol].timestamp, tokenSymbol);
261
+ return this.prices[tokenSymbol];
242
262
  }
243
263
  _loadPrices(onUpdate = () => {
244
264
  }) {
@@ -728,260 +748,1877 @@ var AutoCompounderSTRK = class {
728
748
  }
729
749
  };
730
750
 
731
- // src/notifs/telegram.ts
732
- var import_node_telegram_bot_api = __toESM(require("node-telegram-bot-api"));
733
- var TelegramNotif = class {
734
- constructor(token, shouldPoll) {
735
- this.subscribers = [
736
- // '6820228303',
737
- "1505578076",
738
- // '5434736198', // maaza
739
- "1356705582",
740
- // langs
741
- "1388729514",
742
- // hwashere
743
- "6020162572",
744
- //minato
745
- "985902592"
746
- ];
747
- this.bot = new import_node_telegram_bot_api.default(token, { polling: shouldPoll });
748
- }
749
- // listen to start msgs, register chatId and send registered msg
750
- activateChatBot() {
751
- this.bot.on("message", (msg) => {
752
- const chatId = msg.chat.id;
753
- let text = msg.text.toLowerCase().trim();
754
- logger.verbose(`Tg: IncomingMsg: ID: ${chatId}, msg: ${text}`);
755
- if (text == "start") {
756
- this.bot.sendMessage(chatId, "Registered");
757
- this.subscribers.push(chatId);
758
- logger.verbose(`Tg: New subscriber: ${chatId}`);
759
- } else {
760
- this.bot.sendMessage(chatId, "Unrecognized command. Supported commands: start");
761
- }
762
- });
763
- }
764
- // send a given msg to all registered users
765
- sendMessage(msg) {
766
- logger.verbose(`Tg: Sending message: ${msg}`);
767
- for (let chatId of this.subscribers) {
768
- this.bot.sendMessage(chatId, msg).catch((err) => {
769
- logger.error(`Tg: Error sending msg to ${chatId}`);
770
- logger.error(`Tg: Error sending message: ${err.message}`);
771
- }).then(() => {
772
- logger.verbose(`Tg: Message sent to ${chatId}`);
773
- });
774
- }
775
- }
776
- };
777
-
778
- // src/utils/store.ts
779
- var import_fs = __toESM(require("fs"));
751
+ // src/strategies/vesu-rebalance.ts
780
752
  var import_starknet5 = require("starknet");
781
- var crypto2 = __toESM(require("crypto"));
782
-
783
- // src/utils/encrypt.ts
784
- var crypto = __toESM(require("crypto"));
785
- var PasswordJsonCryptoUtil = class {
786
- constructor() {
787
- this.algorithm = "aes-256-gcm";
788
- this.keyLength = 32;
789
- // 256 bits
790
- this.saltLength = 16;
791
- // 128 bits
792
- this.ivLength = 12;
793
- // 96 bits for GCM
794
- this.tagLength = 16;
795
- // 128 bits
796
- this.pbkdf2Iterations = 1e5;
797
- }
798
- // Number of iterations for PBKDF2
799
- deriveKey(password, salt) {
800
- return crypto.pbkdf2Sync(password, salt, this.pbkdf2Iterations, this.keyLength, "sha256");
801
- }
802
- encrypt(data, password) {
803
- const jsonString = JSON.stringify(data);
804
- const salt = crypto.randomBytes(this.saltLength);
805
- const iv = crypto.randomBytes(this.ivLength);
806
- const key = this.deriveKey(password, salt);
807
- const cipher = crypto.createCipheriv(this.algorithm, key, iv, { authTagLength: this.tagLength });
808
- let encrypted = cipher.update(jsonString, "utf8", "hex");
809
- encrypted += cipher.final("hex");
810
- const tag = cipher.getAuthTag();
811
- return Buffer.concat([salt, iv, tag, Buffer.from(encrypted, "hex")]).toString("base64");
812
- }
813
- decrypt(encryptedData, password) {
814
- const data = Buffer.from(encryptedData, "base64");
815
- const salt = data.subarray(0, this.saltLength);
816
- const iv = data.subarray(this.saltLength, this.saltLength + this.ivLength);
817
- const tag = data.subarray(this.saltLength + this.ivLength, this.saltLength + this.ivLength + this.tagLength);
818
- const encrypted = data.subarray(this.saltLength + this.ivLength + this.tagLength);
819
- const key = this.deriveKey(password, salt);
820
- const decipher = crypto.createDecipheriv(this.algorithm, key, iv, { authTagLength: this.tagLength });
821
- decipher.setAuthTag(tag);
822
- try {
823
- let decrypted = decipher.update(encrypted.toString("hex"), "hex", "utf8");
824
- decrypted += decipher.final("utf8");
825
- return JSON.parse(decrypted);
826
- } catch (error) {
827
- throw new Error("Decryption failed. This could be due to an incorrect password or corrupted data.");
828
- }
829
- }
830
- };
831
-
832
- // src/utils/store.ts
833
- function getDefaultStoreConfig(network) {
834
- if (!process.env.HOME) {
835
- throw new Error("StoreConfig: HOME environment variable not found");
836
- }
837
- return {
838
- SECRET_FILE_FOLDER: `${process.env.HOME}/.starknet-store`,
839
- NETWORK: network,
840
- ACCOUNTS_FILE_NAME: "accounts.json",
841
- PASSWORD: crypto2.randomBytes(16).toString("hex")
842
- };
843
- }
844
- var Store = class _Store {
845
- constructor(config, storeConfig) {
846
- this.encryptor = new PasswordJsonCryptoUtil();
847
- this.config = config;
848
- const defaultStoreConfig = getDefaultStoreConfig(config.network);
849
- if (!storeConfig.PASSWORD) {
850
- _Store.logPassword(defaultStoreConfig.PASSWORD);
851
- }
852
- this.storeConfig = {
853
- ...defaultStoreConfig,
854
- ...storeConfig
855
- };
856
- _Store.ensureFolder(this.storeConfig.SECRET_FILE_FOLDER);
857
- }
858
- static logPassword(password) {
859
- logger.warn(`\u26A0\uFE0F=========================================\u26A0\uFE0F`);
860
- logger.warn(`Generated a random password for store`);
861
- logger.warn(`\u26A0\uFE0F Password: ${password}`);
862
- logger.warn(`This not stored anywhere, please you backup this password for future use`);
863
- logger.warn(`\u26A0\uFE0F=========================================\u26A0\uFE0F`);
864
- }
865
- getAccount(accountKey, txVersion = import_starknet5.constants.TRANSACTION_VERSION.V2) {
866
- const accounts = this.loadAccounts();
867
- logger.verbose(`nAccounts loaded for network: ${Object.keys(accounts).length}`);
868
- const data = accounts[accountKey];
869
- if (!data) {
870
- throw new Error(`Account not found: ${accountKey}`);
871
- }
872
- logger.verbose(`Account loaded: ${accountKey} from network: ${this.config.network}`);
873
- logger.verbose(`Address: ${data.address}`);
874
- const acc = new import_starknet5.Account(this.config.provider, data.address, data.pk, void 0, txVersion);
875
- return acc;
876
- }
877
- addAccount(accountKey, address, pk) {
878
- const allAccounts = this.getAllAccounts();
879
- if (!allAccounts[this.config.network]) {
880
- allAccounts[this.config.network] = {};
881
- }
882
- allAccounts[this.config.network][accountKey] = {
883
- address,
884
- pk
885
- };
886
- const encryptedData = this.encryptor.encrypt(allAccounts, this.storeConfig.PASSWORD);
887
- (0, import_fs.writeFileSync)(this.getAccountFilePath(), encryptedData);
888
- logger.verbose(`Account added: ${accountKey} to network: ${this.config.network}`);
889
- }
890
- getAccountFilePath() {
891
- const path = `${this.storeConfig.SECRET_FILE_FOLDER}/${this.storeConfig.ACCOUNTS_FILE_NAME}`;
892
- logger.verbose(`Path: ${path}`);
893
- return path;
894
- }
895
- getAllAccounts() {
896
- const PATH = this.getAccountFilePath();
897
- if (!import_fs.default.existsSync(PATH)) {
898
- logger.verbose(`Accounts: files doesnt exist`);
899
- return {};
900
- }
901
- let encryptedData = (0, import_fs.readFileSync)(PATH, {
902
- encoding: "utf-8"
903
- });
904
- let data = this.encryptor.decrypt(encryptedData, this.storeConfig.PASSWORD);
905
- return data;
906
- }
907
- /**
908
- * @description Load all accounts of the network
909
- * @returns NetworkAccounts
910
- */
911
- loadAccounts() {
912
- const allData = this.getAllAccounts();
913
- logger.verbose(`Accounts loaded for network: ${this.config.network}`);
914
- if (!allData[this.config.network]) {
915
- allData[this.config.network] = {};
916
- }
917
- return allData[this.config.network];
918
- }
919
- /**
920
- * @description List all accountKeys of the network
921
- * @returns string[]
922
- */
923
- listAccounts() {
924
- return Object.keys(this.loadAccounts());
925
- }
926
- static ensureFolder(folder) {
927
- if (!import_fs.default.existsSync(folder)) {
928
- import_fs.default.mkdirSync(folder, { recursive: true });
929
- }
930
- if (!import_fs.default.existsSync(`${folder}`)) {
931
- throw new Error(`Store folder not found: ${folder}`);
932
- }
933
- }
934
- };
935
753
 
936
- // src/node/pricer-redis.ts
937
- var import_redis = require("redis");
938
- var PricerRedis = class extends Pricer {
939
- constructor(config, tokens2) {
940
- super(config, tokens2);
941
- this.redisClient = null;
942
- }
943
- /** Reads prices from Pricer._loadPrices and uses a callback to set prices in redis */
944
- async startWithRedis(redisUrl) {
945
- await this.initRedis(redisUrl);
946
- logger.info(`Starting Pricer with Redis`);
947
- this._loadPrices(this._setRedisPrices.bind(this));
948
- setInterval(() => {
949
- this._loadPrices(this._setRedisPrices.bind(this));
950
- }, 3e4);
951
- }
952
- async close() {
953
- if (this.redisClient) {
954
- await this.redisClient.disconnect();
955
- }
956
- }
957
- async initRedis(redisUrl) {
958
- logger.info(`Initialising Redis Client`);
959
- this.redisClient = await (0, import_redis.createClient)({
960
- url: redisUrl
961
- });
962
- this.redisClient.on("error", (err) => console.log("Redis Client Error", err)).connect();
963
- logger.info(`Redis Client Initialised`);
964
- }
965
- /** sets current local price in redis */
966
- _setRedisPrices(tokenSymbol) {
967
- if (!this.redisClient) {
968
- throw new FatalError(`Redis client not initialised`);
969
- }
970
- this.redisClient.set(`Price:${tokenSymbol}`, JSON.stringify(this.prices[tokenSymbol])).catch((err) => {
971
- logger.warn(`Error setting price in redis for ${tokenSymbol}`);
972
- });
973
- }
974
- /** Returns price from redis */
975
- async getPrice(tokenSymbol) {
976
- const STALE_TIME = 6e4;
977
- if (!this.redisClient) {
978
- throw new FatalError(`Redis client not initialised`);
979
- }
980
- const data = await this.redisClient.get(`Price:${tokenSymbol}`);
981
- if (!data) {
982
- throw new FatalError(`Redis:Price of ${tokenSymbol} not found`);
983
- }
984
- logger.verbose(`Redis:Price of ${tokenSymbol} is ${data}`);
754
+ // src/data/vesu-rebalance.abi.json
755
+ var vesu_rebalance_abi_default = [
756
+ {
757
+ type: "impl",
758
+ name: "ExternalImpl",
759
+ interface_name: "strkfarm_contracts::strategies::vesu_rebalance::interface::IVesuRebal"
760
+ },
761
+ {
762
+ type: "enum",
763
+ name: "strkfarm_contracts::strategies::vesu_rebalance::interface::Feature",
764
+ variants: [
765
+ {
766
+ name: "DEPOSIT",
767
+ type: "()"
768
+ },
769
+ {
770
+ name: "WITHDRAW",
771
+ type: "()"
772
+ }
773
+ ]
774
+ },
775
+ {
776
+ type: "struct",
777
+ name: "core::integer::u256",
778
+ members: [
779
+ {
780
+ name: "low",
781
+ type: "core::integer::u128"
782
+ },
783
+ {
784
+ name: "high",
785
+ type: "core::integer::u128"
786
+ }
787
+ ]
788
+ },
789
+ {
790
+ type: "struct",
791
+ name: "strkfarm_contracts::strategies::vesu_rebalance::interface::Action",
792
+ members: [
793
+ {
794
+ name: "pool_id",
795
+ type: "core::felt252"
796
+ },
797
+ {
798
+ name: "feature",
799
+ type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Feature"
800
+ },
801
+ {
802
+ name: "token",
803
+ type: "core::starknet::contract_address::ContractAddress"
804
+ },
805
+ {
806
+ name: "amount",
807
+ type: "core::integer::u256"
808
+ }
809
+ ]
810
+ },
811
+ {
812
+ type: "struct",
813
+ name: "strkfarm_contracts::interfaces::IEkuboDistributor::Claim",
814
+ members: [
815
+ {
816
+ name: "id",
817
+ type: "core::integer::u64"
818
+ },
819
+ {
820
+ name: "claimee",
821
+ type: "core::starknet::contract_address::ContractAddress"
822
+ },
823
+ {
824
+ name: "amount",
825
+ type: "core::integer::u128"
826
+ }
827
+ ]
828
+ },
829
+ {
830
+ type: "struct",
831
+ name: "core::array::Span::<core::felt252>",
832
+ members: [
833
+ {
834
+ name: "snapshot",
835
+ type: "@core::array::Array::<core::felt252>"
836
+ }
837
+ ]
838
+ },
839
+ {
840
+ type: "struct",
841
+ name: "strkfarm_contracts::components::swap::Route",
842
+ members: [
843
+ {
844
+ name: "token_from",
845
+ type: "core::starknet::contract_address::ContractAddress"
846
+ },
847
+ {
848
+ name: "token_to",
849
+ type: "core::starknet::contract_address::ContractAddress"
850
+ },
851
+ {
852
+ name: "exchange_address",
853
+ type: "core::starknet::contract_address::ContractAddress"
854
+ },
855
+ {
856
+ name: "percent",
857
+ type: "core::integer::u128"
858
+ },
859
+ {
860
+ name: "additional_swap_params",
861
+ type: "core::array::Array::<core::felt252>"
862
+ }
863
+ ]
864
+ },
865
+ {
866
+ type: "struct",
867
+ name: "strkfarm_contracts::components::swap::AvnuMultiRouteSwap",
868
+ members: [
869
+ {
870
+ name: "token_from_address",
871
+ type: "core::starknet::contract_address::ContractAddress"
872
+ },
873
+ {
874
+ name: "token_from_amount",
875
+ type: "core::integer::u256"
876
+ },
877
+ {
878
+ name: "token_to_address",
879
+ type: "core::starknet::contract_address::ContractAddress"
880
+ },
881
+ {
882
+ name: "token_to_amount",
883
+ type: "core::integer::u256"
884
+ },
885
+ {
886
+ name: "token_to_min_amount",
887
+ type: "core::integer::u256"
888
+ },
889
+ {
890
+ name: "beneficiary",
891
+ type: "core::starknet::contract_address::ContractAddress"
892
+ },
893
+ {
894
+ name: "integrator_fee_amount_bps",
895
+ type: "core::integer::u128"
896
+ },
897
+ {
898
+ name: "integrator_fee_recipient",
899
+ type: "core::starknet::contract_address::ContractAddress"
900
+ },
901
+ {
902
+ name: "routes",
903
+ type: "core::array::Array::<strkfarm_contracts::components::swap::Route>"
904
+ }
905
+ ]
906
+ },
907
+ {
908
+ type: "struct",
909
+ name: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings",
910
+ members: [
911
+ {
912
+ name: "default_pool_index",
913
+ type: "core::integer::u8"
914
+ },
915
+ {
916
+ name: "fee_bps",
917
+ type: "core::integer::u32"
918
+ },
919
+ {
920
+ name: "fee_receiver",
921
+ type: "core::starknet::contract_address::ContractAddress"
922
+ }
923
+ ]
924
+ },
925
+ {
926
+ type: "struct",
927
+ name: "strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps",
928
+ members: [
929
+ {
930
+ name: "pool_id",
931
+ type: "core::felt252"
932
+ },
933
+ {
934
+ name: "max_weight",
935
+ type: "core::integer::u32"
936
+ },
937
+ {
938
+ name: "v_token",
939
+ type: "core::starknet::contract_address::ContractAddress"
940
+ }
941
+ ]
942
+ },
943
+ {
944
+ type: "interface",
945
+ name: "strkfarm_contracts::strategies::vesu_rebalance::interface::IVesuRebal",
946
+ items: [
947
+ {
948
+ type: "function",
949
+ name: "rebalance",
950
+ inputs: [
951
+ {
952
+ name: "actions",
953
+ type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::Action>"
954
+ }
955
+ ],
956
+ outputs: [],
957
+ state_mutability: "external"
958
+ },
959
+ {
960
+ type: "function",
961
+ name: "rebalance_weights",
962
+ inputs: [
963
+ {
964
+ name: "actions",
965
+ type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::Action>"
966
+ }
967
+ ],
968
+ outputs: [],
969
+ state_mutability: "external"
970
+ },
971
+ {
972
+ type: "function",
973
+ name: "emergency_withdraw",
974
+ inputs: [],
975
+ outputs: [],
976
+ state_mutability: "external"
977
+ },
978
+ {
979
+ type: "function",
980
+ name: "emergency_withdraw_pool",
981
+ inputs: [
982
+ {
983
+ name: "pool_index",
984
+ type: "core::integer::u32"
985
+ }
986
+ ],
987
+ outputs: [],
988
+ state_mutability: "external"
989
+ },
990
+ {
991
+ type: "function",
992
+ name: "compute_yield",
993
+ inputs: [],
994
+ outputs: [
995
+ {
996
+ type: "(core::integer::u256, core::integer::u256)"
997
+ }
998
+ ],
999
+ state_mutability: "view"
1000
+ },
1001
+ {
1002
+ type: "function",
1003
+ name: "harvest",
1004
+ inputs: [
1005
+ {
1006
+ name: "rewardsContract",
1007
+ type: "core::starknet::contract_address::ContractAddress"
1008
+ },
1009
+ {
1010
+ name: "claim",
1011
+ type: "strkfarm_contracts::interfaces::IEkuboDistributor::Claim"
1012
+ },
1013
+ {
1014
+ name: "proof",
1015
+ type: "core::array::Span::<core::felt252>"
1016
+ },
1017
+ {
1018
+ name: "swapInfo",
1019
+ type: "strkfarm_contracts::components::swap::AvnuMultiRouteSwap"
1020
+ }
1021
+ ],
1022
+ outputs: [],
1023
+ state_mutability: "external"
1024
+ },
1025
+ {
1026
+ type: "function",
1027
+ name: "set_settings",
1028
+ inputs: [
1029
+ {
1030
+ name: "settings",
1031
+ type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings"
1032
+ }
1033
+ ],
1034
+ outputs: [],
1035
+ state_mutability: "external"
1036
+ },
1037
+ {
1038
+ type: "function",
1039
+ name: "set_allowed_pools",
1040
+ inputs: [
1041
+ {
1042
+ name: "pools",
1043
+ type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps>"
1044
+ }
1045
+ ],
1046
+ outputs: [],
1047
+ state_mutability: "external"
1048
+ },
1049
+ {
1050
+ type: "function",
1051
+ name: "set_incentives_off",
1052
+ inputs: [],
1053
+ outputs: [],
1054
+ state_mutability: "external"
1055
+ },
1056
+ {
1057
+ type: "function",
1058
+ name: "get_settings",
1059
+ inputs: [],
1060
+ outputs: [
1061
+ {
1062
+ type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings"
1063
+ }
1064
+ ],
1065
+ state_mutability: "view"
1066
+ },
1067
+ {
1068
+ type: "function",
1069
+ name: "get_allowed_pools",
1070
+ inputs: [],
1071
+ outputs: [
1072
+ {
1073
+ type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps>"
1074
+ }
1075
+ ],
1076
+ state_mutability: "view"
1077
+ },
1078
+ {
1079
+ type: "function",
1080
+ name: "get_previous_index",
1081
+ inputs: [],
1082
+ outputs: [
1083
+ {
1084
+ type: "core::integer::u128"
1085
+ }
1086
+ ],
1087
+ state_mutability: "view"
1088
+ }
1089
+ ]
1090
+ },
1091
+ {
1092
+ type: "impl",
1093
+ name: "VesuERC4626Impl",
1094
+ interface_name: "strkfarm_contracts::interfaces::IERC4626::IERC4626"
1095
+ },
1096
+ {
1097
+ type: "interface",
1098
+ name: "strkfarm_contracts::interfaces::IERC4626::IERC4626",
1099
+ items: [
1100
+ {
1101
+ type: "function",
1102
+ name: "asset",
1103
+ inputs: [],
1104
+ outputs: [
1105
+ {
1106
+ type: "core::starknet::contract_address::ContractAddress"
1107
+ }
1108
+ ],
1109
+ state_mutability: "view"
1110
+ },
1111
+ {
1112
+ type: "function",
1113
+ name: "total_assets",
1114
+ inputs: [],
1115
+ outputs: [
1116
+ {
1117
+ type: "core::integer::u256"
1118
+ }
1119
+ ],
1120
+ state_mutability: "view"
1121
+ },
1122
+ {
1123
+ type: "function",
1124
+ name: "convert_to_shares",
1125
+ inputs: [
1126
+ {
1127
+ name: "assets",
1128
+ type: "core::integer::u256"
1129
+ }
1130
+ ],
1131
+ outputs: [
1132
+ {
1133
+ type: "core::integer::u256"
1134
+ }
1135
+ ],
1136
+ state_mutability: "view"
1137
+ },
1138
+ {
1139
+ type: "function",
1140
+ name: "convert_to_assets",
1141
+ inputs: [
1142
+ {
1143
+ name: "shares",
1144
+ type: "core::integer::u256"
1145
+ }
1146
+ ],
1147
+ outputs: [
1148
+ {
1149
+ type: "core::integer::u256"
1150
+ }
1151
+ ],
1152
+ state_mutability: "view"
1153
+ },
1154
+ {
1155
+ type: "function",
1156
+ name: "max_deposit",
1157
+ inputs: [
1158
+ {
1159
+ name: "receiver",
1160
+ type: "core::starknet::contract_address::ContractAddress"
1161
+ }
1162
+ ],
1163
+ outputs: [
1164
+ {
1165
+ type: "core::integer::u256"
1166
+ }
1167
+ ],
1168
+ state_mutability: "view"
1169
+ },
1170
+ {
1171
+ type: "function",
1172
+ name: "preview_deposit",
1173
+ inputs: [
1174
+ {
1175
+ name: "assets",
1176
+ type: "core::integer::u256"
1177
+ }
1178
+ ],
1179
+ outputs: [
1180
+ {
1181
+ type: "core::integer::u256"
1182
+ }
1183
+ ],
1184
+ state_mutability: "view"
1185
+ },
1186
+ {
1187
+ type: "function",
1188
+ name: "deposit",
1189
+ inputs: [
1190
+ {
1191
+ name: "assets",
1192
+ type: "core::integer::u256"
1193
+ },
1194
+ {
1195
+ name: "receiver",
1196
+ type: "core::starknet::contract_address::ContractAddress"
1197
+ }
1198
+ ],
1199
+ outputs: [
1200
+ {
1201
+ type: "core::integer::u256"
1202
+ }
1203
+ ],
1204
+ state_mutability: "external"
1205
+ },
1206
+ {
1207
+ type: "function",
1208
+ name: "max_mint",
1209
+ inputs: [
1210
+ {
1211
+ name: "receiver",
1212
+ type: "core::starknet::contract_address::ContractAddress"
1213
+ }
1214
+ ],
1215
+ outputs: [
1216
+ {
1217
+ type: "core::integer::u256"
1218
+ }
1219
+ ],
1220
+ state_mutability: "view"
1221
+ },
1222
+ {
1223
+ type: "function",
1224
+ name: "preview_mint",
1225
+ inputs: [
1226
+ {
1227
+ name: "shares",
1228
+ type: "core::integer::u256"
1229
+ }
1230
+ ],
1231
+ outputs: [
1232
+ {
1233
+ type: "core::integer::u256"
1234
+ }
1235
+ ],
1236
+ state_mutability: "view"
1237
+ },
1238
+ {
1239
+ type: "function",
1240
+ name: "mint",
1241
+ inputs: [
1242
+ {
1243
+ name: "shares",
1244
+ type: "core::integer::u256"
1245
+ },
1246
+ {
1247
+ name: "receiver",
1248
+ type: "core::starknet::contract_address::ContractAddress"
1249
+ }
1250
+ ],
1251
+ outputs: [
1252
+ {
1253
+ type: "core::integer::u256"
1254
+ }
1255
+ ],
1256
+ state_mutability: "external"
1257
+ },
1258
+ {
1259
+ type: "function",
1260
+ name: "max_withdraw",
1261
+ inputs: [
1262
+ {
1263
+ name: "owner",
1264
+ type: "core::starknet::contract_address::ContractAddress"
1265
+ }
1266
+ ],
1267
+ outputs: [
1268
+ {
1269
+ type: "core::integer::u256"
1270
+ }
1271
+ ],
1272
+ state_mutability: "view"
1273
+ },
1274
+ {
1275
+ type: "function",
1276
+ name: "preview_withdraw",
1277
+ inputs: [
1278
+ {
1279
+ name: "assets",
1280
+ type: "core::integer::u256"
1281
+ }
1282
+ ],
1283
+ outputs: [
1284
+ {
1285
+ type: "core::integer::u256"
1286
+ }
1287
+ ],
1288
+ state_mutability: "view"
1289
+ },
1290
+ {
1291
+ type: "function",
1292
+ name: "withdraw",
1293
+ inputs: [
1294
+ {
1295
+ name: "assets",
1296
+ type: "core::integer::u256"
1297
+ },
1298
+ {
1299
+ name: "receiver",
1300
+ type: "core::starknet::contract_address::ContractAddress"
1301
+ },
1302
+ {
1303
+ name: "owner",
1304
+ type: "core::starknet::contract_address::ContractAddress"
1305
+ }
1306
+ ],
1307
+ outputs: [
1308
+ {
1309
+ type: "core::integer::u256"
1310
+ }
1311
+ ],
1312
+ state_mutability: "external"
1313
+ },
1314
+ {
1315
+ type: "function",
1316
+ name: "max_redeem",
1317
+ inputs: [
1318
+ {
1319
+ name: "owner",
1320
+ type: "core::starknet::contract_address::ContractAddress"
1321
+ }
1322
+ ],
1323
+ outputs: [
1324
+ {
1325
+ type: "core::integer::u256"
1326
+ }
1327
+ ],
1328
+ state_mutability: "view"
1329
+ },
1330
+ {
1331
+ type: "function",
1332
+ name: "preview_redeem",
1333
+ inputs: [
1334
+ {
1335
+ name: "shares",
1336
+ type: "core::integer::u256"
1337
+ }
1338
+ ],
1339
+ outputs: [
1340
+ {
1341
+ type: "core::integer::u256"
1342
+ }
1343
+ ],
1344
+ state_mutability: "view"
1345
+ },
1346
+ {
1347
+ type: "function",
1348
+ name: "redeem",
1349
+ inputs: [
1350
+ {
1351
+ name: "shares",
1352
+ type: "core::integer::u256"
1353
+ },
1354
+ {
1355
+ name: "receiver",
1356
+ type: "core::starknet::contract_address::ContractAddress"
1357
+ },
1358
+ {
1359
+ name: "owner",
1360
+ type: "core::starknet::contract_address::ContractAddress"
1361
+ }
1362
+ ],
1363
+ outputs: [
1364
+ {
1365
+ type: "core::integer::u256"
1366
+ }
1367
+ ],
1368
+ state_mutability: "external"
1369
+ }
1370
+ ]
1371
+ },
1372
+ {
1373
+ type: "impl",
1374
+ name: "VesuERC20Impl",
1375
+ interface_name: "openzeppelin_token::erc20::interface::IERC20Mixin"
1376
+ },
1377
+ {
1378
+ type: "enum",
1379
+ name: "core::bool",
1380
+ variants: [
1381
+ {
1382
+ name: "False",
1383
+ type: "()"
1384
+ },
1385
+ {
1386
+ name: "True",
1387
+ type: "()"
1388
+ }
1389
+ ]
1390
+ },
1391
+ {
1392
+ type: "struct",
1393
+ name: "core::byte_array::ByteArray",
1394
+ members: [
1395
+ {
1396
+ name: "data",
1397
+ type: "core::array::Array::<core::bytes_31::bytes31>"
1398
+ },
1399
+ {
1400
+ name: "pending_word",
1401
+ type: "core::felt252"
1402
+ },
1403
+ {
1404
+ name: "pending_word_len",
1405
+ type: "core::integer::u32"
1406
+ }
1407
+ ]
1408
+ },
1409
+ {
1410
+ type: "interface",
1411
+ name: "openzeppelin_token::erc20::interface::IERC20Mixin",
1412
+ items: [
1413
+ {
1414
+ type: "function",
1415
+ name: "total_supply",
1416
+ inputs: [],
1417
+ outputs: [
1418
+ {
1419
+ type: "core::integer::u256"
1420
+ }
1421
+ ],
1422
+ state_mutability: "view"
1423
+ },
1424
+ {
1425
+ type: "function",
1426
+ name: "balance_of",
1427
+ inputs: [
1428
+ {
1429
+ name: "account",
1430
+ type: "core::starknet::contract_address::ContractAddress"
1431
+ }
1432
+ ],
1433
+ outputs: [
1434
+ {
1435
+ type: "core::integer::u256"
1436
+ }
1437
+ ],
1438
+ state_mutability: "view"
1439
+ },
1440
+ {
1441
+ type: "function",
1442
+ name: "allowance",
1443
+ inputs: [
1444
+ {
1445
+ name: "owner",
1446
+ type: "core::starknet::contract_address::ContractAddress"
1447
+ },
1448
+ {
1449
+ name: "spender",
1450
+ type: "core::starknet::contract_address::ContractAddress"
1451
+ }
1452
+ ],
1453
+ outputs: [
1454
+ {
1455
+ type: "core::integer::u256"
1456
+ }
1457
+ ],
1458
+ state_mutability: "view"
1459
+ },
1460
+ {
1461
+ type: "function",
1462
+ name: "transfer",
1463
+ inputs: [
1464
+ {
1465
+ name: "recipient",
1466
+ type: "core::starknet::contract_address::ContractAddress"
1467
+ },
1468
+ {
1469
+ name: "amount",
1470
+ type: "core::integer::u256"
1471
+ }
1472
+ ],
1473
+ outputs: [
1474
+ {
1475
+ type: "core::bool"
1476
+ }
1477
+ ],
1478
+ state_mutability: "external"
1479
+ },
1480
+ {
1481
+ type: "function",
1482
+ name: "transfer_from",
1483
+ inputs: [
1484
+ {
1485
+ name: "sender",
1486
+ type: "core::starknet::contract_address::ContractAddress"
1487
+ },
1488
+ {
1489
+ name: "recipient",
1490
+ type: "core::starknet::contract_address::ContractAddress"
1491
+ },
1492
+ {
1493
+ name: "amount",
1494
+ type: "core::integer::u256"
1495
+ }
1496
+ ],
1497
+ outputs: [
1498
+ {
1499
+ type: "core::bool"
1500
+ }
1501
+ ],
1502
+ state_mutability: "external"
1503
+ },
1504
+ {
1505
+ type: "function",
1506
+ name: "approve",
1507
+ inputs: [
1508
+ {
1509
+ name: "spender",
1510
+ type: "core::starknet::contract_address::ContractAddress"
1511
+ },
1512
+ {
1513
+ name: "amount",
1514
+ type: "core::integer::u256"
1515
+ }
1516
+ ],
1517
+ outputs: [
1518
+ {
1519
+ type: "core::bool"
1520
+ }
1521
+ ],
1522
+ state_mutability: "external"
1523
+ },
1524
+ {
1525
+ type: "function",
1526
+ name: "name",
1527
+ inputs: [],
1528
+ outputs: [
1529
+ {
1530
+ type: "core::byte_array::ByteArray"
1531
+ }
1532
+ ],
1533
+ state_mutability: "view"
1534
+ },
1535
+ {
1536
+ type: "function",
1537
+ name: "symbol",
1538
+ inputs: [],
1539
+ outputs: [
1540
+ {
1541
+ type: "core::byte_array::ByteArray"
1542
+ }
1543
+ ],
1544
+ state_mutability: "view"
1545
+ },
1546
+ {
1547
+ type: "function",
1548
+ name: "decimals",
1549
+ inputs: [],
1550
+ outputs: [
1551
+ {
1552
+ type: "core::integer::u8"
1553
+ }
1554
+ ],
1555
+ state_mutability: "view"
1556
+ },
1557
+ {
1558
+ type: "function",
1559
+ name: "totalSupply",
1560
+ inputs: [],
1561
+ outputs: [
1562
+ {
1563
+ type: "core::integer::u256"
1564
+ }
1565
+ ],
1566
+ state_mutability: "view"
1567
+ },
1568
+ {
1569
+ type: "function",
1570
+ name: "balanceOf",
1571
+ inputs: [
1572
+ {
1573
+ name: "account",
1574
+ type: "core::starknet::contract_address::ContractAddress"
1575
+ }
1576
+ ],
1577
+ outputs: [
1578
+ {
1579
+ type: "core::integer::u256"
1580
+ }
1581
+ ],
1582
+ state_mutability: "view"
1583
+ },
1584
+ {
1585
+ type: "function",
1586
+ name: "transferFrom",
1587
+ inputs: [
1588
+ {
1589
+ name: "sender",
1590
+ type: "core::starknet::contract_address::ContractAddress"
1591
+ },
1592
+ {
1593
+ name: "recipient",
1594
+ type: "core::starknet::contract_address::ContractAddress"
1595
+ },
1596
+ {
1597
+ name: "amount",
1598
+ type: "core::integer::u256"
1599
+ }
1600
+ ],
1601
+ outputs: [
1602
+ {
1603
+ type: "core::bool"
1604
+ }
1605
+ ],
1606
+ state_mutability: "external"
1607
+ }
1608
+ ]
1609
+ },
1610
+ {
1611
+ type: "impl",
1612
+ name: "CommonCompImpl",
1613
+ interface_name: "strkfarm_contracts::interfaces::common::ICommon"
1614
+ },
1615
+ {
1616
+ type: "interface",
1617
+ name: "strkfarm_contracts::interfaces::common::ICommon",
1618
+ items: [
1619
+ {
1620
+ type: "function",
1621
+ name: "upgrade",
1622
+ inputs: [
1623
+ {
1624
+ name: "new_class",
1625
+ type: "core::starknet::class_hash::ClassHash"
1626
+ }
1627
+ ],
1628
+ outputs: [],
1629
+ state_mutability: "external"
1630
+ },
1631
+ {
1632
+ type: "function",
1633
+ name: "pause",
1634
+ inputs: [],
1635
+ outputs: [],
1636
+ state_mutability: "external"
1637
+ },
1638
+ {
1639
+ type: "function",
1640
+ name: "unpause",
1641
+ inputs: [],
1642
+ outputs: [],
1643
+ state_mutability: "external"
1644
+ },
1645
+ {
1646
+ type: "function",
1647
+ name: "is_paused",
1648
+ inputs: [],
1649
+ outputs: [
1650
+ {
1651
+ type: "core::bool"
1652
+ }
1653
+ ],
1654
+ state_mutability: "view"
1655
+ }
1656
+ ]
1657
+ },
1658
+ {
1659
+ type: "impl",
1660
+ name: "RewardShareImpl",
1661
+ interface_name: "strkfarm_contracts::components::harvester::reward_shares::IRewardShare"
1662
+ },
1663
+ {
1664
+ type: "struct",
1665
+ name: "strkfarm_contracts::components::harvester::reward_shares::UserRewardsInfo",
1666
+ members: [
1667
+ {
1668
+ name: "pending_round_points",
1669
+ type: "core::integer::u128"
1670
+ },
1671
+ {
1672
+ name: "shares_owned",
1673
+ type: "core::integer::u128"
1674
+ },
1675
+ {
1676
+ name: "block_number",
1677
+ type: "core::integer::u64"
1678
+ },
1679
+ {
1680
+ name: "index",
1681
+ type: "core::integer::u32"
1682
+ }
1683
+ ]
1684
+ },
1685
+ {
1686
+ type: "struct",
1687
+ name: "strkfarm_contracts::components::harvester::reward_shares::RewardsInfo",
1688
+ members: [
1689
+ {
1690
+ name: "amount",
1691
+ type: "core::integer::u128"
1692
+ },
1693
+ {
1694
+ name: "shares",
1695
+ type: "core::integer::u128"
1696
+ },
1697
+ {
1698
+ name: "total_round_points",
1699
+ type: "core::integer::u128"
1700
+ },
1701
+ {
1702
+ name: "block_number",
1703
+ type: "core::integer::u64"
1704
+ }
1705
+ ]
1706
+ },
1707
+ {
1708
+ type: "interface",
1709
+ name: "strkfarm_contracts::components::harvester::reward_shares::IRewardShare",
1710
+ items: [
1711
+ {
1712
+ type: "function",
1713
+ name: "get_user_reward_info",
1714
+ inputs: [
1715
+ {
1716
+ name: "user",
1717
+ type: "core::starknet::contract_address::ContractAddress"
1718
+ }
1719
+ ],
1720
+ outputs: [
1721
+ {
1722
+ type: "strkfarm_contracts::components::harvester::reward_shares::UserRewardsInfo"
1723
+ }
1724
+ ],
1725
+ state_mutability: "view"
1726
+ },
1727
+ {
1728
+ type: "function",
1729
+ name: "get_rewards_info",
1730
+ inputs: [
1731
+ {
1732
+ name: "index",
1733
+ type: "core::integer::u32"
1734
+ }
1735
+ ],
1736
+ outputs: [
1737
+ {
1738
+ type: "strkfarm_contracts::components::harvester::reward_shares::RewardsInfo"
1739
+ }
1740
+ ],
1741
+ state_mutability: "view"
1742
+ },
1743
+ {
1744
+ type: "function",
1745
+ name: "get_total_rewards",
1746
+ inputs: [],
1747
+ outputs: [
1748
+ {
1749
+ type: "core::integer::u32"
1750
+ }
1751
+ ],
1752
+ state_mutability: "view"
1753
+ },
1754
+ {
1755
+ type: "function",
1756
+ name: "get_total_unminted_shares",
1757
+ inputs: [],
1758
+ outputs: [
1759
+ {
1760
+ type: "core::integer::u128"
1761
+ }
1762
+ ],
1763
+ state_mutability: "view"
1764
+ },
1765
+ {
1766
+ type: "function",
1767
+ name: "get_additional_shares",
1768
+ inputs: [
1769
+ {
1770
+ name: "user",
1771
+ type: "core::starknet::contract_address::ContractAddress"
1772
+ }
1773
+ ],
1774
+ outputs: [
1775
+ {
1776
+ type: "(core::integer::u128, core::integer::u64, core::integer::u128)"
1777
+ }
1778
+ ],
1779
+ state_mutability: "view"
1780
+ }
1781
+ ]
1782
+ },
1783
+ {
1784
+ type: "struct",
1785
+ name: "strkfarm_contracts::interfaces::IVesu::IStonDispatcher",
1786
+ members: [
1787
+ {
1788
+ name: "contract_address",
1789
+ type: "core::starknet::contract_address::ContractAddress"
1790
+ }
1791
+ ]
1792
+ },
1793
+ {
1794
+ type: "struct",
1795
+ name: "strkfarm_contracts::components::vesu::vesuStruct",
1796
+ members: [
1797
+ {
1798
+ name: "singleton",
1799
+ type: "strkfarm_contracts::interfaces::IVesu::IStonDispatcher"
1800
+ },
1801
+ {
1802
+ name: "pool_id",
1803
+ type: "core::felt252"
1804
+ },
1805
+ {
1806
+ name: "debt",
1807
+ type: "core::starknet::contract_address::ContractAddress"
1808
+ },
1809
+ {
1810
+ name: "col",
1811
+ type: "core::starknet::contract_address::ContractAddress"
1812
+ },
1813
+ {
1814
+ name: "oracle",
1815
+ type: "core::starknet::contract_address::ContractAddress"
1816
+ }
1817
+ ]
1818
+ },
1819
+ {
1820
+ type: "constructor",
1821
+ name: "constructor",
1822
+ inputs: [
1823
+ {
1824
+ name: "asset",
1825
+ type: "core::starknet::contract_address::ContractAddress"
1826
+ },
1827
+ {
1828
+ name: "access_control",
1829
+ type: "core::starknet::contract_address::ContractAddress"
1830
+ },
1831
+ {
1832
+ name: "allowed_pools",
1833
+ type: "core::array::Array::<strkfarm_contracts::strategies::vesu_rebalance::interface::PoolProps>"
1834
+ },
1835
+ {
1836
+ name: "settings",
1837
+ type: "strkfarm_contracts::strategies::vesu_rebalance::interface::Settings"
1838
+ },
1839
+ {
1840
+ name: "vesu_settings",
1841
+ type: "strkfarm_contracts::components::vesu::vesuStruct"
1842
+ }
1843
+ ]
1844
+ },
1845
+ {
1846
+ type: "event",
1847
+ name: "openzeppelin_security::reentrancyguard::ReentrancyGuardComponent::Event",
1848
+ kind: "enum",
1849
+ variants: []
1850
+ },
1851
+ {
1852
+ type: "event",
1853
+ name: "strkfarm_contracts::components::erc4626::ERC4626Component::Deposit",
1854
+ kind: "struct",
1855
+ members: [
1856
+ {
1857
+ name: "sender",
1858
+ type: "core::starknet::contract_address::ContractAddress",
1859
+ kind: "key"
1860
+ },
1861
+ {
1862
+ name: "owner",
1863
+ type: "core::starknet::contract_address::ContractAddress",
1864
+ kind: "key"
1865
+ },
1866
+ {
1867
+ name: "assets",
1868
+ type: "core::integer::u256",
1869
+ kind: "data"
1870
+ },
1871
+ {
1872
+ name: "shares",
1873
+ type: "core::integer::u256",
1874
+ kind: "data"
1875
+ }
1876
+ ]
1877
+ },
1878
+ {
1879
+ type: "event",
1880
+ name: "strkfarm_contracts::components::erc4626::ERC4626Component::Withdraw",
1881
+ kind: "struct",
1882
+ members: [
1883
+ {
1884
+ name: "sender",
1885
+ type: "core::starknet::contract_address::ContractAddress",
1886
+ kind: "key"
1887
+ },
1888
+ {
1889
+ name: "receiver",
1890
+ type: "core::starknet::contract_address::ContractAddress",
1891
+ kind: "key"
1892
+ },
1893
+ {
1894
+ name: "owner",
1895
+ type: "core::starknet::contract_address::ContractAddress",
1896
+ kind: "key"
1897
+ },
1898
+ {
1899
+ name: "assets",
1900
+ type: "core::integer::u256",
1901
+ kind: "data"
1902
+ },
1903
+ {
1904
+ name: "shares",
1905
+ type: "core::integer::u256",
1906
+ kind: "data"
1907
+ }
1908
+ ]
1909
+ },
1910
+ {
1911
+ type: "event",
1912
+ name: "strkfarm_contracts::components::erc4626::ERC4626Component::Event",
1913
+ kind: "enum",
1914
+ variants: [
1915
+ {
1916
+ name: "Deposit",
1917
+ type: "strkfarm_contracts::components::erc4626::ERC4626Component::Deposit",
1918
+ kind: "nested"
1919
+ },
1920
+ {
1921
+ name: "Withdraw",
1922
+ type: "strkfarm_contracts::components::erc4626::ERC4626Component::Withdraw",
1923
+ kind: "nested"
1924
+ }
1925
+ ]
1926
+ },
1927
+ {
1928
+ type: "event",
1929
+ name: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Rewards",
1930
+ kind: "struct",
1931
+ members: [
1932
+ {
1933
+ name: "index",
1934
+ type: "core::integer::u32",
1935
+ kind: "data"
1936
+ },
1937
+ {
1938
+ name: "info",
1939
+ type: "strkfarm_contracts::components::harvester::reward_shares::RewardsInfo",
1940
+ kind: "data"
1941
+ },
1942
+ {
1943
+ name: "total_reward_shares",
1944
+ type: "core::integer::u128",
1945
+ kind: "data"
1946
+ },
1947
+ {
1948
+ name: "timestamp",
1949
+ type: "core::integer::u64",
1950
+ kind: "data"
1951
+ }
1952
+ ]
1953
+ },
1954
+ {
1955
+ type: "event",
1956
+ name: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::UserRewards",
1957
+ kind: "struct",
1958
+ members: [
1959
+ {
1960
+ name: "user",
1961
+ type: "core::starknet::contract_address::ContractAddress",
1962
+ kind: "key"
1963
+ },
1964
+ {
1965
+ name: "info",
1966
+ type: "strkfarm_contracts::components::harvester::reward_shares::UserRewardsInfo",
1967
+ kind: "data"
1968
+ },
1969
+ {
1970
+ name: "total_reward_shares",
1971
+ type: "core::integer::u128",
1972
+ kind: "data"
1973
+ },
1974
+ {
1975
+ name: "timestamp",
1976
+ type: "core::integer::u64",
1977
+ kind: "data"
1978
+ }
1979
+ ]
1980
+ },
1981
+ {
1982
+ type: "event",
1983
+ name: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Event",
1984
+ kind: "enum",
1985
+ variants: [
1986
+ {
1987
+ name: "Rewards",
1988
+ type: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Rewards",
1989
+ kind: "nested"
1990
+ },
1991
+ {
1992
+ name: "UserRewards",
1993
+ type: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::UserRewards",
1994
+ kind: "nested"
1995
+ }
1996
+ ]
1997
+ },
1998
+ {
1999
+ type: "event",
2000
+ name: "openzeppelin_token::erc20::erc20::ERC20Component::Transfer",
2001
+ kind: "struct",
2002
+ members: [
2003
+ {
2004
+ name: "from",
2005
+ type: "core::starknet::contract_address::ContractAddress",
2006
+ kind: "key"
2007
+ },
2008
+ {
2009
+ name: "to",
2010
+ type: "core::starknet::contract_address::ContractAddress",
2011
+ kind: "key"
2012
+ },
2013
+ {
2014
+ name: "value",
2015
+ type: "core::integer::u256",
2016
+ kind: "data"
2017
+ }
2018
+ ]
2019
+ },
2020
+ {
2021
+ type: "event",
2022
+ name: "openzeppelin_token::erc20::erc20::ERC20Component::Approval",
2023
+ kind: "struct",
2024
+ members: [
2025
+ {
2026
+ name: "owner",
2027
+ type: "core::starknet::contract_address::ContractAddress",
2028
+ kind: "key"
2029
+ },
2030
+ {
2031
+ name: "spender",
2032
+ type: "core::starknet::contract_address::ContractAddress",
2033
+ kind: "key"
2034
+ },
2035
+ {
2036
+ name: "value",
2037
+ type: "core::integer::u256",
2038
+ kind: "data"
2039
+ }
2040
+ ]
2041
+ },
2042
+ {
2043
+ type: "event",
2044
+ name: "openzeppelin_token::erc20::erc20::ERC20Component::Event",
2045
+ kind: "enum",
2046
+ variants: [
2047
+ {
2048
+ name: "Transfer",
2049
+ type: "openzeppelin_token::erc20::erc20::ERC20Component::Transfer",
2050
+ kind: "nested"
2051
+ },
2052
+ {
2053
+ name: "Approval",
2054
+ type: "openzeppelin_token::erc20::erc20::ERC20Component::Approval",
2055
+ kind: "nested"
2056
+ }
2057
+ ]
2058
+ },
2059
+ {
2060
+ type: "event",
2061
+ name: "openzeppelin_introspection::src5::SRC5Component::Event",
2062
+ kind: "enum",
2063
+ variants: []
2064
+ },
2065
+ {
2066
+ type: "event",
2067
+ name: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded",
2068
+ kind: "struct",
2069
+ members: [
2070
+ {
2071
+ name: "class_hash",
2072
+ type: "core::starknet::class_hash::ClassHash",
2073
+ kind: "data"
2074
+ }
2075
+ ]
2076
+ },
2077
+ {
2078
+ type: "event",
2079
+ name: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event",
2080
+ kind: "enum",
2081
+ variants: [
2082
+ {
2083
+ name: "Upgraded",
2084
+ type: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded",
2085
+ kind: "nested"
2086
+ }
2087
+ ]
2088
+ },
2089
+ {
2090
+ type: "event",
2091
+ name: "openzeppelin_security::pausable::PausableComponent::Paused",
2092
+ kind: "struct",
2093
+ members: [
2094
+ {
2095
+ name: "account",
2096
+ type: "core::starknet::contract_address::ContractAddress",
2097
+ kind: "data"
2098
+ }
2099
+ ]
2100
+ },
2101
+ {
2102
+ type: "event",
2103
+ name: "openzeppelin_security::pausable::PausableComponent::Unpaused",
2104
+ kind: "struct",
2105
+ members: [
2106
+ {
2107
+ name: "account",
2108
+ type: "core::starknet::contract_address::ContractAddress",
2109
+ kind: "data"
2110
+ }
2111
+ ]
2112
+ },
2113
+ {
2114
+ type: "event",
2115
+ name: "openzeppelin_security::pausable::PausableComponent::Event",
2116
+ kind: "enum",
2117
+ variants: [
2118
+ {
2119
+ name: "Paused",
2120
+ type: "openzeppelin_security::pausable::PausableComponent::Paused",
2121
+ kind: "nested"
2122
+ },
2123
+ {
2124
+ name: "Unpaused",
2125
+ type: "openzeppelin_security::pausable::PausableComponent::Unpaused",
2126
+ kind: "nested"
2127
+ }
2128
+ ]
2129
+ },
2130
+ {
2131
+ type: "event",
2132
+ name: "strkfarm_contracts::components::common::CommonComp::Event",
2133
+ kind: "enum",
2134
+ variants: []
2135
+ },
2136
+ {
2137
+ type: "event",
2138
+ name: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::Rebalance",
2139
+ kind: "struct",
2140
+ members: [
2141
+ {
2142
+ name: "yield_before",
2143
+ type: "core::integer::u128",
2144
+ kind: "data"
2145
+ },
2146
+ {
2147
+ name: "yield_after",
2148
+ type: "core::integer::u128",
2149
+ kind: "data"
2150
+ }
2151
+ ]
2152
+ },
2153
+ {
2154
+ type: "event",
2155
+ name: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::CollectFees",
2156
+ kind: "struct",
2157
+ members: [
2158
+ {
2159
+ name: "fee_collected",
2160
+ type: "core::integer::u128",
2161
+ kind: "data"
2162
+ },
2163
+ {
2164
+ name: "fee_collector",
2165
+ type: "core::starknet::contract_address::ContractAddress",
2166
+ kind: "data"
2167
+ }
2168
+ ]
2169
+ },
2170
+ {
2171
+ type: "event",
2172
+ name: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::Event",
2173
+ kind: "enum",
2174
+ variants: [
2175
+ {
2176
+ name: "ReentrancyGuardEvent",
2177
+ type: "openzeppelin_security::reentrancyguard::ReentrancyGuardComponent::Event",
2178
+ kind: "flat"
2179
+ },
2180
+ {
2181
+ name: "ERC4626Event",
2182
+ type: "strkfarm_contracts::components::erc4626::ERC4626Component::Event",
2183
+ kind: "flat"
2184
+ },
2185
+ {
2186
+ name: "RewardShareEvent",
2187
+ type: "strkfarm_contracts::components::harvester::reward_shares::RewardShareComponent::Event",
2188
+ kind: "flat"
2189
+ },
2190
+ {
2191
+ name: "ERC20Event",
2192
+ type: "openzeppelin_token::erc20::erc20::ERC20Component::Event",
2193
+ kind: "flat"
2194
+ },
2195
+ {
2196
+ name: "SRC5Event",
2197
+ type: "openzeppelin_introspection::src5::SRC5Component::Event",
2198
+ kind: "flat"
2199
+ },
2200
+ {
2201
+ name: "UpgradeableEvent",
2202
+ type: "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event",
2203
+ kind: "flat"
2204
+ },
2205
+ {
2206
+ name: "PausableEvent",
2207
+ type: "openzeppelin_security::pausable::PausableComponent::Event",
2208
+ kind: "flat"
2209
+ },
2210
+ {
2211
+ name: "CommonCompEvent",
2212
+ type: "strkfarm_contracts::components::common::CommonComp::Event",
2213
+ kind: "flat"
2214
+ },
2215
+ {
2216
+ name: "Rebalance",
2217
+ type: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::Rebalance",
2218
+ kind: "nested"
2219
+ },
2220
+ {
2221
+ name: "CollectFees",
2222
+ type: "strkfarm_contracts::strategies::vesu_rebalance::vesu_rebalance::VesuRebalance::CollectFees",
2223
+ kind: "nested"
2224
+ }
2225
+ ]
2226
+ }
2227
+ ];
2228
+
2229
+ // src/utils/index.ts
2230
+ function assert(condition, message) {
2231
+ if (!condition) {
2232
+ throw new Error(message);
2233
+ }
2234
+ }
2235
+
2236
+ // src/strategies/vesu-rebalance.ts
2237
+ var import_axios4 = __toESM(require("axios"));
2238
+ var VesuRebalance = class _VesuRebalance {
2239
+ // 10000 bps = 100%
2240
+ /**
2241
+ * Creates a new VesuRebalance strategy instance.
2242
+ * @param config - Configuration object containing provider and other settings
2243
+ * @param pricer - Pricer instance for token price calculations
2244
+ * @param metadata - Strategy metadata including deposit tokens and address
2245
+ * @throws {Error} If more than one deposit token is specified
2246
+ */
2247
+ constructor(config, pricer, metadata) {
2248
+ this.BASE_WEIGHT = 1e4;
2249
+ this.config = config;
2250
+ this.pricer = pricer;
2251
+ assert(metadata.depositTokens.length === 1, "VesuRebalance only supports 1 deposit token");
2252
+ this.metadata = metadata;
2253
+ this.address = metadata.address;
2254
+ this.contract = new import_starknet5.Contract(vesu_rebalance_abi_default, this.address.address, this.config.provider);
2255
+ }
2256
+ /**
2257
+ * Creates a deposit call to the strategy contract.
2258
+ * @param assets - Amount of assets to deposit
2259
+ * @param receiver - Address that will receive the strategy tokens
2260
+ * @returns Populated contract call for deposit
2261
+ */
2262
+ depositCall(assets, receiver) {
2263
+ const assetContract = new import_starknet5.Contract(vesu_rebalance_abi_default, this.metadata.depositTokens[0].address, this.config.provider);
2264
+ const call1 = assetContract.populate("approve", [this.address.address, import_starknet5.uint256.bnToUint256(assets.toWei())]);
2265
+ const call2 = this.contract.populate("deposit", [import_starknet5.uint256.bnToUint256(assets.toWei()), receiver.address]);
2266
+ return [call1, call2];
2267
+ }
2268
+ /**
2269
+ * Creates a withdrawal call to the strategy contract.
2270
+ * @param assets - Amount of assets to withdraw
2271
+ * @param receiver - Address that will receive the withdrawn assets
2272
+ * @param owner - Address that owns the strategy tokens
2273
+ * @returns Populated contract call for withdrawal
2274
+ */
2275
+ withdrawCall(assets, receiver, owner) {
2276
+ return [this.contract.populate("withdraw", [import_starknet5.uint256.bnToUint256(assets.toWei()), receiver.address, owner.address])];
2277
+ }
2278
+ /**
2279
+ * Returns the underlying asset token of the strategy.
2280
+ * @returns The deposit token supported by this strategy
2281
+ */
2282
+ asset() {
2283
+ return this.metadata.depositTokens[0];
2284
+ }
2285
+ /**
2286
+ * Returns the number of decimals used by the strategy token.
2287
+ * @returns Number of decimals (same as the underlying token)
2288
+ */
2289
+ decimals() {
2290
+ return this.metadata.depositTokens[0].decimals;
2291
+ }
2292
+ /**
2293
+ * Calculates the Total Value Locked (TVL) for a specific user.
2294
+ * @param user - Address of the user
2295
+ * @returns Object containing the amount in token units and USD value
2296
+ */
2297
+ async getUserTVL(user) {
2298
+ const shares = await this.contract.balanceOf(user.address);
2299
+ const assets = await this.contract.convert_to_assets(import_starknet5.uint256.bnToUint256(shares));
2300
+ const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
2301
+ let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
2302
+ const usdValue = Number(amount.toFixed(6)) * price.price;
2303
+ return {
2304
+ amount,
2305
+ usdValue
2306
+ };
2307
+ }
2308
+ /**
2309
+ * Calculates the total TVL of the strategy.
2310
+ * @returns Object containing the total amount in token units and USD value
2311
+ */
2312
+ async getTVL() {
2313
+ const assets = await this.contract.total_assets();
2314
+ const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
2315
+ let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
2316
+ const usdValue = Number(amount.toFixed(6)) * price.price;
2317
+ return {
2318
+ amount,
2319
+ usdValue
2320
+ };
2321
+ }
2322
+ /**
2323
+ * Retrieves the list of allowed pools and their detailed information from multiple sources:
2324
+ * 1. Contract's allowed pools
2325
+ * 2. Vesu positions API for current positions
2326
+ * 3. Vesu pools API for APY and utilization data
2327
+ *
2328
+ * @returns {Promise<{
2329
+ * data: Array<PoolInfoFull>,
2330
+ * isErrorPositionsAPI: boolean
2331
+ * }>} Object containing:
2332
+ * - data: Array of pool information including IDs, weights, amounts, APYs and utilization
2333
+ * - isErrorPositionsAPI: Boolean indicating if there was an error fetching position data
2334
+ */
2335
+ async getPools() {
2336
+ const allowedPools = (await this.contract.get_allowed_pools()).map((p) => ({
2337
+ pool_id: ContractAddr.from(p.pool_id),
2338
+ max_weight: Number(p.max_weight) / this.BASE_WEIGHT,
2339
+ v_token: ContractAddr.from(p.v_token)
2340
+ }));
2341
+ let isErrorPositionsAPI = false;
2342
+ let vesuPositions = [];
2343
+ try {
2344
+ const res = await import_axios4.default.get(`https://api.vesu.xyz/positions?walletAddress=${this.address.address}`);
2345
+ const data2 = await res.data;
2346
+ vesuPositions = data2.data;
2347
+ } catch (e) {
2348
+ console.error(`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}`, e);
2349
+ isErrorPositionsAPI = true;
2350
+ }
2351
+ let isErrorPoolsAPI = false;
2352
+ let pools = [];
2353
+ try {
2354
+ const res = await import_axios4.default.get(`https://api.vesu.xyz/pools`);
2355
+ const data2 = await res.data;
2356
+ pools = data2.data;
2357
+ } catch (e) {
2358
+ console.error(`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}`, e);
2359
+ isErrorPoolsAPI = true;
2360
+ }
2361
+ const totalAssets = (await this.getTVL()).amount;
2362
+ const info = allowedPools.map(async (p) => {
2363
+ const vesuPosition = vesuPositions.find((d) => d.pool.id.toString() === import_starknet5.num.getDecimalString(p.pool_id.address.toString()));
2364
+ const pool = pools.find((d) => d.id == import_starknet5.num.getDecimalString(p.pool_id.address));
2365
+ const assetInfo = pool?.assets.find((d) => ContractAddr.from(this.asset().address).eqString(d.address));
2366
+ let vTokenContract = new import_starknet5.Contract(vesu_rebalance_abi_default, p.v_token.address, this.config.provider);
2367
+ const bal = await vTokenContract.balanceOf(this.address.address);
2368
+ const assets = await vTokenContract.convert_to_assets(import_starknet5.uint256.bnToUint256(bal.toString()));
2369
+ const item = {
2370
+ pool_id: p.pool_id,
2371
+ pool_name: vesuPosition?.pool.name,
2372
+ max_weight: p.max_weight,
2373
+ current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)),
2374
+ v_token: p.v_token,
2375
+ amount: Web3Number.fromWei(assets.toString(), this.decimals()),
2376
+ usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(vesuPosition.collateral.usdPrice.value, vesuPosition.collateral.usdPrice.decimals),
2377
+ APY: isErrorPoolsAPI || !assetInfo ? {
2378
+ baseApy: 0,
2379
+ defiSpringApy: 0,
2380
+ netApy: 0
2381
+ } : {
2382
+ baseApy: Number(Web3Number.fromWei(assetInfo.stats.supplyApy.value, assetInfo.stats.supplyApy.decimals).toFixed(6)),
2383
+ defiSpringApy: Number(Web3Number.fromWei(assetInfo.stats.defiSpringSupplyApr.value, assetInfo.stats.defiSpringSupplyApr.decimals).toFixed(6)),
2384
+ netApy: 0
2385
+ },
2386
+ currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.stats.currentUtilization.value, assetInfo.stats.currentUtilization.decimals).toFixed(6)),
2387
+ maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.config.maxUtilization.value, assetInfo.config.maxUtilization.decimals).toFixed(6))
2388
+ };
2389
+ item.APY.netApy = item.APY.baseApy + item.APY.defiSpringApy;
2390
+ return item;
2391
+ });
2392
+ const data = await Promise.all(info);
2393
+ return {
2394
+ data,
2395
+ isErrorPositionsAPI,
2396
+ isErrorPoolsAPI,
2397
+ isError: isErrorPositionsAPI || isErrorPoolsAPI
2398
+ };
2399
+ }
2400
+ /**
2401
+ * Calculates the weighted average APY across all pools based on USD value.
2402
+ * @returns {Promise<number>} The weighted average APY across all pools
2403
+ */
2404
+ async netAPY() {
2405
+ const { data: pools } = await this.getPools();
2406
+ return this.netAPYGivenPools(pools);
2407
+ }
2408
+ /**
2409
+ * Calculates the weighted average APY across all pools based on USD value.
2410
+ * @returns {Promise<number>} The weighted average APY across all pools
2411
+ */
2412
+ netAPYGivenPools(pools) {
2413
+ const weightedApy = pools.reduce((acc, curr) => {
2414
+ const weight = curr.current_weight;
2415
+ return acc + curr.APY.netApy * weight;
2416
+ }, 0);
2417
+ return weightedApy;
2418
+ }
2419
+ /**
2420
+ * Calculates optimal position changes to maximize APY while respecting max weights.
2421
+ * The algorithm:
2422
+ * 1. Sorts pools by APY (highest first)
2423
+ * 2. Calculates target amounts based on max weights
2424
+ * 3. For each pool that needs more funds:
2425
+ * - Takes funds from lowest APY pools that are over their target
2426
+ * 4. Validates that total assets remain constant
2427
+ *
2428
+ * @returns {Promise<{
2429
+ * changes: Change[],
2430
+ * finalPools: PoolInfoFull[],
2431
+ * isAnyPoolOverMaxWeight: boolean
2432
+ * }>} Object containing:
2433
+ * - changes: Array of position changes
2434
+ * - finalPools: Array of pool information after rebalance
2435
+ * @throws Error if rebalance is not possible while maintaining constraints
2436
+ */
2437
+ async getRebalancedPositions() {
2438
+ const { data: pools } = await this.getPools();
2439
+ const totalAssets = (await this.getTVL()).amount;
2440
+ if (totalAssets.eq(0)) return {
2441
+ changes: [],
2442
+ finalPools: []
2443
+ };
2444
+ const sumPools = pools.reduce((acc, curr) => acc.plus(curr.amount.toString()), Web3Number.fromWei("0", this.decimals()));
2445
+ assert(sumPools.lte(totalAssets), "Sum of pools.amount must be less than or equal to totalAssets");
2446
+ const sortedPools = [...pools].sort((a, b) => b.APY.netApy - a.APY.netApy);
2447
+ const targetAmounts = {};
2448
+ let remainingAssets = totalAssets;
2449
+ let isAnyPoolOverMaxWeight = false;
2450
+ for (const pool of sortedPools) {
2451
+ const maxAmount = totalAssets.multipliedBy(pool.max_weight * 0.9);
2452
+ const targetAmount = remainingAssets.gte(maxAmount) ? maxAmount : remainingAssets;
2453
+ targetAmounts[pool.pool_id.address.toString()] = targetAmount;
2454
+ remainingAssets = remainingAssets.minus(targetAmount.toString());
2455
+ if (pool.current_weight > pool.max_weight) {
2456
+ isAnyPoolOverMaxWeight = true;
2457
+ }
2458
+ }
2459
+ assert(remainingAssets.lt(1e-5), "Remaining assets must be 0");
2460
+ const changes = sortedPools.map((pool) => {
2461
+ const target = targetAmounts[pool.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
2462
+ const change = Web3Number.fromWei(target.minus(pool.amount.toString()).toWei(), this.decimals());
2463
+ return {
2464
+ pool_id: pool.pool_id,
2465
+ changeAmt: change,
2466
+ finalAmt: target,
2467
+ isDeposit: change.gt(0)
2468
+ };
2469
+ });
2470
+ const sumChanges = changes.reduce((sum, c) => sum.plus(c.changeAmt.toString()), Web3Number.fromWei("0", this.decimals()));
2471
+ const sumFinal = changes.reduce((sum, c) => sum.plus(c.finalAmt.toString()), Web3Number.fromWei("0", this.decimals()));
2472
+ const hasChanges = changes.some((c) => !c.changeAmt.eq(0));
2473
+ if (!sumChanges.eq(0)) throw new Error("Sum of changes must be zero");
2474
+ if (!sumFinal.eq(totalAssets)) throw new Error("Sum of final amounts must equal total assets");
2475
+ if (!hasChanges) throw new Error("No changes required");
2476
+ const finalPools = pools.map((p) => {
2477
+ const target = targetAmounts[p.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
2478
+ return {
2479
+ ...p,
2480
+ amount: target,
2481
+ usdValue: Web3Number.fromWei("0", this.decimals())
2482
+ };
2483
+ });
2484
+ return {
2485
+ changes,
2486
+ finalPools,
2487
+ isAnyPoolOverMaxWeight
2488
+ };
2489
+ }
2490
+ /**
2491
+ * Creates a rebalance Call object for the strategy contract
2492
+ * @param pools - Array of pool information including IDs, weights, amounts, APYs and utilization
2493
+ * @returns Populated contract call for rebalance
2494
+ */
2495
+ async getRebalanceCall(pools, isOverWeightAdjustment) {
2496
+ const actions = [];
2497
+ pools.sort((a, b) => b.isDeposit ? -1 : 1);
2498
+ console.log("pools", pools);
2499
+ pools.forEach((p) => {
2500
+ if (p.changeAmt.eq(0)) return null;
2501
+ actions.push({
2502
+ pool_id: p.pool_id.address,
2503
+ feature: new import_starknet5.CairoCustomEnum(p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }),
2504
+ token: this.asset().address,
2505
+ amount: import_starknet5.uint256.bnToUint256(p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei())
2506
+ });
2507
+ });
2508
+ if (actions.length === 0) return null;
2509
+ if (isOverWeightAdjustment) {
2510
+ return this.contract.populate("rebalance_weights", [actions]);
2511
+ }
2512
+ return this.contract.populate("rebalance", [actions]);
2513
+ }
2514
+ };
2515
+ 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.";
2516
+ var _protocol = { name: "Vesu", logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png" };
2517
+ var VesuRebalanceStrategies = [{
2518
+ name: "Vesu STRK",
2519
+ description: _description.replace("{{TOKEN}}", "STRK"),
2520
+ address: ContractAddr.from("0xeeb729d554ae486387147b13a9c8871bc7991d454e8b5ff570d4bf94de71e1"),
2521
+ type: "ERC4626",
2522
+ depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "STRK")],
2523
+ protocols: [_protocol]
2524
+ }];
2525
+
2526
+ // src/notifs/telegram.ts
2527
+ var import_node_telegram_bot_api = __toESM(require("node-telegram-bot-api"));
2528
+ var TelegramNotif = class {
2529
+ constructor(token, shouldPoll) {
2530
+ this.subscribers = [
2531
+ // '6820228303',
2532
+ "1505578076",
2533
+ // '5434736198', // maaza
2534
+ "1356705582",
2535
+ // langs
2536
+ "1388729514",
2537
+ // hwashere
2538
+ "6020162572",
2539
+ //minato
2540
+ "985902592"
2541
+ ];
2542
+ this.bot = new import_node_telegram_bot_api.default(token, { polling: shouldPoll });
2543
+ }
2544
+ // listen to start msgs, register chatId and send registered msg
2545
+ activateChatBot() {
2546
+ this.bot.on("message", (msg) => {
2547
+ const chatId = msg.chat.id;
2548
+ let text = msg.text.toLowerCase().trim();
2549
+ logger.verbose(`Tg: IncomingMsg: ID: ${chatId}, msg: ${text}`);
2550
+ if (text == "start") {
2551
+ this.bot.sendMessage(chatId, "Registered");
2552
+ this.subscribers.push(chatId);
2553
+ logger.verbose(`Tg: New subscriber: ${chatId}`);
2554
+ } else {
2555
+ this.bot.sendMessage(chatId, "Unrecognized command. Supported commands: start");
2556
+ }
2557
+ });
2558
+ }
2559
+ // send a given msg to all registered users
2560
+ sendMessage(msg) {
2561
+ logger.verbose(`Tg: Sending message: ${msg}`);
2562
+ for (let chatId of this.subscribers) {
2563
+ this.bot.sendMessage(chatId, msg).catch((err) => {
2564
+ logger.error(`Tg: Error sending msg to ${chatId}`);
2565
+ logger.error(`Tg: Error sending message: ${err.message}`);
2566
+ }).then(() => {
2567
+ logger.verbose(`Tg: Message sent to ${chatId}`);
2568
+ });
2569
+ }
2570
+ }
2571
+ };
2572
+
2573
+ // src/node/pricer-redis.ts
2574
+ var import_redis = require("redis");
2575
+ var PricerRedis = class extends Pricer {
2576
+ constructor(config, tokens2) {
2577
+ super(config, tokens2);
2578
+ this.redisClient = null;
2579
+ }
2580
+ /** Reads prices from Pricer._loadPrices and uses a callback to set prices in redis */
2581
+ async startWithRedis(redisUrl) {
2582
+ await this.initRedis(redisUrl);
2583
+ logger.info(`Starting Pricer with Redis`);
2584
+ this._loadPrices(this._setRedisPrices.bind(this));
2585
+ setInterval(() => {
2586
+ this._loadPrices(this._setRedisPrices.bind(this));
2587
+ }, 3e4);
2588
+ }
2589
+ async close() {
2590
+ if (this.redisClient) {
2591
+ await this.redisClient.disconnect();
2592
+ }
2593
+ }
2594
+ async initRedis(redisUrl) {
2595
+ logger.info(`Initialising Redis Client`);
2596
+ this.redisClient = await (0, import_redis.createClient)({
2597
+ url: redisUrl
2598
+ });
2599
+ this.redisClient.on("error", (err) => console.log("Redis Client Error", err)).connect();
2600
+ logger.info(`Redis Client Initialised`);
2601
+ }
2602
+ /** sets current local price in redis */
2603
+ _setRedisPrices(tokenSymbol) {
2604
+ if (!this.redisClient) {
2605
+ throw new FatalError(`Redis client not initialised`);
2606
+ }
2607
+ this.redisClient.set(`Price:${tokenSymbol}`, JSON.stringify(this.prices[tokenSymbol])).catch((err) => {
2608
+ logger.warn(`Error setting price in redis for ${tokenSymbol}`);
2609
+ });
2610
+ }
2611
+ /** Returns price from redis */
2612
+ async getPrice(tokenSymbol) {
2613
+ const STALE_TIME = 6e4;
2614
+ if (!this.redisClient) {
2615
+ throw new FatalError(`Redis client not initialised`);
2616
+ }
2617
+ const data = await this.redisClient.get(`Price:${tokenSymbol}`);
2618
+ if (!data) {
2619
+ throw new FatalError(`Redis:Price of ${tokenSymbol} not found`);
2620
+ }
2621
+ logger.verbose(`Redis:Price of ${tokenSymbol} is ${data}`);
985
2622
  const priceInfo = JSON.parse(data);
986
2623
  priceInfo.timestamp = new Date(priceInfo.timestamp);
987
2624
  const isStale = (/* @__PURE__ */ new Date()).getTime() - priceInfo.timestamp.getTime() > STALE_TIME;
@@ -989,6 +2626,164 @@ var PricerRedis = class extends Pricer {
989
2626
  return priceInfo;
990
2627
  }
991
2628
  };
2629
+
2630
+ // src/utils/store.ts
2631
+ var import_fs = __toESM(require("fs"));
2632
+ var import_starknet6 = require("starknet");
2633
+ var crypto2 = __toESM(require("crypto"));
2634
+
2635
+ // src/utils/encrypt.ts
2636
+ var crypto = __toESM(require("crypto"));
2637
+ var PasswordJsonCryptoUtil = class {
2638
+ constructor() {
2639
+ this.algorithm = "aes-256-gcm";
2640
+ this.keyLength = 32;
2641
+ // 256 bits
2642
+ this.saltLength = 16;
2643
+ // 128 bits
2644
+ this.ivLength = 12;
2645
+ // 96 bits for GCM
2646
+ this.tagLength = 16;
2647
+ // 128 bits
2648
+ this.pbkdf2Iterations = 1e5;
2649
+ }
2650
+ // Number of iterations for PBKDF2
2651
+ deriveKey(password, salt) {
2652
+ return crypto.pbkdf2Sync(password, salt, this.pbkdf2Iterations, this.keyLength, "sha256");
2653
+ }
2654
+ encrypt(data, password) {
2655
+ const jsonString = JSON.stringify(data);
2656
+ const salt = crypto.randomBytes(this.saltLength);
2657
+ const iv = crypto.randomBytes(this.ivLength);
2658
+ const key = this.deriveKey(password, salt);
2659
+ const cipher = crypto.createCipheriv(this.algorithm, key, iv, { authTagLength: this.tagLength });
2660
+ let encrypted = cipher.update(jsonString, "utf8", "hex");
2661
+ encrypted += cipher.final("hex");
2662
+ const tag = cipher.getAuthTag();
2663
+ return Buffer.concat([salt, iv, tag, Buffer.from(encrypted, "hex")]).toString("base64");
2664
+ }
2665
+ decrypt(encryptedData, password) {
2666
+ const data = Buffer.from(encryptedData, "base64");
2667
+ const salt = data.subarray(0, this.saltLength);
2668
+ const iv = data.subarray(this.saltLength, this.saltLength + this.ivLength);
2669
+ const tag = data.subarray(this.saltLength + this.ivLength, this.saltLength + this.ivLength + this.tagLength);
2670
+ const encrypted = data.subarray(this.saltLength + this.ivLength + this.tagLength);
2671
+ const key = this.deriveKey(password, salt);
2672
+ const decipher = crypto.createDecipheriv(this.algorithm, key, iv, { authTagLength: this.tagLength });
2673
+ decipher.setAuthTag(tag);
2674
+ try {
2675
+ let decrypted = decipher.update(encrypted.toString("hex"), "hex", "utf8");
2676
+ decrypted += decipher.final("utf8");
2677
+ return JSON.parse(decrypted);
2678
+ } catch (error) {
2679
+ throw new Error("Decryption failed. This could be due to an incorrect password or corrupted data.");
2680
+ }
2681
+ }
2682
+ };
2683
+
2684
+ // src/utils/store.ts
2685
+ function getDefaultStoreConfig(network) {
2686
+ if (!process.env.HOME) {
2687
+ throw new Error("StoreConfig: HOME environment variable not found");
2688
+ }
2689
+ return {
2690
+ SECRET_FILE_FOLDER: `${process.env.HOME}/.starknet-store`,
2691
+ NETWORK: network,
2692
+ ACCOUNTS_FILE_NAME: "accounts.json",
2693
+ PASSWORD: crypto2.randomBytes(16).toString("hex")
2694
+ };
2695
+ }
2696
+ var Store = class _Store {
2697
+ constructor(config, storeConfig) {
2698
+ this.encryptor = new PasswordJsonCryptoUtil();
2699
+ this.config = config;
2700
+ const defaultStoreConfig = getDefaultStoreConfig(config.network);
2701
+ if (!storeConfig.PASSWORD) {
2702
+ _Store.logPassword(defaultStoreConfig.PASSWORD);
2703
+ }
2704
+ this.storeConfig = {
2705
+ ...defaultStoreConfig,
2706
+ ...storeConfig
2707
+ };
2708
+ _Store.ensureFolder(this.storeConfig.SECRET_FILE_FOLDER);
2709
+ }
2710
+ static logPassword(password) {
2711
+ logger.warn(`\u26A0\uFE0F=========================================\u26A0\uFE0F`);
2712
+ logger.warn(`Generated a random password for store`);
2713
+ logger.warn(`\u26A0\uFE0F Password: ${password}`);
2714
+ logger.warn(`This not stored anywhere, please you backup this password for future use`);
2715
+ logger.warn(`\u26A0\uFE0F=========================================\u26A0\uFE0F`);
2716
+ }
2717
+ getAccount(accountKey, txVersion = import_starknet6.constants.TRANSACTION_VERSION.V2) {
2718
+ const accounts = this.loadAccounts();
2719
+ logger.verbose(`nAccounts loaded for network: ${Object.keys(accounts).length}`);
2720
+ const data = accounts[accountKey];
2721
+ if (!data) {
2722
+ throw new Error(`Account not found: ${accountKey}`);
2723
+ }
2724
+ logger.verbose(`Account loaded: ${accountKey} from network: ${this.config.network}`);
2725
+ logger.verbose(`Address: ${data.address}`);
2726
+ const acc = new import_starknet6.Account(this.config.provider, data.address, data.pk, void 0, txVersion);
2727
+ return acc;
2728
+ }
2729
+ addAccount(accountKey, address, pk) {
2730
+ const allAccounts = this.getAllAccounts();
2731
+ if (!allAccounts[this.config.network]) {
2732
+ allAccounts[this.config.network] = {};
2733
+ }
2734
+ allAccounts[this.config.network][accountKey] = {
2735
+ address,
2736
+ pk
2737
+ };
2738
+ const encryptedData = this.encryptor.encrypt(allAccounts, this.storeConfig.PASSWORD);
2739
+ (0, import_fs.writeFileSync)(this.getAccountFilePath(), encryptedData);
2740
+ logger.verbose(`Account added: ${accountKey} to network: ${this.config.network}`);
2741
+ }
2742
+ getAccountFilePath() {
2743
+ const path = `${this.storeConfig.SECRET_FILE_FOLDER}/${this.storeConfig.ACCOUNTS_FILE_NAME}`;
2744
+ logger.verbose(`Path: ${path}`);
2745
+ return path;
2746
+ }
2747
+ getAllAccounts() {
2748
+ const PATH = this.getAccountFilePath();
2749
+ if (!import_fs.default.existsSync(PATH)) {
2750
+ logger.verbose(`Accounts: files doesnt exist`);
2751
+ return {};
2752
+ }
2753
+ let encryptedData = (0, import_fs.readFileSync)(PATH, {
2754
+ encoding: "utf-8"
2755
+ });
2756
+ let data = this.encryptor.decrypt(encryptedData, this.storeConfig.PASSWORD);
2757
+ return data;
2758
+ }
2759
+ /**
2760
+ * @description Load all accounts of the network
2761
+ * @returns NetworkAccounts
2762
+ */
2763
+ loadAccounts() {
2764
+ const allData = this.getAllAccounts();
2765
+ logger.verbose(`Accounts loaded for network: ${this.config.network}`);
2766
+ if (!allData[this.config.network]) {
2767
+ allData[this.config.network] = {};
2768
+ }
2769
+ return allData[this.config.network];
2770
+ }
2771
+ /**
2772
+ * @description List all accountKeys of the network
2773
+ * @returns string[]
2774
+ */
2775
+ listAccounts() {
2776
+ return Object.keys(this.loadAccounts());
2777
+ }
2778
+ static ensureFolder(folder) {
2779
+ if (!import_fs.default.existsSync(folder)) {
2780
+ import_fs.default.mkdirSync(folder, { recursive: true });
2781
+ }
2782
+ if (!import_fs.default.existsSync(`${folder}`)) {
2783
+ throw new Error(`Store folder not found: ${folder}`);
2784
+ }
2785
+ }
2786
+ };
992
2787
  // Annotate the CommonJS export names for ESM import in node:
993
2788
  0 && (module.exports = {
994
2789
  AutoCompounderSTRK,
@@ -1002,11 +2797,15 @@ var PricerRedis = class extends Pricer {
1002
2797
  PasswordJsonCryptoUtil,
1003
2798
  Pragma,
1004
2799
  Pricer,
2800
+ PricerBase,
1005
2801
  PricerRedis,
1006
2802
  Store,
1007
2803
  TelegramNotif,
2804
+ VesuRebalance,
2805
+ VesuRebalanceStrategies,
1008
2806
  Web3Number,
1009
2807
  ZkLend,
2808
+ assert,
1010
2809
  getDefaultStoreConfig,
1011
2810
  getMainnetConfig,
1012
2811
  logger