@strkfarm/sdk 1.1.39 → 1.1.41
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 +722 -186
- package/dist/index.browser.mjs +721 -183
- package/dist/index.d.ts +126 -13
- package/dist/index.js +722 -183
- package/dist/index.mjs +721 -183
- 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 +254 -86
- 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
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { logger } from "@/utils";
|
|
2
|
+
|
|
3
|
+
export async function binarySearch(
|
|
4
|
+
lowWei: bigint,
|
|
5
|
+
highWei: bigint,
|
|
6
|
+
callback: (mid: bigint) => Promise<'go_low' | 'go_high' | 'retry' | 'found'>
|
|
7
|
+
): Promise<bigint | null> {
|
|
8
|
+
while (lowWei <= highWei) {
|
|
9
|
+
const diff = highWei - lowWei;
|
|
10
|
+
const mid = lowWei + (diff / 2n);
|
|
11
|
+
const result = await callback(mid);
|
|
12
|
+
|
|
13
|
+
if (result === 'found') {
|
|
14
|
+
return mid;
|
|
15
|
+
} else if (result == 'retry') {
|
|
16
|
+
// do nothing.
|
|
17
|
+
} else if (result === 'go_low') {
|
|
18
|
+
highWei = mid - BigInt(1);
|
|
19
|
+
} else {
|
|
20
|
+
lowWei = mid + BigInt(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return null; // not found
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface SwapResult {
|
|
28
|
+
optimalInput: number;
|
|
29
|
+
actualOutput: number;
|
|
30
|
+
actualSlippage: number;
|
|
31
|
+
apiCallsUsed: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface FindMaxInputOptions {
|
|
35
|
+
/** Function that calls your API: input amount -> output amount */
|
|
36
|
+
apiGetOutput: (inputAmount: number) => Promise<number>;
|
|
37
|
+
/** Maximum input amount you're willing to swap */
|
|
38
|
+
maxInput: number;
|
|
39
|
+
/** Maximum acceptable slippage in percent (e.g., 1.0 for 1%) */
|
|
40
|
+
maxSlippagePercent: number;
|
|
41
|
+
/** Convergence tolerance as fraction of maxInput */
|
|
42
|
+
tolerance: number;
|
|
43
|
+
/** Minimum input amount (default: 0) */
|
|
44
|
+
minInput?: number;
|
|
45
|
+
/** Reference amount multiplier for price calculation (default: 0.001) */
|
|
46
|
+
referenceAmountMultiplier?: number;
|
|
47
|
+
/** Reference rate for price calculation */
|
|
48
|
+
referenceRate?: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Find maximum input amount within slippage constraints using binary search
|
|
53
|
+
*
|
|
54
|
+
* @returns Promise with optimal input, output, slippage, and API calls used
|
|
55
|
+
*/
|
|
56
|
+
export async function findMaxInputWithSlippage(
|
|
57
|
+
options: FindMaxInputOptions
|
|
58
|
+
): Promise<SwapResult> {
|
|
59
|
+
const {
|
|
60
|
+
apiGetOutput,
|
|
61
|
+
maxInput,
|
|
62
|
+
maxSlippagePercent,
|
|
63
|
+
tolerance,
|
|
64
|
+
minInput = 0,
|
|
65
|
+
referenceAmountMultiplier = 0.001,
|
|
66
|
+
referenceRate = 0,
|
|
67
|
+
} = options;
|
|
68
|
+
|
|
69
|
+
let apiCalls = 0;
|
|
70
|
+
|
|
71
|
+
// one of referenceRate or referenceAmountMultiplier must be provided
|
|
72
|
+
if (!referenceRate && !referenceAmountMultiplier) {
|
|
73
|
+
throw new Error('One of referenceRate or referenceAmountMultiplier must be provided');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let _referenceRate = referenceRate;
|
|
77
|
+
if (!_referenceRate) {
|
|
78
|
+
// Get reference rate at minimal amount for price calculation
|
|
79
|
+
const smallAmount = maxInput * referenceAmountMultiplier;
|
|
80
|
+
const referenceOutput = await apiGetOutput(smallAmount);
|
|
81
|
+
apiCalls++;
|
|
82
|
+
_referenceRate = referenceOutput / smallAmount;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Check if slippage is acceptable for given input amount
|
|
87
|
+
* Returns { acceptable: boolean, slippage: number, output: number }
|
|
88
|
+
*/
|
|
89
|
+
async function checkSlippage(inputAmount: number) {
|
|
90
|
+
const actualOutput = await apiGetOutput(inputAmount);
|
|
91
|
+
apiCalls++;
|
|
92
|
+
|
|
93
|
+
const expectedOutput = inputAmount * referenceRate;
|
|
94
|
+
const slippage = ((expectedOutput - actualOutput) / expectedOutput);
|
|
95
|
+
logger.verbose(`findMaxInputWithSlippage::checkSlippage inputAmount: ${inputAmount}, actualOutput: ${actualOutput}, slippage: ${slippage}, maxSlippagePercent: ${maxSlippagePercent}`);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
acceptable: slippage <= maxSlippagePercent,
|
|
99
|
+
slippage,
|
|
100
|
+
output: actualOutput,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Start from the top - try maxInput first
|
|
105
|
+
const maxCheck = await checkSlippage(maxInput);
|
|
106
|
+
if (maxCheck.acceptable) {
|
|
107
|
+
// Best case: maxInput is within slippage, return immediately
|
|
108
|
+
return {
|
|
109
|
+
optimalInput: maxInput,
|
|
110
|
+
actualOutput: maxCheck.output,
|
|
111
|
+
actualSlippage: maxCheck.slippage,
|
|
112
|
+
apiCallsUsed: apiCalls,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Binary search between minInput and maxInput
|
|
117
|
+
let left = minInput;
|
|
118
|
+
let right = maxInput;
|
|
119
|
+
let bestInput = minInput;
|
|
120
|
+
let bestOutput = 0;
|
|
121
|
+
let bestSlippage = 0;
|
|
122
|
+
|
|
123
|
+
const convergenceThreshold = tolerance * maxInput;
|
|
124
|
+
|
|
125
|
+
while (right - left > convergenceThreshold) {
|
|
126
|
+
const mid = (left + right) / 2;
|
|
127
|
+
const midCheck = await checkSlippage(mid);
|
|
128
|
+
|
|
129
|
+
if (midCheck.acceptable) {
|
|
130
|
+
// Good slippage at mid, save it and try higher
|
|
131
|
+
bestInput = mid;
|
|
132
|
+
bestOutput = midCheck.output;
|
|
133
|
+
bestSlippage = midCheck.slippage;
|
|
134
|
+
left = mid; // Search in upper half [mid, right]
|
|
135
|
+
} else {
|
|
136
|
+
// Bad slippage at mid, try lower
|
|
137
|
+
right = mid; // Search in lower half [left, mid]
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
optimalInput: bestInput,
|
|
143
|
+
actualOutput: bestOutput,
|
|
144
|
+
actualSlippage: bestSlippage,
|
|
145
|
+
apiCallsUsed: apiCalls,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|