@strkfarm/sdk 1.0.62 → 1.0.63
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.browser.global.js +457 -308
- package/dist/index.browser.mjs +154 -5
- package/dist/index.d.ts +21 -2
- package/dist/index.js +152 -3
- package/dist/index.mjs +154 -5
- package/package.json +1 -1
- package/src/modules/harvests.ts +4 -2
- package/src/strategies/universal-adapters/adapter-utils.ts +3 -1
- package/src/strategies/universal-adapters/common-adapter.ts +57 -1
- package/src/strategies/universal-adapters/vesu-adapter.ts +39 -0
- package/src/strategies/universal-strategy.tsx +78 -5
package/dist/index.mjs
CHANGED
|
@@ -3890,11 +3890,12 @@ var EkuboHarvests = class extends Harvests {
|
|
|
3890
3890
|
return rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
|
|
3891
3891
|
}
|
|
3892
3892
|
};
|
|
3893
|
+
var VESU_REWARDS_CONTRACT = ContractAddr.from("0x0387f3eb1d98632fbe3440a9f1385Aec9d87b6172491d3Dd81f1c35A7c61048F");
|
|
3893
3894
|
var VesuHarvests = class _VesuHarvests extends Harvests {
|
|
3894
3895
|
async getHarvests(addr) {
|
|
3895
3896
|
const result = await fetch(`https://api.vesu.xyz/users/${addr.address}/strk-rewards/calldata`);
|
|
3896
3897
|
const data = await result.json();
|
|
3897
|
-
const rewardsContract =
|
|
3898
|
+
const rewardsContract = VESU_REWARDS_CONTRACT;
|
|
3898
3899
|
const cls = await this.config.provider.getClassAt(rewardsContract.address);
|
|
3899
3900
|
const contract = new Contract4(cls.abi, rewardsContract.address, this.config.provider);
|
|
3900
3901
|
const _claimed_amount = await contract.call("amount_already_claimed", [addr.address]);
|
|
@@ -18486,7 +18487,9 @@ var SenseiStrategies = [
|
|
|
18486
18487
|
import { hash, num as num6, shortString } from "starknet";
|
|
18487
18488
|
|
|
18488
18489
|
// src/strategies/universal-adapters/adapter-utils.ts
|
|
18489
|
-
var SIMPLE_SANITIZER = ContractAddr.from("
|
|
18490
|
+
var SIMPLE_SANITIZER = ContractAddr.from("0x5a2e3ceb3da368b983a8717898427ab7b6daf04014b70f321e777f9aad940b4");
|
|
18491
|
+
var PRICE_ROUTER = ContractAddr.from("0x05e83Fa38D791d2dba8E6f487758A9687FfEe191A6Cf8a6c5761ab0a110DB837");
|
|
18492
|
+
var AVNU_MIDDLEWARE = ContractAddr.from("0x4a7972ed3f5d1e74a6d6c4a8f467666953d081c8f2270390cc169d50d17cb0d");
|
|
18490
18493
|
function toBigInt(value) {
|
|
18491
18494
|
if (typeof value === "string") {
|
|
18492
18495
|
return BigInt(value);
|
|
@@ -18519,7 +18522,7 @@ var BaseAdapter = class extends CacheClass {
|
|
|
18519
18522
|
};
|
|
18520
18523
|
|
|
18521
18524
|
// src/strategies/universal-adapters/common-adapter.ts
|
|
18522
|
-
import { hash as hash2, uint256 as uint2566 } from "starknet";
|
|
18525
|
+
import { hash as hash2, num as num7, uint256 as uint2566 } from "starknet";
|
|
18523
18526
|
var CommonAdapter = class extends BaseAdapter {
|
|
18524
18527
|
constructor(config) {
|
|
18525
18528
|
super();
|
|
@@ -18630,10 +18633,70 @@ var CommonAdapter = class extends BaseAdapter {
|
|
|
18630
18633
|
};
|
|
18631
18634
|
};
|
|
18632
18635
|
}
|
|
18636
|
+
getAvnuAdapter(fromToken, toToken, id) {
|
|
18637
|
+
return () => ({
|
|
18638
|
+
leaf: this.constructSimpleLeafData({
|
|
18639
|
+
id,
|
|
18640
|
+
target: AVNU_MIDDLEWARE,
|
|
18641
|
+
method: "multi_route_swap",
|
|
18642
|
+
packedArguments: [
|
|
18643
|
+
fromToken.toBigInt(),
|
|
18644
|
+
toToken.toBigInt(),
|
|
18645
|
+
this.config.vaultAllocator.toBigInt()
|
|
18646
|
+
]
|
|
18647
|
+
}),
|
|
18648
|
+
callConstructor: this.getAvnuCall(fromToken, toToken).bind(this)
|
|
18649
|
+
});
|
|
18650
|
+
}
|
|
18651
|
+
getAvnuCall(fromToken, toToken) {
|
|
18652
|
+
return (params) => {
|
|
18653
|
+
return {
|
|
18654
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
18655
|
+
call: {
|
|
18656
|
+
contractAddress: AVNU_MIDDLEWARE,
|
|
18657
|
+
selector: hash2.getSelectorFromName("multi_route_swap"),
|
|
18658
|
+
calldata: [
|
|
18659
|
+
fromToken.toBigInt(),
|
|
18660
|
+
// sell_token_address
|
|
18661
|
+
toBigInt(params.props.token_from_amount.low.toString()),
|
|
18662
|
+
// sell_token_amount low
|
|
18663
|
+
toBigInt(params.props.token_from_amount.high.toString()),
|
|
18664
|
+
// sell_token_amount high
|
|
18665
|
+
toToken.toBigInt(),
|
|
18666
|
+
// buy_token_address
|
|
18667
|
+
toBigInt(params.props.token_to_amount.low.toString()),
|
|
18668
|
+
// buy_token_amount low
|
|
18669
|
+
toBigInt(params.props.token_to_amount.high.toString()),
|
|
18670
|
+
// buy_token_amount high
|
|
18671
|
+
toBigInt(params.props.token_to_min_amount.low.toString()),
|
|
18672
|
+
// buy_token_min_amount low
|
|
18673
|
+
toBigInt(params.props.token_to_min_amount.high.toString()),
|
|
18674
|
+
// buy_token_min_amount high
|
|
18675
|
+
this.config.vaultAllocator.toBigInt(),
|
|
18676
|
+
// beneficiary
|
|
18677
|
+
toBigInt(0),
|
|
18678
|
+
// integrator_fee_amount_bps
|
|
18679
|
+
this.config.vaultAllocator.toBigInt(),
|
|
18680
|
+
// integrator_fee_recipient
|
|
18681
|
+
// unpack routes
|
|
18682
|
+
BigInt(params.props.routes.length),
|
|
18683
|
+
...params.props.routes.map((r) => [
|
|
18684
|
+
BigInt(num7.hexToDecimalString(r.token_from)),
|
|
18685
|
+
BigInt(num7.hexToDecimalString(r.token_to)),
|
|
18686
|
+
BigInt(num7.hexToDecimalString(r.exchange_address)),
|
|
18687
|
+
BigInt(r.percent),
|
|
18688
|
+
BigInt(r.additional_swap_params.length),
|
|
18689
|
+
...r.additional_swap_params.map((p) => BigInt(num7.hexToDecimalString(p)))
|
|
18690
|
+
]).flat()
|
|
18691
|
+
]
|
|
18692
|
+
}
|
|
18693
|
+
};
|
|
18694
|
+
};
|
|
18695
|
+
}
|
|
18633
18696
|
};
|
|
18634
18697
|
|
|
18635
18698
|
// src/strategies/universal-adapters/vesu-adapter.ts
|
|
18636
|
-
import { CairoCustomEnum as CairoCustomEnum2, Contract as Contract8, hash as hash3, RpcProvider as RpcProvider4, uint256 as uint2567 } from "starknet";
|
|
18699
|
+
import { CairoCustomEnum as CairoCustomEnum2, Contract as Contract8, hash as hash3, num as num8, RpcProvider as RpcProvider4, shortString as shortString3, uint256 as uint2567 } from "starknet";
|
|
18637
18700
|
|
|
18638
18701
|
// src/data/vesu-singleton.abi.json
|
|
18639
18702
|
var vesu_singleton_abi_default = [
|
|
@@ -20966,6 +21029,40 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
20966
21029
|
}
|
|
20967
21030
|
};
|
|
20968
21031
|
};
|
|
21032
|
+
this.getDefispringRewardsAdapter = (id) => {
|
|
21033
|
+
return () => {
|
|
21034
|
+
const packedArguments = [];
|
|
21035
|
+
const output = {
|
|
21036
|
+
id: BigInt(num8.getDecimalString(shortString3.encodeShortString(id))),
|
|
21037
|
+
readableId: id,
|
|
21038
|
+
data: [
|
|
21039
|
+
SIMPLE_SANITIZER.toBigInt(),
|
|
21040
|
+
// sanitizer address
|
|
21041
|
+
VESU_REWARDS_CONTRACT.toBigInt(),
|
|
21042
|
+
// contract
|
|
21043
|
+
toBigInt(hash3.getSelectorFromName("claim")),
|
|
21044
|
+
// method name
|
|
21045
|
+
BigInt(packedArguments.length),
|
|
21046
|
+
...packedArguments
|
|
21047
|
+
]
|
|
21048
|
+
};
|
|
21049
|
+
return { leaf: output, callConstructor: this.getDefiSpringClaimCall().bind(this) };
|
|
21050
|
+
};
|
|
21051
|
+
};
|
|
21052
|
+
this.getDefiSpringClaimCall = () => {
|
|
21053
|
+
return (params) => ({
|
|
21054
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
21055
|
+
call: {
|
|
21056
|
+
contractAddress: VESU_REWARDS_CONTRACT,
|
|
21057
|
+
selector: hash3.getSelectorFromName("claim"),
|
|
21058
|
+
calldata: [
|
|
21059
|
+
BigInt(params.amount.toWei()),
|
|
21060
|
+
BigInt(params.proofs.length),
|
|
21061
|
+
...params.proofs.map((proof) => BigInt(num8.hexToDecimalString(proof)))
|
|
21062
|
+
]
|
|
21063
|
+
}
|
|
21064
|
+
});
|
|
21065
|
+
};
|
|
20969
21066
|
this.config = config;
|
|
20970
21067
|
}
|
|
20971
21068
|
static getDefaultModifyPositionCallParams(params) {
|
|
@@ -23595,7 +23692,7 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
23595
23692
|
const aumToken = vesuAum.plus(balance.amount);
|
|
23596
23693
|
logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
|
|
23597
23694
|
const netAPY = await this.netAPY();
|
|
23598
|
-
const defispringAPY = netAPY.splits.find((s) => s.id === "defispring")?.apy || 0;
|
|
23695
|
+
const defispringAPY = (netAPY.splits.find((s) => s.id === "defispring")?.apy || 0) * 0.8;
|
|
23599
23696
|
if (!defispringAPY) throw new Error("DefiSpring APY not found");
|
|
23600
23697
|
const timeDiff = Math.round(Date.now() / 1e3) - Number(lastReportTime);
|
|
23601
23698
|
const growthRate = timeDiff * defispringAPY / (365 * 24 * 60 * 60);
|
|
@@ -23838,6 +23935,51 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
23838
23935
|
const manageCall = this.getManageCall(["approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */, "bring_liquidity" /* BRING_LIQUIDITY */], [manageCall1, manageCall2]);
|
|
23839
23936
|
return manageCall;
|
|
23840
23937
|
}
|
|
23938
|
+
async getHarvestCall() {
|
|
23939
|
+
const vesuHarvest = new VesuHarvests(this.config);
|
|
23940
|
+
const harvestInfo = await vesuHarvest.getUnHarvestedRewards(this.metadata.additionalInfo.vaultAllocator);
|
|
23941
|
+
if (harvestInfo.length != 1) {
|
|
23942
|
+
throw new Error(`Expected 1 harvest info, got ${harvestInfo.length}`);
|
|
23943
|
+
}
|
|
23944
|
+
const amount = harvestInfo[0].claim.amount;
|
|
23945
|
+
const actualReward = harvestInfo[0].actualReward;
|
|
23946
|
+
const proofs = harvestInfo[0].proof;
|
|
23947
|
+
if (actualReward.isZero()) {
|
|
23948
|
+
throw new Error(`Expected non-zero actual reward, got ${harvestInfo[0].actualReward}`);
|
|
23949
|
+
}
|
|
23950
|
+
const manage1Info = this.getProofs("defispring_rewards" /* DEFISPRING_REWARDS */);
|
|
23951
|
+
const manageCall1 = manage1Info.callConstructor({
|
|
23952
|
+
amount,
|
|
23953
|
+
proofs
|
|
23954
|
+
});
|
|
23955
|
+
const proofIds = ["defispring_rewards" /* DEFISPRING_REWARDS */];
|
|
23956
|
+
const manageCalls = [manageCall1];
|
|
23957
|
+
const STRK2 = Global.getDefaultTokens().find((t) => t.symbol === "STRK");
|
|
23958
|
+
if (this.asset().symbol != "STRK") {
|
|
23959
|
+
const manage2Info = this.getProofs("approve_swap_token1" /* APPROVE_SWAP_TOKEN1 */);
|
|
23960
|
+
const manageCall2 = manage2Info.callConstructor({
|
|
23961
|
+
amount: actualReward
|
|
23962
|
+
});
|
|
23963
|
+
const avnuModule = new AvnuWrapper();
|
|
23964
|
+
const quote = await avnuModule.getQuotes(
|
|
23965
|
+
STRK2.address.address,
|
|
23966
|
+
this.asset().address.address,
|
|
23967
|
+
actualReward.toWei(),
|
|
23968
|
+
this.address.address
|
|
23969
|
+
);
|
|
23970
|
+
const swapInfo = await avnuModule.getSwapInfo(quote, this.address.address, 0, this.address.address);
|
|
23971
|
+
const manage3Info = this.getProofs("avnu_swap_rewards" /* AVNU_SWAP_REWARDS */);
|
|
23972
|
+
const manageCall3 = manage3Info.callConstructor({
|
|
23973
|
+
props: swapInfo
|
|
23974
|
+
});
|
|
23975
|
+
proofIds.push("approve_swap_token1" /* APPROVE_SWAP_TOKEN1 */);
|
|
23976
|
+
proofIds.push("avnu_swap_rewards" /* AVNU_SWAP_REWARDS */);
|
|
23977
|
+
manageCalls.push(manageCall2);
|
|
23978
|
+
manageCalls.push(manageCall3);
|
|
23979
|
+
}
|
|
23980
|
+
const manageCall = this.getManageCall(proofIds, manageCalls);
|
|
23981
|
+
return { call: manageCall, reward: actualReward, tokenInfo: STRK2 };
|
|
23982
|
+
}
|
|
23841
23983
|
async getRebalanceCall(params) {
|
|
23842
23984
|
let callSet1 = this.getVesuModifyPositionCalls({
|
|
23843
23985
|
isLeg1: true,
|
|
@@ -23874,6 +24016,9 @@ var UNIVERSAL_MANAGE_IDS = /* @__PURE__ */ ((UNIVERSAL_MANAGE_IDS2) => {
|
|
|
23874
24016
|
UNIVERSAL_MANAGE_IDS2["APPROVE_TOKEN2"] = "approve_token2";
|
|
23875
24017
|
UNIVERSAL_MANAGE_IDS2["APPROVE_BRING_LIQUIDITY"] = "approve_bring_liquidity";
|
|
23876
24018
|
UNIVERSAL_MANAGE_IDS2["BRING_LIQUIDITY"] = "bring_liquidity";
|
|
24019
|
+
UNIVERSAL_MANAGE_IDS2["DEFISPRING_REWARDS"] = "defispring_rewards";
|
|
24020
|
+
UNIVERSAL_MANAGE_IDS2["APPROVE_SWAP_TOKEN1"] = "approve_swap_token1";
|
|
24021
|
+
UNIVERSAL_MANAGE_IDS2["AVNU_SWAP_REWARDS"] = "avnu_swap_rewards";
|
|
23877
24022
|
return UNIVERSAL_MANAGE_IDS2;
|
|
23878
24023
|
})(UNIVERSAL_MANAGE_IDS || {});
|
|
23879
24024
|
var UNIVERSAL_ADAPTERS = /* @__PURE__ */ ((UNIVERSAL_ADAPTERS2) => {
|
|
@@ -23923,6 +24068,10 @@ function getLooperSettings(token1Symbol, token2Symbol, vaultSettings, pool1, poo
|
|
|
23923
24068
|
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(ETHToken.address, vesuAdapterETHUSDC.VESU_SINGLETON, "approve_token2" /* APPROVE_TOKEN2 */).bind(commonAdapter));
|
|
23924
24069
|
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(USDCToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
|
|
23925
24070
|
vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
|
|
24071
|
+
vaultSettings.leafAdapters.push(vesuAdapterUSDCETH.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterUSDCETH));
|
|
24072
|
+
const STRKToken = Global.getDefaultTokens().find((token) => token.symbol === "STRK");
|
|
24073
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address, AVNU_MIDDLEWARE, "approve_swap_token1" /* APPROVE_SWAP_TOKEN1 */).bind(commonAdapter));
|
|
24074
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, USDCToken.address, "avnu_swap_rewards" /* AVNU_SWAP_REWARDS */).bind(commonAdapter));
|
|
23926
24075
|
return vaultSettings;
|
|
23927
24076
|
}
|
|
23928
24077
|
var _riskFactor4 = [
|
package/package.json
CHANGED
package/src/modules/harvests.ts
CHANGED
|
@@ -83,12 +83,14 @@ export class EkuboHarvests extends Harvests {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
export const VESU_REWARDS_CONTRACT = ContractAddr.from('0x0387f3eb1d98632fbe3440a9f1385Aec9d87b6172491d3Dd81f1c35A7c61048F');
|
|
87
|
+
|
|
86
88
|
export class VesuHarvests extends Harvests {
|
|
87
89
|
async getHarvests(addr: ContractAddr): Promise<HarvestInfo[]> {
|
|
88
90
|
const result = await fetch(`https://api.vesu.xyz/users/${addr.address}/strk-rewards/calldata`);
|
|
89
91
|
const data = await result.json();
|
|
90
|
-
const rewardsContract =
|
|
91
|
-
|
|
92
|
+
const rewardsContract = VESU_REWARDS_CONTRACT;
|
|
93
|
+
|
|
92
94
|
// get already claimed amount
|
|
93
95
|
const cls = await this.config.provider.getClassAt(rewardsContract.address);
|
|
94
96
|
const contract = new Contract(cls.abi, rewardsContract.address, this.config.provider);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ContractAddr } from "@/dataTypes";
|
|
2
2
|
|
|
3
|
-
export const SIMPLE_SANITIZER = ContractAddr.from('
|
|
3
|
+
export const SIMPLE_SANITIZER = ContractAddr.from('0x5a2e3ceb3da368b983a8717898427ab7b6daf04014b70f321e777f9aad940b4');
|
|
4
|
+
export const PRICE_ROUTER = ContractAddr.from('0x05e83Fa38D791d2dba8E6f487758A9687FfEe191A6Cf8a6c5761ab0a110DB837');
|
|
5
|
+
export const AVNU_MIDDLEWARE = ContractAddr.from('0x4a7972ed3f5d1e74a6d6c4a8f467666953d081c8f2270390cc169d50d17cb0d');
|
|
4
6
|
|
|
5
7
|
export function toBigInt(value: string | number): bigint {
|
|
6
8
|
if (typeof value === 'string') {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ContractAddr, Web3Number } from "@/dataTypes";
|
|
2
2
|
import { LeafData } from "@/utils";
|
|
3
3
|
import { Call, hash, num, shortString, uint256 } from "starknet";
|
|
4
|
-
import { SIMPLE_SANITIZER, toBigInt } from "./adapter-utils";
|
|
4
|
+
import { AVNU_MIDDLEWARE, SIMPLE_SANITIZER, toBigInt } from "./adapter-utils";
|
|
5
5
|
import { AdapterLeafType, BaseAdapter, GenerateCallFn, LeafAdapterFn, ManageCall } from "./baseAdapter";
|
|
6
|
+
import { SwapInfo } from "@/modules";
|
|
6
7
|
|
|
7
8
|
export interface FlashloanCallParams {
|
|
8
9
|
amount: Web3Number,
|
|
@@ -11,6 +12,9 @@ export interface FlashloanCallParams {
|
|
|
11
12
|
export interface ApproveCallParams {
|
|
12
13
|
amount: Web3Number,
|
|
13
14
|
}
|
|
15
|
+
export interface AvnuSwapCallParams {
|
|
16
|
+
props: SwapInfo
|
|
17
|
+
}
|
|
14
18
|
|
|
15
19
|
export interface CommonAdapterConfig {
|
|
16
20
|
id: string,
|
|
@@ -124,4 +128,56 @@ export class CommonAdapter extends BaseAdapter {
|
|
|
124
128
|
}
|
|
125
129
|
}
|
|
126
130
|
}
|
|
131
|
+
|
|
132
|
+
getAvnuAdapter(fromToken: ContractAddr, toToken: ContractAddr, id: string): () => AdapterLeafType<AvnuSwapCallParams> {
|
|
133
|
+
return () => ({
|
|
134
|
+
leaf: this.constructSimpleLeafData({
|
|
135
|
+
id: id,
|
|
136
|
+
target: AVNU_MIDDLEWARE,
|
|
137
|
+
method: 'multi_route_swap',
|
|
138
|
+
packedArguments: [
|
|
139
|
+
fromToken.toBigInt(),
|
|
140
|
+
toToken.toBigInt(),
|
|
141
|
+
this.config.vaultAllocator.toBigInt(),
|
|
142
|
+
]
|
|
143
|
+
}),
|
|
144
|
+
callConstructor: this.getAvnuCall(fromToken, toToken).bind(this)
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
getAvnuCall(fromToken: ContractAddr, toToken: ContractAddr): GenerateCallFn<AvnuSwapCallParams> {
|
|
149
|
+
return (params: AvnuSwapCallParams): ManageCall => {
|
|
150
|
+
return {
|
|
151
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
152
|
+
call: {
|
|
153
|
+
contractAddress: AVNU_MIDDLEWARE,
|
|
154
|
+
selector: hash.getSelectorFromName('multi_route_swap'),
|
|
155
|
+
calldata: [
|
|
156
|
+
fromToken.toBigInt(), // sell_token_address
|
|
157
|
+
toBigInt(params.props.token_from_amount.low.toString()), // sell_token_amount low
|
|
158
|
+
toBigInt(params.props.token_from_amount.high.toString()), // sell_token_amount high
|
|
159
|
+
toToken.toBigInt(), // buy_token_address
|
|
160
|
+
toBigInt(params.props.token_to_amount.low.toString()), // buy_token_amount low
|
|
161
|
+
toBigInt(params.props.token_to_amount.high.toString()), // buy_token_amount high
|
|
162
|
+
toBigInt(params.props.token_to_min_amount.low.toString()), // buy_token_min_amount low
|
|
163
|
+
toBigInt(params.props.token_to_min_amount.high.toString()), // buy_token_min_amount high
|
|
164
|
+
this.config.vaultAllocator.toBigInt(), // beneficiary
|
|
165
|
+
toBigInt(0), // integrator_fee_amount_bps
|
|
166
|
+
this.config.vaultAllocator.toBigInt(), // integrator_fee_recipient
|
|
167
|
+
|
|
168
|
+
// unpack routes
|
|
169
|
+
BigInt(params.props.routes.length),
|
|
170
|
+
...params.props.routes.map(r => ([
|
|
171
|
+
BigInt(num.hexToDecimalString(r.token_from)),
|
|
172
|
+
BigInt(num.hexToDecimalString(r.token_to)),
|
|
173
|
+
BigInt(num.hexToDecimalString(r.exchange_address)),
|
|
174
|
+
BigInt(r.percent),
|
|
175
|
+
BigInt(r.additional_swap_params.length),
|
|
176
|
+
...r.additional_swap_params.map(p => BigInt(num.hexToDecimalString(p)))
|
|
177
|
+
])).flat()
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
127
183
|
}
|
|
@@ -9,6 +9,7 @@ import { PricerBase } from "@/modules/pricerBase";
|
|
|
9
9
|
import VesuPoolIDs from "@/data/vesu_pools.json";
|
|
10
10
|
import { getAPIUsingHeadlessBrowser } from "@/node/headless";
|
|
11
11
|
import { Global } from "@/global";
|
|
12
|
+
import { VESU_REWARDS_CONTRACT } from "@/modules/harvests";
|
|
12
13
|
|
|
13
14
|
interface VesuPoolsInfo { pools: any[]; isErrorPoolsAPI: boolean };
|
|
14
15
|
|
|
@@ -38,6 +39,11 @@ export interface VesuModifyPositionCallParams {
|
|
|
38
39
|
debtAmount: VesuAmount
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
export interface VesuDefiSpringRewardsCallParams {
|
|
43
|
+
amount: Web3Number,
|
|
44
|
+
proofs: string[],
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
export interface VesuAdapterConfig {
|
|
42
48
|
poolId: ContractAddr,
|
|
43
49
|
collateral: TokenInfo,
|
|
@@ -156,6 +162,39 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
156
162
|
}
|
|
157
163
|
}
|
|
158
164
|
}
|
|
165
|
+
|
|
166
|
+
getDefispringRewardsAdapter = (id: string): () => AdapterLeafType<VesuDefiSpringRewardsCallParams> => {
|
|
167
|
+
return () => {
|
|
168
|
+
const packedArguments: bigint[] = [];
|
|
169
|
+
const output = {
|
|
170
|
+
id: BigInt(num.getDecimalString(shortString.encodeShortString(id))),
|
|
171
|
+
readableId: id,
|
|
172
|
+
data: [
|
|
173
|
+
SIMPLE_SANITIZER.toBigInt(), // sanitizer address
|
|
174
|
+
VESU_REWARDS_CONTRACT.toBigInt(), // contract
|
|
175
|
+
toBigInt(hash.getSelectorFromName("claim")), // method name
|
|
176
|
+
BigInt(packedArguments.length),
|
|
177
|
+
...packedArguments
|
|
178
|
+
]
|
|
179
|
+
};
|
|
180
|
+
return { leaf: output, callConstructor: this.getDefiSpringClaimCall().bind(this) };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
getDefiSpringClaimCall = (): GenerateCallFn<VesuDefiSpringRewardsCallParams> => {
|
|
185
|
+
return (params: VesuDefiSpringRewardsCallParams) => ({
|
|
186
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
187
|
+
call: {
|
|
188
|
+
contractAddress: VESU_REWARDS_CONTRACT,
|
|
189
|
+
selector: hash.getSelectorFromName('claim'),
|
|
190
|
+
calldata: [
|
|
191
|
+
BigInt(params.amount.toWei()),
|
|
192
|
+
BigInt(params.proofs.length),
|
|
193
|
+
...params.proofs.map(proof => BigInt(num.hexToDecimalString(proof)))
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
}
|
|
159
198
|
|
|
160
199
|
formatAmountTypeEnum(amountType: VesuAmountType) {
|
|
161
200
|
switch(amountType) {
|
|
@@ -7,9 +7,11 @@ import { VesuRebalanceSettings } from "./vesu-rebalance";
|
|
|
7
7
|
import { assert, LeafData, logger, StandardMerkleTree } from "@/utils";
|
|
8
8
|
import UniversalVaultAbi from '../data/universal-vault.abi.json';
|
|
9
9
|
import ManagerAbi from '../data/vault-manager.abi.json';
|
|
10
|
-
import { ApproveCallParams, BaseAdapter, CommonAdapter, FlashloanCallParams, GenerateCallFn, LeafAdapterFn, ManageCall, VesuAdapter, VesuModifyPositionCallParams, VesuPools } from "./universal-adapters";
|
|
10
|
+
import { ApproveCallParams, AvnuSwapCallParams, BaseAdapter, CommonAdapter, FlashloanCallParams, GenerateCallFn, LeafAdapterFn, ManageCall, VesuAdapter, VesuDefiSpringRewardsCallParams, VesuModifyPositionCallParams, VesuPools } from "./universal-adapters";
|
|
11
11
|
import { Global } from "@/global";
|
|
12
|
-
import { ERC20 } from "@/modules";
|
|
12
|
+
import { AvnuWrapper, ERC20 } from "@/modules";
|
|
13
|
+
import { AVNU_MIDDLEWARE } from "./universal-adapters/adapter-utils";
|
|
14
|
+
import { VesuHarvests } from "@/modules/harvests";
|
|
13
15
|
|
|
14
16
|
export interface UniversalStrategySettings {
|
|
15
17
|
vaultAddress: ContractAddr,
|
|
@@ -312,7 +314,8 @@ export class UniversalStrategy<
|
|
|
312
314
|
|
|
313
315
|
// calculate estimated growth from strk rewards
|
|
314
316
|
const netAPY = await this.netAPY();
|
|
315
|
-
|
|
317
|
+
// account only 80% of value
|
|
318
|
+
const defispringAPY = (netAPY.splits.find(s => s.id === 'defispring')?.apy || 0) * 0.8;
|
|
316
319
|
if (!defispringAPY) throw new Error('DefiSpring APY not found');
|
|
317
320
|
|
|
318
321
|
const timeDiff = (Math.round(Date.now() / 1000) - Number(lastReportTime));
|
|
@@ -605,6 +608,61 @@ export class UniversalStrategy<
|
|
|
605
608
|
return manageCall;
|
|
606
609
|
}
|
|
607
610
|
|
|
611
|
+
async getHarvestCall() {
|
|
612
|
+
const vesuHarvest = new VesuHarvests(this.config);
|
|
613
|
+
const harvestInfo = await vesuHarvest.getUnHarvestedRewards(this.metadata.additionalInfo.vaultAllocator);
|
|
614
|
+
if (harvestInfo.length != 1) {
|
|
615
|
+
throw new Error(`Expected 1 harvest info, got ${harvestInfo.length}`);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
const amount = harvestInfo[0].claim.amount;
|
|
619
|
+
const actualReward = harvestInfo[0].actualReward;
|
|
620
|
+
const proofs = harvestInfo[0].proof;
|
|
621
|
+
if (actualReward.isZero()) {
|
|
622
|
+
throw new Error(`Expected non-zero actual reward, got ${harvestInfo[0].actualReward}`);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
const manage1Info = this.getProofs<VesuDefiSpringRewardsCallParams>(UNIVERSAL_MANAGE_IDS.DEFISPRING_REWARDS);
|
|
626
|
+
const manageCall1 = manage1Info.callConstructor({
|
|
627
|
+
amount,
|
|
628
|
+
proofs
|
|
629
|
+
});
|
|
630
|
+
const proofIds: string[] = [UNIVERSAL_MANAGE_IDS.DEFISPRING_REWARDS];
|
|
631
|
+
const manageCalls: ManageCall[] = [manageCall1];
|
|
632
|
+
|
|
633
|
+
// swap rewards for underlying
|
|
634
|
+
const STRK = Global.getDefaultTokens().find(t => t.symbol === 'STRK')!;
|
|
635
|
+
if (this.asset().symbol != 'STRK') {
|
|
636
|
+
// approve
|
|
637
|
+
const manage2Info = this.getProofs<ApproveCallParams>(UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1);
|
|
638
|
+
const manageCall2 = manage2Info.callConstructor({
|
|
639
|
+
amount: actualReward
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
// swap
|
|
643
|
+
const avnuModule = new AvnuWrapper();
|
|
644
|
+
const quote = await avnuModule.getQuotes(
|
|
645
|
+
STRK.address.address,
|
|
646
|
+
this.asset().address.address,
|
|
647
|
+
actualReward.toWei(),
|
|
648
|
+
this.address.address
|
|
649
|
+
);
|
|
650
|
+
const swapInfo = await avnuModule.getSwapInfo(quote, this.address.address, 0, this.address.address);
|
|
651
|
+
const manage3Info = this.getProofs<AvnuSwapCallParams>(UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS);
|
|
652
|
+
const manageCall3 = manage3Info.callConstructor({
|
|
653
|
+
props: swapInfo
|
|
654
|
+
});
|
|
655
|
+
proofIds.push(UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1);
|
|
656
|
+
proofIds.push(UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS);
|
|
657
|
+
|
|
658
|
+
manageCalls.push(manageCall2);
|
|
659
|
+
manageCalls.push(manageCall3);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const manageCall = this.getManageCall(proofIds, manageCalls);
|
|
663
|
+
return { call: manageCall, reward: actualReward, tokenInfo: STRK };
|
|
664
|
+
}
|
|
665
|
+
|
|
608
666
|
async getRebalanceCall(params: {
|
|
609
667
|
isLeg1toLeg2: boolean,
|
|
610
668
|
amount: Web3Number
|
|
@@ -646,7 +704,14 @@ export enum UNIVERSAL_MANAGE_IDS {
|
|
|
646
704
|
APPROVE_TOKEN1 = 'approve_token1',
|
|
647
705
|
APPROVE_TOKEN2 = 'approve_token2',
|
|
648
706
|
APPROVE_BRING_LIQUIDITY = 'approve_bring_liquidity',
|
|
649
|
-
BRING_LIQUIDITY = 'bring_liquidity'
|
|
707
|
+
BRING_LIQUIDITY = 'bring_liquidity',
|
|
708
|
+
|
|
709
|
+
// defi spring claim
|
|
710
|
+
DEFISPRING_REWARDS = 'defispring_rewards',
|
|
711
|
+
|
|
712
|
+
// avnu swaps
|
|
713
|
+
APPROVE_SWAP_TOKEN1 = 'approve_swap_token1',
|
|
714
|
+
AVNU_SWAP_REWARDS = 'avnu_swap_rewards'
|
|
650
715
|
}
|
|
651
716
|
|
|
652
717
|
export enum UNIVERSAL_ADAPTERS {
|
|
@@ -707,7 +772,15 @@ function getLooperSettings(
|
|
|
707
772
|
// to bridge liquidity back to vault (used by bring_liquidity)
|
|
708
773
|
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(USDCToken.address, vaultSettings.vaultAddress, UNIVERSAL_MANAGE_IDS.APPROVE_BRING_LIQUIDITY).bind(commonAdapter));
|
|
709
774
|
vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter(UNIVERSAL_MANAGE_IDS.BRING_LIQUIDITY).bind(commonAdapter));
|
|
710
|
-
|
|
775
|
+
|
|
776
|
+
// claim rewards
|
|
777
|
+
vaultSettings.leafAdapters.push(vesuAdapterUSDCETH.getDefispringRewardsAdapter(UNIVERSAL_MANAGE_IDS.DEFISPRING_REWARDS).bind(vesuAdapterUSDCETH));
|
|
778
|
+
|
|
779
|
+
// avnu swap
|
|
780
|
+
const STRKToken = Global.getDefaultTokens().find(token => token.symbol === 'STRK')!;
|
|
781
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address, AVNU_MIDDLEWARE, UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1).bind(commonAdapter));
|
|
782
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, USDCToken.address, UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS).bind(commonAdapter));
|
|
783
|
+
return vaultSettings;
|
|
711
784
|
}
|
|
712
785
|
|
|
713
786
|
const _riskFactor: RiskFactor[] = [
|