@strkfarm/sdk 1.1.39 → 1.1.40
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 +723 -179
- package/dist/index.browser.mjs +722 -176
- package/dist/index.d.ts +126 -13
- package/dist/index.js +723 -176
- package/dist/index.mjs +722 -176
- package/package.json +1 -1
- package/src/global.ts +18 -0
- package/src/modules/avnu.ts +5 -4
- package/src/modules/harvests.ts +16 -15
- package/src/strategies/ekubo-cl-vault.tsx +255 -79
- package/src/strategies/universal-adapters/baseAdapter.ts +184 -2
- package/src/strategies/universal-adapters/vesu-adapter.ts +34 -17
- package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +322 -0
- package/src/strategies/universal-lst-muliplier-strategy.tsx +226 -67
- package/src/strategies/universal-strategy.tsx +5 -5
- package/src/utils/health-factor-math.ts +83 -0
- package/src/utils/math-utils.ts +150 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LeafData, logger } from "@/utils"
|
|
2
|
-
import { CairoCustomEnum, Contract, hash, num, RpcProvider, shortString, uint256, Uint256 } from "starknet";
|
|
2
|
+
import { BlockIdentifier, CairoCustomEnum, Contract, hash, num, RpcProvider, shortString, uint256, Uint256 } from "starknet";
|
|
3
3
|
import { SIMPLE_SANITIZER, SIMPLE_SANITIZER_V2, SIMPLE_SANITIZER_VESU_V1_DELEGATIONS, toBigInt, VESU_SINGLETON, VESU_V2_MODIFY_POSITION_SANITIZER } from "./adapter-utils";
|
|
4
4
|
import { ContractAddr, Web3Number } from "@/dataTypes";
|
|
5
5
|
import { AdapterLeafType, BaseAdapter, GenerateCallFn, LeafAdapterFn, ManageCall } from "./baseAdapter";
|
|
@@ -536,7 +536,22 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
536
536
|
}
|
|
537
537
|
const output: any = await contract.call('pair_config', [this.config.collateral.address.address, this.config.debt.address.address]);
|
|
538
538
|
logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap debt_cap: ${output.debt_cap.toString()}`);
|
|
539
|
-
|
|
539
|
+
|
|
540
|
+
if (!isV2) {
|
|
541
|
+
throw new Error('getDebtCap is not supported for v1');
|
|
542
|
+
}
|
|
543
|
+
const currentDebt = await this.getCurrentDebtUtilisationAmount(config);
|
|
544
|
+
logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap currentDebt: ${currentDebt.toString()}`);
|
|
545
|
+
return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals).minus(currentDebt);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
async getCurrentDebtUtilisationAmount(config: IConfig) {
|
|
549
|
+
const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
|
|
550
|
+
if (!isV2) {
|
|
551
|
+
throw new Error('getCurrentDebtUtilisationAmount is not supported for v1');
|
|
552
|
+
}
|
|
553
|
+
const output: any = await contract.call('pairs', [this.config.collateral.address.address, this.config.debt.address.address]);
|
|
554
|
+
return new Web3Number((Number(output.total_nominal_debt) / 1e18).toFixed(9), this.config.debt.decimals);
|
|
540
555
|
}
|
|
541
556
|
|
|
542
557
|
async getMaxBorrowableByInterestRate(config: IConfig, asset: TokenInfo, maxBorrowAPY: number) {
|
|
@@ -572,19 +587,20 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
572
587
|
const assetConfig = isV2 ? _assetConfig : _assetConfig['0'];
|
|
573
588
|
const timeDelta = assetConfig.last_updated;
|
|
574
589
|
const lastFullUtilizationRate = assetConfig.last_full_utilization_rate;
|
|
575
|
-
const
|
|
590
|
+
const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
|
|
591
|
+
const totalSupply = currentDebt.plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
|
|
576
592
|
|
|
577
593
|
const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
|
|
578
594
|
const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
|
|
579
595
|
logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
|
|
580
596
|
|
|
581
597
|
const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
|
|
582
|
-
|
|
598
|
+
logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate currentDebt: ${currentDebt.toString()}, maxDebtToHave: ${maxDebtToHave.toString()}`);
|
|
583
599
|
return maxDebtToHave.minus(currentDebt);
|
|
584
600
|
}
|
|
585
601
|
|
|
586
|
-
async getLTVConfig(config: IConfig) {
|
|
587
|
-
const CACHE_KEY =
|
|
602
|
+
async getLTVConfig(config: IConfig, blockNumber: BlockIdentifier = 'latest') {
|
|
603
|
+
const CACHE_KEY = `ltv_config_${blockNumber}`;
|
|
588
604
|
const cacheData = this.getCache<number>(CACHE_KEY);
|
|
589
605
|
if (cacheData) {
|
|
590
606
|
return cacheData as number;
|
|
@@ -592,10 +608,10 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
592
608
|
const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
|
|
593
609
|
let ltv = 0;
|
|
594
610
|
if (isV2) {
|
|
595
|
-
const output: any = await contract.call('pair_config', [this.config.collateral.address.address, this.config.debt.address.address]);
|
|
611
|
+
const output: any = await contract.call('pair_config', [this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
|
|
596
612
|
ltv = Number(output.max_ltv) / 1e18;
|
|
597
613
|
} else {
|
|
598
|
-
const output: any = await contract.call('ltv_config', [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
|
|
614
|
+
const output: any = await contract.call('ltv_config', [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
|
|
599
615
|
ltv = Number(output.max_ltv) / 1e18;
|
|
600
616
|
}
|
|
601
617
|
if (ltv == 0) {
|
|
@@ -605,12 +621,12 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
605
621
|
return this.getCache<number>(CACHE_KEY) as number;
|
|
606
622
|
}
|
|
607
623
|
|
|
608
|
-
async getPositions(config: IConfig): Promise<VaultPosition[]> {
|
|
624
|
+
async getPositions(config: IConfig, blockNumber: BlockIdentifier = 'latest'): Promise<VaultPosition[]> {
|
|
609
625
|
if (!this.pricer) {
|
|
610
626
|
throw new Error('Pricer is not initialized');
|
|
611
627
|
}
|
|
612
628
|
// { '0': { collateral_shares: 0n, nominal_debt: 0n }, '1': 0n, '2': 0n }
|
|
613
|
-
const CACHE_KEY =
|
|
629
|
+
const CACHE_KEY = `positions_${blockNumber}`;
|
|
614
630
|
const cacheData = this.getCache<VaultPosition[]>(CACHE_KEY);
|
|
615
631
|
if (cacheData) {
|
|
616
632
|
return cacheData;
|
|
@@ -623,8 +639,9 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
623
639
|
this.config.collateral.address.address,
|
|
624
640
|
this.config.debt.address.address,
|
|
625
641
|
this.config.vaultAllocator.address
|
|
626
|
-
]);
|
|
642
|
+
], { blockIdentifier: blockNumber });
|
|
627
643
|
|
|
644
|
+
console.log(output)
|
|
628
645
|
const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
|
|
629
646
|
const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
|
|
630
647
|
logger.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
|
|
@@ -646,12 +663,12 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
646
663
|
return value;
|
|
647
664
|
}
|
|
648
665
|
|
|
649
|
-
async getCollateralization(config: IConfig): Promise<Omit<VaultPosition, 'amount'>[]> {
|
|
666
|
+
async getCollateralization(config: IConfig, blockNumber: BlockIdentifier = 'latest'): Promise<Omit<VaultPosition, 'amount'>[]> {
|
|
650
667
|
if (!this.pricer) {
|
|
651
668
|
throw new Error('Pricer is not initialized');
|
|
652
669
|
}
|
|
653
670
|
// { '0': bool, '1': 0n, '2': 0n }
|
|
654
|
-
const CACHE_KEY =
|
|
671
|
+
const CACHE_KEY = `collateralization_${blockNumber}`;
|
|
655
672
|
const cacheData = this.getCache<Omit<VaultPosition, 'amount'>[]>(CACHE_KEY);
|
|
656
673
|
if (cacheData) {
|
|
657
674
|
return cacheData;
|
|
@@ -664,7 +681,7 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
664
681
|
this.config.collateral.address.address,
|
|
665
682
|
this.config.debt.address.address,
|
|
666
683
|
this.config.vaultAllocator.address
|
|
667
|
-
]);
|
|
684
|
+
], { blockIdentifier: blockNumber });
|
|
668
685
|
|
|
669
686
|
// usd values
|
|
670
687
|
const collateralAmount = Web3Number.fromWei(output['1'].toString(), 18);
|
|
@@ -709,9 +726,9 @@ export class VesuAdapter extends BaseAdapter {
|
|
|
709
726
|
}
|
|
710
727
|
}
|
|
711
728
|
|
|
712
|
-
async getHealthFactor() {
|
|
713
|
-
const ltv = await this.getLTVConfig(this.networkConfig
|
|
714
|
-
const collateralisation = await this.getCollateralization(this.networkConfig
|
|
729
|
+
async getHealthFactor(blockNumber: BlockIdentifier = 'latest') {
|
|
730
|
+
const ltv = await this.getLTVConfig(this.networkConfig!, blockNumber);
|
|
731
|
+
const collateralisation = await this.getCollateralization(this.networkConfig!, blockNumber);
|
|
715
732
|
return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
|
|
716
733
|
}
|
|
717
734
|
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { ContractAddr, Web3Number } from "@/dataTypes";
|
|
2
|
+
import { IConfig, TokenInfo } from "@/interfaces";
|
|
3
|
+
import { PricerBase } from "@/modules/pricerBase";
|
|
4
|
+
import { BaseAdapter, BaseAdapterConfig, SupportedPosition, PositionInfo, PositionAPY, APYType, ManageCall, AdapterLeafType, GenerateCallFn } from "./baseAdapter";
|
|
5
|
+
import { SIMPLE_SANITIZER, toBigInt } from "./adapter-utils";
|
|
6
|
+
import { hash, uint256, Contract } from "starknet";
|
|
7
|
+
import { VesuAdapter } from "./vesu-adapter";
|
|
8
|
+
import { logger } from "@/utils";
|
|
9
|
+
|
|
10
|
+
export interface VesuSupplyOnlyAdapterConfig extends BaseAdapterConfig {
|
|
11
|
+
vTokenContract: ContractAddr;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface DepositParams {
|
|
15
|
+
amount: Web3Number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface WithdrawParams {
|
|
19
|
+
amount: Web3Number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class VesuSupplyOnlyAdapter extends BaseAdapter<any, any> {
|
|
23
|
+
readonly config: VesuSupplyOnlyAdapterConfig;
|
|
24
|
+
|
|
25
|
+
constructor(config: VesuSupplyOnlyAdapterConfig) {
|
|
26
|
+
super(config);
|
|
27
|
+
this.config = config;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected async getAPY(supportedPosition: SupportedPosition): Promise<PositionAPY> {
|
|
31
|
+
const CACHE_KEY = `apy_${this.config.vTokenContract.address}`;
|
|
32
|
+
const cacheData = this.getCache<PositionAPY>(CACHE_KEY);
|
|
33
|
+
if (cacheData) {
|
|
34
|
+
return cacheData;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// Get Vesu pools to find APY for the underlying asset
|
|
39
|
+
const allVesuPools = await VesuAdapter.getVesuPools();
|
|
40
|
+
const baseToken = this.config.baseToken;
|
|
41
|
+
|
|
42
|
+
// Find the pool that contains our base token
|
|
43
|
+
const pool = allVesuPools.pools.find(p => {
|
|
44
|
+
return p.assets.some((asset: any) =>
|
|
45
|
+
asset.symbol.toLowerCase() === baseToken.symbol.toLowerCase()
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (!pool) {
|
|
50
|
+
logger.warn(`VesuSupplyOnlyAdapter: Pool not found for token ${baseToken.symbol}`);
|
|
51
|
+
return {
|
|
52
|
+
apy: 0,
|
|
53
|
+
type: APYType.BASE
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Find the asset stats for our token
|
|
58
|
+
const assetStats = pool.assets.find((a: any) =>
|
|
59
|
+
a.symbol.toLowerCase() === baseToken.symbol.toLowerCase()
|
|
60
|
+
)?.stats;
|
|
61
|
+
|
|
62
|
+
if (!assetStats) {
|
|
63
|
+
logger.warn(`VesuSupplyOnlyAdapter: Asset stats not found for token ${baseToken.symbol}`);
|
|
64
|
+
return {
|
|
65
|
+
apy: 0,
|
|
66
|
+
type: APYType.BASE
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Get supply APY (divide by 1e18 as it's in wei)
|
|
71
|
+
const supplyApy = Number(assetStats.supplyApy?.value || 0) / 1e18;
|
|
72
|
+
|
|
73
|
+
// Get LST APR if applicable (for LST tokens)
|
|
74
|
+
let lstAPY = 0;
|
|
75
|
+
if (baseToken.symbol === 'STRK' || baseToken.symbol === 'ETH') {
|
|
76
|
+
// This would need to be implemented based on your LST APR service
|
|
77
|
+
// For now, using a placeholder
|
|
78
|
+
lstAPY = 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const totalAPY = supplyApy + lstAPY;
|
|
82
|
+
|
|
83
|
+
const result = {
|
|
84
|
+
apy: totalAPY,
|
|
85
|
+
type: APYType.BASE
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
this.setCache(CACHE_KEY, result, 300000); // Cache for 5 minutes
|
|
89
|
+
return result;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
logger.error(`VesuSupplyOnlyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`, error);
|
|
92
|
+
return {
|
|
93
|
+
apy: 0,
|
|
94
|
+
type: APYType.BASE
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
protected async getPosition(supportedPosition: SupportedPosition): Promise<Web3Number> {
|
|
100
|
+
const CACHE_KEY = `position_${this.config.vTokenContract.address}`;
|
|
101
|
+
const cacheData = this.getCache<Web3Number>(CACHE_KEY);
|
|
102
|
+
if (cacheData) {
|
|
103
|
+
return cacheData;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
// Create contract instance for the vToken
|
|
108
|
+
const vTokenContract = new Contract({
|
|
109
|
+
abi: [], // We only need basic ERC20 methods
|
|
110
|
+
address: this.config.vTokenContract.address,
|
|
111
|
+
providerOrAccount: this.config.networkConfig.provider
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Get the vault allocator's balance (shares) in the vToken contract
|
|
115
|
+
const shares = await vTokenContract.balanceOf(this.config.vaultAllocator.address);
|
|
116
|
+
|
|
117
|
+
// Convert shares to assets using convert_to_assets
|
|
118
|
+
const assets = await vTokenContract.convert_to_assets(
|
|
119
|
+
uint256.bnToUint256(shares)
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const result = Web3Number.fromWei(
|
|
123
|
+
assets.toString(),
|
|
124
|
+
supportedPosition.asset.decimals
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
this.setCache(CACHE_KEY, result, 60000); // Cache for 1 minute
|
|
128
|
+
return result;
|
|
129
|
+
} catch (error) {
|
|
130
|
+
logger.error(`VesuSupplyOnlyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`, error);
|
|
131
|
+
return new Web3Number('0', supportedPosition.asset.decimals);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
protected async maxDeposit(amount?: Web3Number): Promise<PositionInfo[]> {
|
|
136
|
+
const baseToken = this.config.baseToken;
|
|
137
|
+
// todo for assets with some borrowing on Vesu, the yield wont
|
|
138
|
+
// remain same as supply increases. So need to account for that.
|
|
139
|
+
|
|
140
|
+
if (!amount) {
|
|
141
|
+
// Return infinity for max deposit when no amount specified
|
|
142
|
+
return [{
|
|
143
|
+
amount: new Web3Number('999999999999999999999999999', baseToken.decimals),
|
|
144
|
+
usdValue: 999999999999999999999999999,
|
|
145
|
+
remarks: "Max deposit (infinity)",
|
|
146
|
+
apy: await this.getAPY({ asset: baseToken, isDebt: false })
|
|
147
|
+
}];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Return position info based on input amount
|
|
151
|
+
const usdValue = await this.getUSDValue(baseToken, amount);
|
|
152
|
+
return [{
|
|
153
|
+
amount,
|
|
154
|
+
usdValue,
|
|
155
|
+
remarks: "Deposit amount",
|
|
156
|
+
apy: await this.getAPY({ asset: baseToken, isDebt: false })
|
|
157
|
+
}];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
protected async maxWithdraw(): Promise<PositionInfo[]> {
|
|
161
|
+
const baseToken = this.config.baseToken;
|
|
162
|
+
const currentPosition = await this.getPosition({ asset: baseToken, isDebt: false });
|
|
163
|
+
|
|
164
|
+
// Return the current position as max withdraw
|
|
165
|
+
const usdValue = await this.getUSDValue(baseToken, currentPosition);
|
|
166
|
+
return [{
|
|
167
|
+
amount: currentPosition,
|
|
168
|
+
usdValue,
|
|
169
|
+
remarks: "Max withdraw",
|
|
170
|
+
apy: await this.getAPY({ asset: baseToken, isDebt: false })
|
|
171
|
+
}];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
protected _getDepositLeaf(): {
|
|
175
|
+
target: ContractAddr,
|
|
176
|
+
method: string,
|
|
177
|
+
packedArguments: bigint[],
|
|
178
|
+
sanitizer: ContractAddr,
|
|
179
|
+
id: string
|
|
180
|
+
}[] {
|
|
181
|
+
const baseToken = this.config.baseToken;
|
|
182
|
+
const vTokenContract = this.config.vTokenContract;
|
|
183
|
+
|
|
184
|
+
return [
|
|
185
|
+
// Approval step
|
|
186
|
+
{
|
|
187
|
+
target: baseToken.address,
|
|
188
|
+
method: 'approve',
|
|
189
|
+
packedArguments: [
|
|
190
|
+
vTokenContract.toBigInt(), // spender
|
|
191
|
+
],
|
|
192
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
193
|
+
id: `approve_deposit_vtoken_${this.config.vTokenContract.address}`
|
|
194
|
+
},
|
|
195
|
+
// Deposit step
|
|
196
|
+
{
|
|
197
|
+
target: vTokenContract,
|
|
198
|
+
method: 'deposit',
|
|
199
|
+
packedArguments: [
|
|
200
|
+
this.config.vaultAllocator.toBigInt(),
|
|
201
|
+
],
|
|
202
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
203
|
+
id: `deposit_vtoken_${this.config.vTokenContract.address}`
|
|
204
|
+
}
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
protected _getWithdrawLeaf(): {
|
|
209
|
+
target: ContractAddr,
|
|
210
|
+
method: string,
|
|
211
|
+
packedArguments: bigint[],
|
|
212
|
+
sanitizer: ContractAddr,
|
|
213
|
+
id: string
|
|
214
|
+
}[] {
|
|
215
|
+
const vTokenContract = this.config.vTokenContract;
|
|
216
|
+
|
|
217
|
+
return [
|
|
218
|
+
// Withdraw step
|
|
219
|
+
{
|
|
220
|
+
target: vTokenContract,
|
|
221
|
+
method: 'withdraw',
|
|
222
|
+
packedArguments: [
|
|
223
|
+
this.config.vaultAllocator.toBigInt(),
|
|
224
|
+
this.config.vaultAllocator.toBigInt(),
|
|
225
|
+
],
|
|
226
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
227
|
+
id: `withdraw_vtoken_${this.config.vTokenContract.address}`
|
|
228
|
+
}
|
|
229
|
+
];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
getDepositAdapter(): AdapterLeafType<DepositParams> {
|
|
233
|
+
const leafConfigs = this._getDepositLeaf();
|
|
234
|
+
const leaves = leafConfigs.map(config => {
|
|
235
|
+
const { target, method, packedArguments, sanitizer, id } = config;
|
|
236
|
+
const leaf = this.constructSimpleLeafData({
|
|
237
|
+
id: id,
|
|
238
|
+
target,
|
|
239
|
+
method,
|
|
240
|
+
packedArguments
|
|
241
|
+
}, sanitizer);
|
|
242
|
+
return leaf;
|
|
243
|
+
});
|
|
244
|
+
return { leaves, callConstructor: this.createDepositCall.bind(this) as unknown as GenerateCallFn<DepositParams> };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
getWithdrawAdapter(): AdapterLeafType<WithdrawParams> {
|
|
248
|
+
const leafConfigs = this._getWithdrawLeaf();
|
|
249
|
+
const leaves = leafConfigs.map(config => {
|
|
250
|
+
const { target, method, packedArguments, sanitizer, id } = config;
|
|
251
|
+
const leaf = this.constructSimpleLeafData({
|
|
252
|
+
id: id,
|
|
253
|
+
target,
|
|
254
|
+
method,
|
|
255
|
+
packedArguments
|
|
256
|
+
}, sanitizer);
|
|
257
|
+
return leaf;
|
|
258
|
+
});
|
|
259
|
+
return { leaves, callConstructor: this.createWithdrawCall.bind(this) as unknown as GenerateCallFn<WithdrawParams> };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
private createDepositCall(params: DepositParams): ManageCall[] {
|
|
263
|
+
const baseToken = this.config.baseToken;
|
|
264
|
+
const vTokenContract = this.config.vTokenContract;
|
|
265
|
+
|
|
266
|
+
const amount = params.amount;
|
|
267
|
+
const uint256Amount = uint256.bnToUint256(amount.toWei());
|
|
268
|
+
|
|
269
|
+
return [
|
|
270
|
+
// Approval call
|
|
271
|
+
{
|
|
272
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
273
|
+
call: {
|
|
274
|
+
contractAddress: baseToken.address,
|
|
275
|
+
selector: hash.getSelectorFromName('approve'),
|
|
276
|
+
calldata: [
|
|
277
|
+
vTokenContract.toBigInt(), // spender
|
|
278
|
+
toBigInt(uint256Amount.low.toString()), // amount low
|
|
279
|
+
toBigInt(uint256Amount.high.toString()), // amount high
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
// Deposit call
|
|
284
|
+
{
|
|
285
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
286
|
+
call: {
|
|
287
|
+
contractAddress: vTokenContract,
|
|
288
|
+
selector: hash.getSelectorFromName('deposit'),
|
|
289
|
+
calldata: [
|
|
290
|
+
toBigInt(uint256Amount.low.toString()), // amount low
|
|
291
|
+
toBigInt(uint256Amount.high.toString()), // amount high
|
|
292
|
+
this.config.vaultAllocator.toBigInt(),
|
|
293
|
+
]
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
private createWithdrawCall(params: WithdrawParams): ManageCall[] {
|
|
300
|
+
const vTokenContract = this.config.vTokenContract;
|
|
301
|
+
|
|
302
|
+
const amount = params.amount;
|
|
303
|
+
const uint256Amount = uint256.bnToUint256(amount.toWei());
|
|
304
|
+
|
|
305
|
+
return [
|
|
306
|
+
// Withdraw call
|
|
307
|
+
{
|
|
308
|
+
sanitizer: SIMPLE_SANITIZER,
|
|
309
|
+
call: {
|
|
310
|
+
contractAddress: vTokenContract,
|
|
311
|
+
selector: hash.getSelectorFromName('withdraw'),
|
|
312
|
+
calldata: [
|
|
313
|
+
toBigInt(uint256Amount.low.toString()), // amount low
|
|
314
|
+
toBigInt(uint256Amount.high.toString()), // amount high
|
|
315
|
+
this.config.vaultAllocator.toBigInt(),
|
|
316
|
+
this.config.vaultAllocator.toBigInt(),
|
|
317
|
+
]
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
];
|
|
321
|
+
}
|
|
322
|
+
}
|