@paraswap/dex-lib 2.47.5 → 2.47.7
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/build/abi/balancer-v2/gyro-e.abi.json +1595 -0
- package/build/dex/balancer-v2/balancer-v2.d.ts +6 -3
- package/build/dex/balancer-v2/balancer-v2.js +56 -35
- package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
- package/build/dex/balancer-v2/pools/gyro/Gyro3Pool.d.ts +32 -0
- package/build/dex/balancer-v2/pools/gyro/Gyro3Pool.js +149 -0
- package/build/dex/balancer-v2/pools/gyro/Gyro3Pool.js.map +1 -0
- package/build/dex/balancer-v2/pools/gyro/GyroEPool.d.ts +37 -0
- package/build/dex/balancer-v2/pools/gyro/GyroEPool.js +222 -0
- package/build/dex/balancer-v2/pools/gyro/GyroEPool.js.map +1 -0
- package/build/dex/balancer-v2/pools/gyro/gyro-helpers.d.ts +2 -0
- package/build/dex/balancer-v2/pools/gyro/gyro-helpers.js +19 -0
- package/build/dex/balancer-v2/pools/gyro/gyro-helpers.js.map +1 -0
- package/build/dex/balancer-v2/queryOnChain.d.ts +1 -0
- package/build/dex/balancer-v2/queryOnChain.js +40 -0
- package/build/dex/balancer-v2/queryOnChain.js.map +1 -0
- package/build/dex/balancer-v2/types.d.ts +24 -1
- package/build/dex/balancer-v2/types.js +2 -0
- package/build/dex/balancer-v2/types.js.map +1 -1
- package/build/dex/balancer-v2/utils.d.ts +8 -0
- package/build/dex/balancer-v2/utils.js +17 -1
- package/build/dex/balancer-v2/utils.js.map +1 -1
- package/package.json +2 -1
- package/src/abi/balancer-v2/gyro-e.abi.json +1595 -0
- package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +94 -0
- package/src/dex/balancer-v2/balancer-v2-gyro3.test.ts +268 -0
- package/src/dex/balancer-v2/balancer-v2-gyroE.test.ts +401 -0
- package/src/dex/balancer-v2/balancer-v2-integration.test.ts +253 -112
- package/src/dex/balancer-v2/balancer-v2.ts +107 -67
- package/src/dex/balancer-v2/pools/gyro/Gyro3Pool.ts +255 -0
- package/src/dex/balancer-v2/pools/gyro/GyroEPool.ts +403 -0
- package/src/dex/balancer-v2/pools/gyro/gyro-helpers.ts +15 -0
- package/src/dex/balancer-v2/queryOnChain.ts +48 -0
- package/src/dex/balancer-v2/types.ts +26 -0
- package/src/dex/balancer-v2/utils.ts +16 -0
- package/src/dex/synthetix/synthetix-state.ts +2 -2
- package/tests/constants-e2e.ts +26 -0
- package/build/abi/Redstone.json +0 -739
- package/build/abi/angle/stagToken.json +0 -963
- package/build/abi/angle-transmuter/Pyth.json +0 -1534
- package/build/abi/angle-transmuter/Transmuter.json +0 -1719
- package/build/abi/smardex/smardex-factory.json +0 -185
- package/build/abi/smardex/smardex-pool.json +0 -578
- package/build/abi/smardex/smardex-router.json +0 -648
- package/build/abi/trader-joe-v2_1/FactoryABI.json +0 -1208
- package/build/abi/trader-joe-v2_1/PairABI.json +0 -1493
- package/build/abi/trader-joe-v2_1/RouterABI.json +0 -1489
- package/build/abi/trader-joe-v2_1/StateMulticall.json +0 -193
- package/build/abi/wombat/pool.json +0 -1289
- package/build/dex/angle-staked-stable/angle-staked-stable-pool.d.ts +0 -53
- package/build/dex/angle-staked-stable/angle-staked-stable-pool.js +0 -175
- package/build/dex/angle-staked-stable/angle-staked-stable-pool.js.map +0 -1
- package/build/dex/angle-staked-stable/angle-staked-stable.d.ts +0 -42
- package/build/dex/angle-staked-stable/angle-staked-stable.js +0 -232
- package/build/dex/angle-staked-stable/angle-staked-stable.js.map +0 -1
- package/build/dex/angle-staked-stable/config.d.ts +0 -4
- package/build/dex/angle-staked-stable/config.js +0 -26
- package/build/dex/angle-staked-stable/config.js.map +0 -1
- package/build/dex/angle-staked-stable/types.d.ts +0 -15
- package/build/dex/angle-staked-stable/types.js +0 -3
- package/build/dex/angle-staked-stable/types.js.map +0 -1
- package/build/dex/angle-transmuter/angle-transmuter-pool.d.ts +0 -43
- package/build/dex/angle-transmuter/angle-transmuter-pool.js +0 -309
- package/build/dex/angle-transmuter/angle-transmuter-pool.js.map +0 -1
- package/build/dex/angle-transmuter/angle-transmuter.d.ts +0 -46
- package/build/dex/angle-transmuter/angle-transmuter.js +0 -233
- package/build/dex/angle-transmuter/angle-transmuter.js.map +0 -1
- package/build/dex/angle-transmuter/backedOracle.d.ts +0 -19
- package/build/dex/angle-transmuter/backedOracle.js +0 -56
- package/build/dex/angle-transmuter/backedOracle.js.map +0 -1
- package/build/dex/angle-transmuter/config.d.ts +0 -4
- package/build/dex/angle-transmuter/config.js +0 -20
- package/build/dex/angle-transmuter/config.js.map +0 -1
- package/build/dex/angle-transmuter/constants.d.ts +0 -4
- package/build/dex/angle-transmuter/constants.js +0 -8
- package/build/dex/angle-transmuter/constants.js.map +0 -1
- package/build/dex/angle-transmuter/pyth.d.ts +0 -19
- package/build/dex/angle-transmuter/pyth.js +0 -71
- package/build/dex/angle-transmuter/pyth.js.map +0 -1
- package/build/dex/angle-transmuter/redstone.d.ts +0 -20
- package/build/dex/angle-transmuter/redstone.js +0 -73
- package/build/dex/angle-transmuter/redstone.js.map +0 -1
- package/build/dex/angle-transmuter/transmuter.d.ts +0 -50
- package/build/dex/angle-transmuter/transmuter.js +0 -314
- package/build/dex/angle-transmuter/transmuter.js.map +0 -1
- package/build/dex/angle-transmuter/types.d.ts +0 -144
- package/build/dex/angle-transmuter/types.js +0 -31
- package/build/dex/angle-transmuter/types.js.map +0 -1
- package/build/dex/angle-transmuter/utils.d.ts +0 -9
- package/build/dex/angle-transmuter/utils.js +0 -264
- package/build/dex/angle-transmuter/utils.js.map +0 -1
- package/build/dex/smardex/subgraph-queries.d.ts +0 -1
- package/build/dex/smardex/subgraph-queries.js +0 -17
- package/build/dex/smardex/subgraph-queries.js.map +0 -1
- package/build/dex/smardex/usd-reserves.d.ts +0 -23
- package/build/dex/smardex/usd-reserves.js +0 -86
- package/build/dex/smardex/usd-reserves.js.map +0 -1
- package/build/dex/trader-joe-v2-1-2/config.d.ts +0 -4
- package/build/dex/trader-joe-v2-1-2/config.js +0 -47
- package/build/dex/trader-joe-v2-1-2/config.js.map +0 -1
- package/build/dex/trader-joe-v2-1-2/constants.d.ts +0 -20
- package/build/dex/trader-joe-v2-1-2/constants.js +0 -22
- package/build/dex/trader-joe-v2-1-2/constants.js.map +0 -1
- package/build/dex/trader-joe-v2-1-2/math/index.d.ts +0 -37
- package/build/dex/trader-joe-v2-1-2/math/index.js +0 -291
- package/build/dex/trader-joe-v2-1-2/math/index.js.map +0 -1
- package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2-pool.d.ts +0 -60
- package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2-pool.js +0 -248
- package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2-pool.js.map +0 -1
- package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2.d.ts +0 -53
- package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2.js +0 -307
- package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2.js.map +0 -1
- package/build/dex/trader-joe-v2-1-2/types.d.ts +0 -82
- package/build/dex/trader-joe-v2-1-2/types.js +0 -9
- package/build/dex/trader-joe-v2-1-2/types.js.map +0 -1
- package/build/dex/trader-joe-v2_1/config.d.ts +0 -4
- package/build/dex/trader-joe-v2_1/config.js +0 -47
- package/build/dex/trader-joe-v2_1/config.js.map +0 -1
- package/build/dex/trader-joe-v2_1/constants.d.ts +0 -20
- package/build/dex/trader-joe-v2_1/constants.js +0 -22
- package/build/dex/trader-joe-v2_1/constants.js.map +0 -1
- package/build/dex/trader-joe-v2_1/math/index.d.ts +0 -37
- package/build/dex/trader-joe-v2_1/math/index.js +0 -291
- package/build/dex/trader-joe-v2_1/math/index.js.map +0 -1
- package/build/dex/trader-joe-v2_1/trader-joe-v2.1.d.ts +0 -0
- package/build/dex/trader-joe-v2_1/trader-joe-v2.1.js +0 -384
- package/build/dex/trader-joe-v2_1/trader-joe-v2.1.js.map +0 -1
- package/build/dex/trader-joe-v2_1/trader-joe-v2_1-pool.d.ts +0 -60
- package/build/dex/trader-joe-v2_1/trader-joe-v2_1-pool.js +0 -247
- package/build/dex/trader-joe-v2_1/trader-joe-v2_1-pool.js.map +0 -1
- package/build/dex/trader-joe-v2_1/trader-joe-v2_1.d.ts +0 -53
- package/build/dex/trader-joe-v2_1/trader-joe-v2_1.js +0 -307
- package/build/dex/trader-joe-v2_1/trader-joe-v2_1.js.map +0 -1
- package/build/dex/trader-joe-v2_1/types.d.ts +0 -82
- package/build/dex/trader-joe-v2_1/types.js +0 -9
- package/build/dex/trader-joe-v2_1/types.js.map +0 -1
- package/build/dex/wombat/wombat-pool-poller.d.ts +0 -22
- package/build/dex/wombat/wombat-pool-poller.js +0 -164
- package/build/dex/wombat/wombat-pool-poller.js.map +0 -1
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import { BigNumber } from '@ethersproject/bignumber';
|
|
3
|
+
|
|
4
|
+
import { BasePool } from '../balancer-v2-pool';
|
|
5
|
+
import { NULL_ADDRESS, SwapSide } from '../../../../constants';
|
|
6
|
+
import {
|
|
7
|
+
decodeThrowError,
|
|
8
|
+
getTokenScalingFactor,
|
|
9
|
+
safeParseFixed,
|
|
10
|
+
} from '../../utils';
|
|
11
|
+
import { callData, SubgraphPoolBase, PoolState, TokenState } from '../../types';
|
|
12
|
+
import { MathSol } from '../../balancer-v2-math';
|
|
13
|
+
import {
|
|
14
|
+
GyroEMaths,
|
|
15
|
+
DerivedGyroEParams,
|
|
16
|
+
GyroEParams,
|
|
17
|
+
balancesFromTokenInOut,
|
|
18
|
+
Vector2,
|
|
19
|
+
} from '@balancer-labs/sor';
|
|
20
|
+
import GyroEAbi from '../../../../abi/balancer-v2/gyro-e.abi.json';
|
|
21
|
+
import * as util from 'util';
|
|
22
|
+
|
|
23
|
+
// Swap Limit factor
|
|
24
|
+
const SWAP_LIMIT_FACTOR = BigInt('999999000000000000');
|
|
25
|
+
|
|
26
|
+
// All values should be normalised to 18 decimals. e.g. 1USDC = 1e18 not 1e6
|
|
27
|
+
export type GyroEPoolPairData = {
|
|
28
|
+
balances: BigNumber[];
|
|
29
|
+
tokenRates: bigint[];
|
|
30
|
+
gyroParams: GyroEParams;
|
|
31
|
+
gyroDerivedParams: DerivedGyroEParams;
|
|
32
|
+
rateProviders: string[];
|
|
33
|
+
indexIn: number;
|
|
34
|
+
indexOut: number;
|
|
35
|
+
swapFee: bigint;
|
|
36
|
+
scalingFactors: bigint[];
|
|
37
|
+
tokenInIsToken0: boolean;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export class GyroEPool extends BasePool {
|
|
41
|
+
vaultAddress: string;
|
|
42
|
+
vaultInterface: Interface;
|
|
43
|
+
poolInterface = new Interface(GyroEAbi);
|
|
44
|
+
|
|
45
|
+
constructor(vaultAddress: string, vaultInterface: Interface) {
|
|
46
|
+
super();
|
|
47
|
+
this.vaultAddress = vaultAddress;
|
|
48
|
+
this.vaultInterface = vaultInterface;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
parsePoolPairData(
|
|
52
|
+
pool: SubgraphPoolBase,
|
|
53
|
+
poolState: PoolState,
|
|
54
|
+
tokenIn: string,
|
|
55
|
+
tokenOut: string,
|
|
56
|
+
): GyroEPoolPairData {
|
|
57
|
+
// All values should be normalised to 18 decimals. e.g. 1USDC = 1e18 not 1e6
|
|
58
|
+
let indexIn = 0,
|
|
59
|
+
indexOut = 0;
|
|
60
|
+
const scalingFactors: bigint[] = [];
|
|
61
|
+
const balances = pool.tokens.map((t, i) => {
|
|
62
|
+
if (t.address.toLowerCase() === tokenIn.toLowerCase()) indexIn = i;
|
|
63
|
+
else if (t.address.toLowerCase() === tokenOut.toLowerCase()) indexOut = i;
|
|
64
|
+
const scalingFactor = getTokenScalingFactor(t.decimals);
|
|
65
|
+
scalingFactors.push(scalingFactor);
|
|
66
|
+
return BigNumber.from(
|
|
67
|
+
this._upscale(
|
|
68
|
+
BigInt(poolState.tokens[t.address.toLowerCase()].balance),
|
|
69
|
+
scalingFactor,
|
|
70
|
+
),
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const tokenInIsToken0 = indexIn === 0;
|
|
75
|
+
|
|
76
|
+
const tokenRates = poolState.tokenRates
|
|
77
|
+
? [poolState.tokenRates![0], poolState.tokenRates![1]]
|
|
78
|
+
: [];
|
|
79
|
+
|
|
80
|
+
const rateProviders = poolState.rateProviders ?? [];
|
|
81
|
+
|
|
82
|
+
const poolPairData: GyroEPoolPairData = {
|
|
83
|
+
gyroParams: poolState.gyroParams!,
|
|
84
|
+
gyroDerivedParams: poolState.gyroDerivedParams!,
|
|
85
|
+
tokenRates,
|
|
86
|
+
rateProviders,
|
|
87
|
+
balances,
|
|
88
|
+
indexIn,
|
|
89
|
+
indexOut,
|
|
90
|
+
scalingFactors,
|
|
91
|
+
swapFee: poolState.swapFee,
|
|
92
|
+
tokenInIsToken0,
|
|
93
|
+
};
|
|
94
|
+
return poolPairData;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
getSwapMaxAmount(poolPairData: GyroEPoolPairData, side: SwapSide): bigint {
|
|
98
|
+
if (side === SwapSide.SELL) {
|
|
99
|
+
// Approximation - similar to traditional stable pools
|
|
100
|
+
return this._downscaleDown(
|
|
101
|
+
MathSol.mulDownFixed(
|
|
102
|
+
poolPairData.balances[poolPairData.indexOut].toBigInt(),
|
|
103
|
+
SWAP_LIMIT_FACTOR,
|
|
104
|
+
),
|
|
105
|
+
poolPairData.scalingFactors[poolPairData.indexIn],
|
|
106
|
+
);
|
|
107
|
+
} else {
|
|
108
|
+
return this._downscaleDown(
|
|
109
|
+
MathSol.mulDownFixed(
|
|
110
|
+
poolPairData.balances[poolPairData.indexIn].toBigInt(),
|
|
111
|
+
SWAP_LIMIT_FACTOR,
|
|
112
|
+
),
|
|
113
|
+
poolPairData.scalingFactors[poolPairData.indexOut],
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
Helper function to construct onchain multicall data for Pool.
|
|
120
|
+
*/
|
|
121
|
+
getOnChainCalls(pool: SubgraphPoolBase): callData[] {
|
|
122
|
+
const poolCallData: callData[] = [
|
|
123
|
+
{
|
|
124
|
+
target: this.vaultAddress,
|
|
125
|
+
callData: this.vaultInterface.encodeFunctionData('getPoolTokens', [
|
|
126
|
+
pool.id,
|
|
127
|
+
]),
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
target: pool.address,
|
|
131
|
+
callData: this.poolInterface.encodeFunctionData('getSwapFeePercentage'),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
target: pool.address,
|
|
135
|
+
callData: this.poolInterface.encodeFunctionData('getECLPParams'),
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
// Only version 2 of GyroE uses token rates
|
|
140
|
+
const v2Calls =
|
|
141
|
+
pool.poolTypeVersion === 2
|
|
142
|
+
? [
|
|
143
|
+
{
|
|
144
|
+
target: pool.address,
|
|
145
|
+
callData: this.poolInterface.encodeFunctionData('getTokenRates'),
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
target: pool.address,
|
|
149
|
+
callData: this.poolInterface.encodeFunctionData('rateProvider0'),
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
target: pool.address,
|
|
153
|
+
callData: this.poolInterface.encodeFunctionData('rateProvider1'),
|
|
154
|
+
},
|
|
155
|
+
]
|
|
156
|
+
: [];
|
|
157
|
+
|
|
158
|
+
return [...poolCallData, ...v2Calls];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
Helper function to decode multicall data for Pool.
|
|
163
|
+
data must contain returnData
|
|
164
|
+
startIndex is where to start in returnData. Allows this decode function to be called along with other pool types.
|
|
165
|
+
*/
|
|
166
|
+
decodeOnChainCalls(
|
|
167
|
+
pool: SubgraphPoolBase,
|
|
168
|
+
data: { success: boolean; returnData: any }[],
|
|
169
|
+
startIndex: number,
|
|
170
|
+
): [{ [address: string]: PoolState }, number] {
|
|
171
|
+
const pools = {} as { [address: string]: PoolState };
|
|
172
|
+
|
|
173
|
+
const poolTokens = decodeThrowError(
|
|
174
|
+
this.vaultInterface,
|
|
175
|
+
'getPoolTokens',
|
|
176
|
+
data[startIndex++],
|
|
177
|
+
pool.address,
|
|
178
|
+
);
|
|
179
|
+
const swapFee = decodeThrowError(
|
|
180
|
+
this.poolInterface,
|
|
181
|
+
'getSwapFeePercentage',
|
|
182
|
+
data[startIndex++],
|
|
183
|
+
pool.address,
|
|
184
|
+
)[0];
|
|
185
|
+
|
|
186
|
+
const eclParams = decodeThrowError(
|
|
187
|
+
this.poolInterface,
|
|
188
|
+
'getECLPParams',
|
|
189
|
+
data[startIndex++],
|
|
190
|
+
pool.address,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
let tokenRates;
|
|
194
|
+
let rateProviders: string[] = [];
|
|
195
|
+
if (pool.poolTypeVersion === 2) {
|
|
196
|
+
tokenRates = decodeThrowError(
|
|
197
|
+
this.poolInterface,
|
|
198
|
+
'getTokenRates',
|
|
199
|
+
data[startIndex++],
|
|
200
|
+
pool.address,
|
|
201
|
+
);
|
|
202
|
+
tokenRates = tokenRates.map(t => BigInt(t.toString()));
|
|
203
|
+
|
|
204
|
+
const rateProvider0 = decodeThrowError(
|
|
205
|
+
this.poolInterface,
|
|
206
|
+
'rateProvider0',
|
|
207
|
+
data[startIndex++],
|
|
208
|
+
pool.address,
|
|
209
|
+
)[0];
|
|
210
|
+
|
|
211
|
+
const rateProvider1 = decodeThrowError(
|
|
212
|
+
this.poolInterface,
|
|
213
|
+
'rateProvider1',
|
|
214
|
+
data[startIndex++],
|
|
215
|
+
pool.address,
|
|
216
|
+
)[0];
|
|
217
|
+
rateProviders = [rateProvider0, rateProvider1];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const poolState: PoolState = {
|
|
221
|
+
gyroParams: eclParams.params,
|
|
222
|
+
gyroDerivedParams: eclParams.d,
|
|
223
|
+
swapFee: BigInt(swapFee.toString()),
|
|
224
|
+
tokenRates,
|
|
225
|
+
rateProviders,
|
|
226
|
+
orderedTokens: poolTokens.tokens,
|
|
227
|
+
tokens: poolTokens.tokens.reduce(
|
|
228
|
+
(ptAcc: { [address: string]: TokenState }, pt: string, j: number) => {
|
|
229
|
+
const tokenState: TokenState = {
|
|
230
|
+
balance: BigInt(poolTokens.balances[j].toString()),
|
|
231
|
+
};
|
|
232
|
+
ptAcc[pt.toLowerCase()] = tokenState;
|
|
233
|
+
return ptAcc;
|
|
234
|
+
},
|
|
235
|
+
{},
|
|
236
|
+
),
|
|
237
|
+
};
|
|
238
|
+
pools[pool.address] = poolState;
|
|
239
|
+
return [pools, startIndex];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
onSell(amounts: bigint[], poolPairData: GyroEPoolPairData): bigint[] {
|
|
243
|
+
try {
|
|
244
|
+
const scalingFactorTokenIn = this._scalingFactor(
|
|
245
|
+
poolPairData.tokenInIsToken0,
|
|
246
|
+
poolPairData,
|
|
247
|
+
);
|
|
248
|
+
const scalingFactorTokenOut = this._scalingFactor(
|
|
249
|
+
!poolPairData.tokenInIsToken0,
|
|
250
|
+
poolPairData,
|
|
251
|
+
);
|
|
252
|
+
const normalizedBalances = this._normalizeBalances(
|
|
253
|
+
poolPairData.balances,
|
|
254
|
+
poolPairData.tokenRates,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const orderedNormalizedBalances = balancesFromTokenInOut(
|
|
258
|
+
normalizedBalances[poolPairData.indexIn],
|
|
259
|
+
normalizedBalances[poolPairData.indexOut],
|
|
260
|
+
poolPairData.tokenInIsToken0,
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const [currentInvariant, invErr] = GyroEMaths.calculateInvariantWithError(
|
|
264
|
+
orderedNormalizedBalances,
|
|
265
|
+
poolPairData.gyroParams,
|
|
266
|
+
poolPairData.gyroDerivedParams,
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
const invariant: Vector2 = {
|
|
270
|
+
x: currentInvariant.add(invErr.mul(2)),
|
|
271
|
+
y: currentInvariant,
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const tokenAmountsInScaled = amounts.map(a =>
|
|
275
|
+
this._upscale(a, scalingFactorTokenIn),
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
const tokenAmountsInWithFee = tokenAmountsInScaled.map(a =>
|
|
279
|
+
this._subtractSwapFeeAmount(a, poolPairData.swapFee),
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
const amountsOut: bigint[] = tokenAmountsInWithFee.map(amount => {
|
|
283
|
+
try {
|
|
284
|
+
const amountOut = GyroEMaths.calcOutGivenIn(
|
|
285
|
+
orderedNormalizedBalances,
|
|
286
|
+
BigNumber.from(amount),
|
|
287
|
+
poolPairData.tokenInIsToken0,
|
|
288
|
+
poolPairData.gyroParams,
|
|
289
|
+
poolPairData.gyroDerivedParams,
|
|
290
|
+
invariant,
|
|
291
|
+
).toBigInt();
|
|
292
|
+
|
|
293
|
+
return this._downscaleDown(amountOut, scalingFactorTokenOut);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
return BigInt(0);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
return amountsOut;
|
|
300
|
+
} catch (error) {
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
onBuy(amounts: bigint[], poolPairData: GyroEPoolPairData): bigint[] {
|
|
306
|
+
try {
|
|
307
|
+
const scalingFactorTokenIn = this._scalingFactor(
|
|
308
|
+
poolPairData.tokenInIsToken0,
|
|
309
|
+
poolPairData,
|
|
310
|
+
);
|
|
311
|
+
const scalingFactorTokenOut = this._scalingFactor(
|
|
312
|
+
!poolPairData.tokenInIsToken0,
|
|
313
|
+
poolPairData,
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
const normalizedBalances = this._normalizeBalances(
|
|
317
|
+
poolPairData.balances,
|
|
318
|
+
poolPairData.tokenRates,
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
const orderedNormalizedBalances = balancesFromTokenInOut(
|
|
322
|
+
normalizedBalances[poolPairData.indexIn],
|
|
323
|
+
normalizedBalances[poolPairData.indexOut],
|
|
324
|
+
poolPairData.tokenInIsToken0,
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
const [currentInvariant, invErr] = GyroEMaths.calculateInvariantWithError(
|
|
328
|
+
orderedNormalizedBalances,
|
|
329
|
+
poolPairData.gyroParams,
|
|
330
|
+
poolPairData.gyroDerivedParams,
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
const invariant: Vector2 = {
|
|
334
|
+
x: currentInvariant.add(invErr.mul(2)),
|
|
335
|
+
y: currentInvariant,
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const tokenAmountsOutScaled = amounts.map(a =>
|
|
339
|
+
this._upscale(a, scalingFactorTokenOut),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const amountsIn: bigint[] = tokenAmountsOutScaled.map(amount => {
|
|
343
|
+
try {
|
|
344
|
+
const amountIn = GyroEMaths.calcInGivenOut(
|
|
345
|
+
orderedNormalizedBalances,
|
|
346
|
+
BigNumber.from(amount),
|
|
347
|
+
poolPairData.tokenInIsToken0,
|
|
348
|
+
poolPairData.gyroParams,
|
|
349
|
+
poolPairData.gyroDerivedParams,
|
|
350
|
+
invariant,
|
|
351
|
+
).toBigInt();
|
|
352
|
+
return amountIn;
|
|
353
|
+
} catch (error) {
|
|
354
|
+
return BigInt(0);
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const downScaled = amountsIn.map(amount =>
|
|
359
|
+
this._downscaleUp(amount, scalingFactorTokenIn),
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
return downScaled.map(a => this._addFeeAmount(a, poolPairData.swapFee));
|
|
363
|
+
} catch (error) {
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
private _scalingFactor(
|
|
369
|
+
token0: boolean,
|
|
370
|
+
poolPairData: GyroEPoolPairData,
|
|
371
|
+
): bigint {
|
|
372
|
+
const tokenIndex = token0 ? 0 : 1;
|
|
373
|
+
const scalingFactor = poolPairData.scalingFactors[tokenIndex];
|
|
374
|
+
if (
|
|
375
|
+
poolPairData.rateProviders.length === 0 ||
|
|
376
|
+
poolPairData.rateProviders[tokenIndex].toLowerCase() === NULL_ADDRESS
|
|
377
|
+
) {
|
|
378
|
+
return scalingFactor;
|
|
379
|
+
} else {
|
|
380
|
+
return MathSol.mulDownFixed(
|
|
381
|
+
scalingFactor,
|
|
382
|
+
poolPairData.tokenRates[tokenIndex],
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
private _normalizeBalances(
|
|
388
|
+
balances: BigNumber[],
|
|
389
|
+
tokenRates: bigint[],
|
|
390
|
+
): BigNumber[] {
|
|
391
|
+
// If pool is V1, e.g. has no tokenRates return balances
|
|
392
|
+
if (tokenRates.length === 0) return balances;
|
|
393
|
+
/*
|
|
394
|
+
Apply tokenRates
|
|
395
|
+
SOR upscales here first using scalingFactors but this is already being done in parse pair data so no need to repeat.
|
|
396
|
+
*/
|
|
397
|
+
return balances.map((bal, i) => {
|
|
398
|
+
return BigNumber.from(
|
|
399
|
+
MathSol.mulDownFixed(bal.toBigInt(), tokenRates[i]),
|
|
400
|
+
);
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function _reduceFee(amountIn: bigint, swapFee: bigint): bigint {
|
|
2
|
+
const product = amountIn * swapFee;
|
|
3
|
+
const feeAmount = (product - 1n) / 1000000000000000000n + 1n;
|
|
4
|
+
return amountIn - feeAmount;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function _addFee(amountIn: bigint, swapFee: bigint): bigint {
|
|
8
|
+
const fee = 1000000000000000000n - swapFee;
|
|
9
|
+
return divUp(amountIn, fee);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function divUp(a: bigint, b: bigint): bigint {
|
|
13
|
+
const aInflated = a * 1000000000000000000n;
|
|
14
|
+
return (aInflated - 1n) / b + 1n;
|
|
15
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
import { Contract } from '@ethersproject/contracts';
|
|
4
|
+
import { JsonRpcProvider } from '@ethersproject/providers';
|
|
5
|
+
import VaultABI from '../../abi/balancer-v2/vault.json';
|
|
6
|
+
|
|
7
|
+
// Compare retrieve an onchain query result for a single swap
|
|
8
|
+
export async function queryOnChain(
|
|
9
|
+
rpcUrl: string,
|
|
10
|
+
blockNumber: number,
|
|
11
|
+
poolId: string,
|
|
12
|
+
kind: 0 | 1,
|
|
13
|
+
assetIn: string,
|
|
14
|
+
assetOut: string,
|
|
15
|
+
amount: BigInt,
|
|
16
|
+
): Promise<bigint[]> {
|
|
17
|
+
const provider = new JsonRpcProvider(rpcUrl);
|
|
18
|
+
const vaultAddress = '0xBA12222222228d8Ba445958a75a0704d566BF2C8';
|
|
19
|
+
const vaultContract = new Contract(vaultAddress, VaultABI, provider);
|
|
20
|
+
|
|
21
|
+
const funds = {
|
|
22
|
+
sender: '0x0000000000000000000000000000000000000000',
|
|
23
|
+
recipient: '0x0000000000000000000000000000000000000000',
|
|
24
|
+
fromInternalBalance: false,
|
|
25
|
+
toInternalBalance: false,
|
|
26
|
+
};
|
|
27
|
+
const swaps = [
|
|
28
|
+
{
|
|
29
|
+
poolId,
|
|
30
|
+
assetInIndex: 0,
|
|
31
|
+
assetOutIndex: 1,
|
|
32
|
+
amount,
|
|
33
|
+
userData: '0x',
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
const assets = [assetIn, assetOut];
|
|
37
|
+
const deltas = await vaultContract.callStatic.queryBatchSwap(
|
|
38
|
+
kind,
|
|
39
|
+
swaps,
|
|
40
|
+
assets,
|
|
41
|
+
funds,
|
|
42
|
+
{
|
|
43
|
+
blockTag: blockNumber,
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
// console.log(deltas.toString());
|
|
47
|
+
return [deltas[0].toBigInt(), deltas[1].toBigInt()];
|
|
48
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NumberAsString } from '@paraswap/core';
|
|
2
2
|
import { Address } from '../../types';
|
|
3
|
+
import { DerivedGyroEParams, GyroEParams } from '@balancer-labs/sor';
|
|
3
4
|
|
|
4
5
|
// These should match the Balancer Pool types available on Subgraph
|
|
5
6
|
export enum BalancerPoolTypes {
|
|
@@ -20,6 +21,8 @@ export enum BalancerPoolTypes {
|
|
|
20
21
|
SiloLinear = 'SiloLinear',
|
|
21
22
|
TetuLinear = 'TetuLinear',
|
|
22
23
|
YearnLinear = 'YearnLinear',
|
|
24
|
+
Gyro3 = 'Gyro3',
|
|
25
|
+
GyroE = 'GyroE',
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
export type TokenState = {
|
|
@@ -32,6 +35,10 @@ export type PoolState = {
|
|
|
32
35
|
tokens: {
|
|
33
36
|
[address: string]: TokenState;
|
|
34
37
|
};
|
|
38
|
+
tokenRates?: bigint[];
|
|
39
|
+
rateProviders?: string[];
|
|
40
|
+
gyroParams?: GyroEParams;
|
|
41
|
+
gyroDerivedParams?: DerivedGyroEParams;
|
|
35
42
|
swapFee: bigint;
|
|
36
43
|
orderedTokens: string[];
|
|
37
44
|
rate?: bigint;
|
|
@@ -71,12 +78,31 @@ export interface SubgraphPoolBase {
|
|
|
71
78
|
id: string;
|
|
72
79
|
address: string;
|
|
73
80
|
poolType: BalancerPoolTypes;
|
|
81
|
+
poolTypeVersion: number;
|
|
74
82
|
tokens: SubgraphToken[];
|
|
75
83
|
tokensMap: { [tokenAddress: string]: SubgraphToken };
|
|
76
84
|
mainIndex: number;
|
|
77
85
|
wrappedIndex: number;
|
|
78
86
|
|
|
79
87
|
mainTokens: SubgraphMainToken[];
|
|
88
|
+
|
|
89
|
+
// gyro3
|
|
90
|
+
root3Alpha: string;
|
|
91
|
+
// gyroE
|
|
92
|
+
alpha: string;
|
|
93
|
+
beta: string;
|
|
94
|
+
c: string;
|
|
95
|
+
s: string;
|
|
96
|
+
lambda: string;
|
|
97
|
+
tauAlphaX: string;
|
|
98
|
+
tauAlphaY: string;
|
|
99
|
+
tauBetaX: string;
|
|
100
|
+
tauBetaY: string;
|
|
101
|
+
u: string;
|
|
102
|
+
v: string;
|
|
103
|
+
w: string;
|
|
104
|
+
z: string;
|
|
105
|
+
dSq: string;
|
|
80
106
|
}
|
|
81
107
|
|
|
82
108
|
export type BalancerSwapV2 = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getAddress } from '@ethersproject/address';
|
|
2
2
|
import { Interface, Result } from '@ethersproject/abi';
|
|
3
|
+
import { parseFixed, BigNumber } from '@ethersproject/bignumber';
|
|
3
4
|
import { getBigIntPow } from '../../utils';
|
|
4
5
|
import { BI_POWS } from '../../bigint-constants';
|
|
5
6
|
import { SwapSide } from '../../constants';
|
|
@@ -19,6 +20,21 @@ interface BalancerPathHop {
|
|
|
19
20
|
tokenOut: SubgraphToken;
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Parses a fixed-point decimal string into a BigNumber. If we do not have enough decimals to express the number, we truncate it.
|
|
25
|
+
* @param value
|
|
26
|
+
* @param decimals
|
|
27
|
+
* @returns BigNumber
|
|
28
|
+
*/
|
|
29
|
+
export function safeParseFixed(value: string, decimals = 0): BigNumber {
|
|
30
|
+
const [integer, fraction] = value.split('.');
|
|
31
|
+
if (!fraction) {
|
|
32
|
+
return parseFixed(value, decimals);
|
|
33
|
+
}
|
|
34
|
+
const safeValue = integer + '.' + fraction.slice(0, decimals);
|
|
35
|
+
return parseFixed(safeValue, decimals);
|
|
36
|
+
}
|
|
37
|
+
|
|
22
38
|
export const isSameAddress = (address1: string, address2: string): boolean =>
|
|
23
39
|
getAddress(address1) === getAddress(address2);
|
|
24
40
|
|
|
@@ -407,7 +407,7 @@ export class SynthetixState {
|
|
|
407
407
|
Address,
|
|
408
408
|
bigint,
|
|
409
409
|
bigint,
|
|
410
|
-
...Address[]
|
|
410
|
+
...Address[],
|
|
411
411
|
];
|
|
412
412
|
|
|
413
413
|
const [
|
|
@@ -437,7 +437,7 @@ export class SynthetixState {
|
|
|
437
437
|
Address,
|
|
438
438
|
Address,
|
|
439
439
|
bigint,
|
|
440
|
-
...string[]
|
|
440
|
+
...string[],
|
|
441
441
|
];
|
|
442
442
|
|
|
443
443
|
_require(
|
package/tests/constants-e2e.ts
CHANGED
|
@@ -41,6 +41,14 @@ export const Tokens: {
|
|
|
41
41
|
addBalance: balancesFn,
|
|
42
42
|
addAllowance: allowedFn,
|
|
43
43
|
},
|
|
44
|
+
R: {
|
|
45
|
+
address: '0x183015a9ba6ff60230fdeadc3f43b3d788b13e21',
|
|
46
|
+
decimals: 18,
|
|
47
|
+
},
|
|
48
|
+
sDAI: {
|
|
49
|
+
address: '0x83f20f44975d03b1b09e64809b757c47f942beea',
|
|
50
|
+
decimals: 18,
|
|
51
|
+
},
|
|
44
52
|
CUSDC: {
|
|
45
53
|
address: '0x39AA39c021dfbaE8faC545936693aC917d5E7563',
|
|
46
54
|
decimals: 8,
|
|
@@ -335,6 +343,10 @@ export const Tokens: {
|
|
|
335
343
|
address: '0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6',
|
|
336
344
|
decimals: 19,
|
|
337
345
|
},
|
|
346
|
+
GYD: {
|
|
347
|
+
address: '0xe07f9d810a48ab5c3c914ba3ca53af14e4491e8a',
|
|
348
|
+
decimals: 18,
|
|
349
|
+
},
|
|
338
350
|
},
|
|
339
351
|
[Network.ROPSTEN]: {
|
|
340
352
|
DAI: {
|
|
@@ -465,10 +477,22 @@ export const Tokens: {
|
|
|
465
477
|
address: '0xa3fa99a148fa48d14ed51d610c367c61876997f1',
|
|
466
478
|
decimals: 18,
|
|
467
479
|
},
|
|
480
|
+
BUSD: {
|
|
481
|
+
address: '0x9C9e5fD8bbc25984B178FdCE6117Defa39d2db39',
|
|
482
|
+
decimals: 18,
|
|
483
|
+
},
|
|
484
|
+
TUSD: {
|
|
485
|
+
address: '0x2e1ad108ff1d8c782fcbbb89aad783ac49586756',
|
|
486
|
+
decimals: 18,
|
|
487
|
+
},
|
|
468
488
|
SDEX: {
|
|
469
489
|
address: '0x6899fAcE15c14348E1759371049ab64A3a06bFA6',
|
|
470
490
|
decimals: 18,
|
|
471
491
|
},
|
|
492
|
+
MATICX: {
|
|
493
|
+
address: '0xfa68fb4628dff1028cfec22b4162fccd0d45efb6',
|
|
494
|
+
decimals: 18,
|
|
495
|
+
},
|
|
472
496
|
},
|
|
473
497
|
[Network.FANTOM]: {
|
|
474
498
|
FTM: { address: ETHER_ADDRESS, decimals: 18 },
|
|
@@ -1031,6 +1055,8 @@ export const Holders: {
|
|
|
1031
1055
|
WETH: '0x2fEb1512183545f48f6b9C5b4EbfCaF49CfCa6F3',
|
|
1032
1056
|
USDT: '0x8A446971dbB112f3be15bc38C14D44B94D9E94b9',
|
|
1033
1057
|
XAUT: '0xc4e161e8d8a4bc4ac762ab33a28bbac5474203d7',
|
|
1058
|
+
R: '0xBfe4c9D3235475C138a61f62e9e72FaD94A3303b',
|
|
1059
|
+
sDAI: '0x8846163Fedc6b881526A6B48321601b474D40923',
|
|
1034
1060
|
CVX: '0x0aCA67Fa70B142A3b9bF2eD89A81B40ff85dACdC',
|
|
1035
1061
|
MIM: '0xa046a8660e66d178ee07ec97c585eeb6aa18c26c',
|
|
1036
1062
|
AnkETH: '0xF7260D4ADc48fEefd5a19a9Eb23f9747CeE15C92',
|