@paraswap/dex-lib 2.43.0 → 2.44.1
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/swETH.json +1086 -0
- package/build/config.js +1 -0
- package/build/config.js.map +1 -1
- package/build/dex/index.js +7 -1
- package/build/dex/index.js.map +1 -1
- package/build/dex/simple-exchange.d.ts +2 -0
- package/build/dex/simple-exchange.js +5 -0
- package/build/dex/simple-exchange.js.map +1 -1
- package/build/dex/solidly/solidly.js +1 -0
- package/build/dex/solidly/solidly.js.map +1 -1
- package/build/dex/swell/config.d.ts +14 -0
- package/build/dex/swell/config.js +22 -0
- package/build/dex/swell/config.js.map +1 -0
- package/build/dex/swell/swell.d.ts +60 -0
- package/build/dex/swell/swell.js +153 -0
- package/build/dex/swell/swell.js.map +1 -0
- package/build/dex/swell/sweth-pool.d.ts +16 -0
- package/build/dex/swell/sweth-pool.js +38 -0
- package/build/dex/swell/sweth-pool.js.map +1 -0
- package/build/dex/swell/type.d.ts +3 -0
- package/build/dex/swell/type.js +3 -0
- package/build/dex/swell/type.js.map +1 -0
- package/build/dex/swell/utils.d.ts +4 -0
- package/build/dex/swell/utils.js +22 -0
- package/build/dex/swell/utils.js.map +1 -0
- package/package.json +1 -1
- package/src/abi/swETH.json +1086 -0
- package/src/config.ts +1 -0
- package/src/dex/index.ts +4 -1
- package/src/dex/simple-exchange.ts +8 -1
- package/src/dex/solidly/solidly.ts +1 -0
- package/src/dex/swell/config.ts +27 -0
- package/src/dex/swell/swell-e2e.test.ts +53 -0
- package/src/dex/swell/swell.ts +234 -0
- package/src/dex/swell/sweth-pool.ts +58 -0
- package/src/dex/swell/type.ts +3 -0
- package/src/dex/swell/utils.ts +29 -0
- package/tests/constants-e2e.ts +4 -0
package/src/config.ts
CHANGED
|
@@ -54,6 +54,7 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
54
54
|
Adapter02: '0xFC2Ba6E830a04C25e207B8214b26d8C713F6881F',
|
|
55
55
|
Adapter03: '0xBAEeb4540f59d30E567a5B563CC0c4587eDd9366',
|
|
56
56
|
Adapter04: '0x369A2FDb910d432f0a07381a5E3d27572c876713',
|
|
57
|
+
Adapter05: '0x3329dfa55A40B450952FBE0203167Ae6908E656d',
|
|
57
58
|
BuyAdapter: '0x84bEF12C9931cE12662cc9F2366b6a5029E4BD29',
|
|
58
59
|
BuyAdapter02: '0xe53d24CD81cC81bbf271AD7B02D0d67f851D727c',
|
|
59
60
|
},
|
package/src/dex/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
1
2
|
import { UnoptimizedRate } from '../types';
|
|
2
3
|
import { CurveV2 } from './curve-v2';
|
|
3
4
|
import { IDexTxBuilder, DexContructor, IDex, IRouteOptimizer } from './idex';
|
|
@@ -83,6 +84,7 @@ import { NomiswapV2 } from './uniswap-v2/nomiswap-v2';
|
|
|
83
84
|
import { Dexalot } from './dexalot/dexalot';
|
|
84
85
|
import { Smardex } from './smardex/smardex';
|
|
85
86
|
import { Wombat } from './wombat/wombat';
|
|
87
|
+
import { Swell } from './swell/swell';
|
|
86
88
|
|
|
87
89
|
const LegacyDexes = [
|
|
88
90
|
CurveV2,
|
|
@@ -163,6 +165,7 @@ const Dexes = [
|
|
|
163
165
|
SolidlyV3,
|
|
164
166
|
Smardex,
|
|
165
167
|
Wombat,
|
|
168
|
+
Swell,
|
|
166
169
|
];
|
|
167
170
|
|
|
168
171
|
export type LegacyDexConstructor = new (dexHelper: IDexHelper) => IDexTxBuilder<
|
|
@@ -292,7 +295,7 @@ export class DexAdapterService {
|
|
|
292
295
|
}
|
|
293
296
|
|
|
294
297
|
getAllDexKeys() {
|
|
295
|
-
return this.dexKeys;
|
|
298
|
+
return _.uniq(this.dexKeys);
|
|
296
299
|
}
|
|
297
300
|
|
|
298
301
|
getDexByKey(key: string): IDex<any, any, any> {
|
|
@@ -44,7 +44,7 @@ export class SimpleExchange {
|
|
|
44
44
|
readonly cacheStateKey: string;
|
|
45
45
|
private readonly cacheApprovesKey: string;
|
|
46
46
|
|
|
47
|
-
constructor(dexHelper: IDexHelper, public dexKey: string) {
|
|
47
|
+
constructor(protected readonly dexHelper: IDexHelper, public dexKey: string) {
|
|
48
48
|
this.simpleSwapHelper = new Interface(SimpleSwapHelperABI);
|
|
49
49
|
this.erc20Interface = new Interface(ERC20ABI);
|
|
50
50
|
this.erc20Contract = new dexHelper.web3Provider.eth.Contract(
|
|
@@ -183,4 +183,11 @@ export class SimpleExchange {
|
|
|
183
183
|
networkFee,
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
|
+
|
|
187
|
+
protected isWETH(tokenAddress: string) {
|
|
188
|
+
const weth =
|
|
189
|
+
this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase();
|
|
190
|
+
|
|
191
|
+
return tokenAddress.toLowerCase() === weth;
|
|
192
|
+
}
|
|
186
193
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Network, SwapSide } from '../../constants';
|
|
2
|
+
import { DexConfigMap } from '../../types';
|
|
3
|
+
|
|
4
|
+
type DexParams = {
|
|
5
|
+
swETH: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const SwellConfig: DexConfigMap<DexParams> = {
|
|
9
|
+
Swell: {
|
|
10
|
+
[Network.MAINNET]: {
|
|
11
|
+
swETH: '0xf951E335afb289353dc249e82926178EaC7DEd78',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const Adapters: {
|
|
17
|
+
[chainId: number]: { [side: string]: { name: string; index: number }[] };
|
|
18
|
+
} = {
|
|
19
|
+
[Network.MAINNET]: {
|
|
20
|
+
[SwapSide.SELL]: [
|
|
21
|
+
{
|
|
22
|
+
name: 'Adapter05',
|
|
23
|
+
index: 1,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
|
|
4
|
+
import { testE2E } from '../../../tests/utils-e2e';
|
|
5
|
+
import { Tokens, Holders } from '../../../tests/constants-e2e';
|
|
6
|
+
import { Network, ContractMethod, SwapSide } from '../../constants';
|
|
7
|
+
import { StaticJsonRpcProvider } from '@ethersproject/providers';
|
|
8
|
+
import { generateConfig } from '../../config';
|
|
9
|
+
|
|
10
|
+
describe('Swell', () => {
|
|
11
|
+
const network = Network.MAINNET;
|
|
12
|
+
const tokens = Tokens[network];
|
|
13
|
+
const holders = Holders[network];
|
|
14
|
+
const provider = new StaticJsonRpcProvider(
|
|
15
|
+
generateConfig(network).privateHttpProvider,
|
|
16
|
+
network,
|
|
17
|
+
);
|
|
18
|
+
const dexKey = 'Swell';
|
|
19
|
+
|
|
20
|
+
[
|
|
21
|
+
ContractMethod.simpleSwap,
|
|
22
|
+
ContractMethod.multiSwap,
|
|
23
|
+
ContractMethod.megaSwap,
|
|
24
|
+
].forEach(contractMethod => {
|
|
25
|
+
it(`${contractMethod} - ETH -> SWETH`, async () => {
|
|
26
|
+
await testE2E(
|
|
27
|
+
tokens.ETH,
|
|
28
|
+
tokens.SWETH,
|
|
29
|
+
holders.ETH,
|
|
30
|
+
'1000000000000000000',
|
|
31
|
+
SwapSide.SELL,
|
|
32
|
+
dexKey,
|
|
33
|
+
contractMethod,
|
|
34
|
+
network,
|
|
35
|
+
provider,
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it(`${contractMethod} - WETH -> SWETH`, async () => {
|
|
40
|
+
await testE2E(
|
|
41
|
+
tokens.WETH,
|
|
42
|
+
tokens.SWETH,
|
|
43
|
+
holders.WETH,
|
|
44
|
+
'1000000000000000000',
|
|
45
|
+
SwapSide.SELL,
|
|
46
|
+
dexKey,
|
|
47
|
+
contractMethod,
|
|
48
|
+
network,
|
|
49
|
+
provider,
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { Interface, JsonFragment } from '@ethersproject/abi';
|
|
2
|
+
import { NumberAsString, SwapSide } from '@paraswap/core';
|
|
3
|
+
import {
|
|
4
|
+
AdapterExchangeParam,
|
|
5
|
+
Address,
|
|
6
|
+
ExchangePrices,
|
|
7
|
+
Logger,
|
|
8
|
+
PoolLiquidity,
|
|
9
|
+
PoolPrices,
|
|
10
|
+
SimpleExchangeParam,
|
|
11
|
+
Token,
|
|
12
|
+
TransferFeeParams,
|
|
13
|
+
} from '../../types';
|
|
14
|
+
import { IDex } from '../idex';
|
|
15
|
+
import SWETH_ABI from '../../abi/swETH.json';
|
|
16
|
+
import { ETHER_ADDRESS, Network } from '../../constants';
|
|
17
|
+
import { IDexHelper } from '../../dex-helper';
|
|
18
|
+
import { SimpleExchange } from '../simple-exchange';
|
|
19
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
20
|
+
import { AsyncOrSync } from 'ts-essentials';
|
|
21
|
+
import { getOnChainState } from './utils';
|
|
22
|
+
import { SwethPool } from './sweth-pool';
|
|
23
|
+
import { getDexKeysWithNetwork, isETHAddress } from '../../utils';
|
|
24
|
+
import { WethFunctions } from '../weth/types';
|
|
25
|
+
import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
|
|
26
|
+
import _ from 'lodash';
|
|
27
|
+
import { SwellConfig, Adapters } from './config';
|
|
28
|
+
|
|
29
|
+
export enum swETHFunctions {
|
|
30
|
+
deposit = 'deposit',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type SwellData = {};
|
|
34
|
+
export type SwellParams = {};
|
|
35
|
+
|
|
36
|
+
export class Swell
|
|
37
|
+
extends SimpleExchange
|
|
38
|
+
implements IDex<SwellData, SwellParams>
|
|
39
|
+
{
|
|
40
|
+
static dexKeys = ['Swell'];
|
|
41
|
+
swETHInterface: Interface;
|
|
42
|
+
needWrapNative = false;
|
|
43
|
+
hasConstantPriceLargeAmounts: boolean = true;
|
|
44
|
+
swETHAddress: string;
|
|
45
|
+
eventPool: SwethPool;
|
|
46
|
+
logger: Logger;
|
|
47
|
+
|
|
48
|
+
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
49
|
+
getDexKeysWithNetwork(_.pick(SwellConfig, ['Swell']));
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
protected network: Network,
|
|
53
|
+
dexKey: string,
|
|
54
|
+
protected dexHelper: IDexHelper,
|
|
55
|
+
protected config = SwellConfig[dexKey][network],
|
|
56
|
+
protected adapters = Adapters[network],
|
|
57
|
+
) {
|
|
58
|
+
super(dexHelper, 'Swell');
|
|
59
|
+
|
|
60
|
+
this.network = dexHelper.config.data.network;
|
|
61
|
+
this.swETHInterface = new Interface(SWETH_ABI as JsonFragment[]);
|
|
62
|
+
this.swETHAddress = this.config.swETH.toLowerCase();
|
|
63
|
+
this.logger = dexHelper.getLogger(this.dexKey);
|
|
64
|
+
this.eventPool = new SwethPool(
|
|
65
|
+
this.dexKey,
|
|
66
|
+
dexHelper,
|
|
67
|
+
this.swETHAddress,
|
|
68
|
+
this.swETHInterface,
|
|
69
|
+
this.logger,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async initializePricing(blockNumber: number) {
|
|
74
|
+
const poolState = await getOnChainState(
|
|
75
|
+
this.dexHelper.multiContract,
|
|
76
|
+
this.swETHAddress,
|
|
77
|
+
this.swETHInterface,
|
|
78
|
+
blockNumber,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
await this.eventPool.initialize(blockNumber, {
|
|
82
|
+
state: poolState,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
getPoolIdentifierKey(): string {
|
|
87
|
+
return `${ETHER_ADDRESS}_${this.swETHAddress}`.toLowerCase();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
isEligibleSwap(
|
|
91
|
+
srcToken: Token | string,
|
|
92
|
+
destToken: Token | string,
|
|
93
|
+
side: SwapSide,
|
|
94
|
+
): boolean {
|
|
95
|
+
if (side === SwapSide.BUY) return false;
|
|
96
|
+
|
|
97
|
+
const srcTokenAddress = (
|
|
98
|
+
typeof srcToken === 'string' ? srcToken : srcToken.address
|
|
99
|
+
).toLowerCase();
|
|
100
|
+
const destTokenAddress = (
|
|
101
|
+
typeof destToken === 'string' ? destToken : destToken.address
|
|
102
|
+
).toLowerCase();
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
(isETHAddress(srcTokenAddress) || this.isWETH(srcTokenAddress)) &&
|
|
106
|
+
destTokenAddress === this.swETHAddress
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
assertEligibility(
|
|
111
|
+
srcToken: Token | string,
|
|
112
|
+
destToken: Token | string,
|
|
113
|
+
side: SwapSide,
|
|
114
|
+
) {
|
|
115
|
+
if (!this.isEligibleSwap(srcToken, destToken, side)) {
|
|
116
|
+
throw new Error('Only eth/weth -> swETH swaps are supported');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async getPoolIdentifiers(
|
|
121
|
+
srcToken: Token,
|
|
122
|
+
destToken: Token,
|
|
123
|
+
side: SwapSide,
|
|
124
|
+
blockNumber: number,
|
|
125
|
+
): Promise<string[]> {
|
|
126
|
+
return this.isEligibleSwap(srcToken, destToken, side)
|
|
127
|
+
? [this.getPoolIdentifierKey()]
|
|
128
|
+
: [];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async getPricesVolume(
|
|
132
|
+
srcToken: Token,
|
|
133
|
+
destToken: Token,
|
|
134
|
+
amountsIn: bigint[],
|
|
135
|
+
side: SwapSide,
|
|
136
|
+
blockNumber: number,
|
|
137
|
+
limitPools?: string[] | undefined,
|
|
138
|
+
transferFees?: TransferFeeParams | undefined,
|
|
139
|
+
isFirstSwap?: boolean | undefined,
|
|
140
|
+
): Promise<ExchangePrices<SwellData> | null> {
|
|
141
|
+
if (!this.isEligibleSwap(srcToken, destToken, side)) return null;
|
|
142
|
+
if (this.eventPool.getState(blockNumber) === null) return null;
|
|
143
|
+
|
|
144
|
+
const unitIn = BI_POWS[18];
|
|
145
|
+
const unitOut = this.eventPool.getPrice(blockNumber, unitIn);
|
|
146
|
+
const amountsOut = amountsIn.map(amountIn =>
|
|
147
|
+
this.eventPool.getPrice(blockNumber, amountIn),
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
return [
|
|
151
|
+
{
|
|
152
|
+
prices: amountsOut,
|
|
153
|
+
unit: unitOut,
|
|
154
|
+
data: {},
|
|
155
|
+
exchange: this.dexKey,
|
|
156
|
+
poolIdentifier: this.getPoolIdentifierKey(),
|
|
157
|
+
gasCost: 120_000,
|
|
158
|
+
poolAddresses: [this.swETHAddress],
|
|
159
|
+
},
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
getAdapterParam(
|
|
164
|
+
srcToken: Address,
|
|
165
|
+
destToken: Address,
|
|
166
|
+
srcAmount: NumberAsString,
|
|
167
|
+
destAmount: NumberAsString,
|
|
168
|
+
data: SwellData,
|
|
169
|
+
side: SwapSide,
|
|
170
|
+
): AdapterExchangeParam {
|
|
171
|
+
this.assertEligibility(srcToken, destToken, side);
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
targetExchange: this.swETHAddress, // not used contract side
|
|
175
|
+
payload: '0x',
|
|
176
|
+
networkFee: '0',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async getSimpleParam(
|
|
181
|
+
srcToken: Address,
|
|
182
|
+
destToken: Address,
|
|
183
|
+
srcAmount: NumberAsString,
|
|
184
|
+
destAmount: NumberAsString,
|
|
185
|
+
data: SwellData,
|
|
186
|
+
side: SwapSide,
|
|
187
|
+
): Promise<SimpleExchangeParam> {
|
|
188
|
+
this.assertEligibility(srcToken, destToken, side);
|
|
189
|
+
|
|
190
|
+
const callees = [];
|
|
191
|
+
const calldata = [];
|
|
192
|
+
const values = [];
|
|
193
|
+
|
|
194
|
+
if (this.isWETH(srcToken)) {
|
|
195
|
+
// note: apparently ERC20 ABI contains wETH fns (deposit() and withdraw())
|
|
196
|
+
const wethUnwrapData = this.erc20Interface.encodeFunctionData(
|
|
197
|
+
WethFunctions.withdraw,
|
|
198
|
+
[srcAmount],
|
|
199
|
+
);
|
|
200
|
+
callees.push(this.dexHelper.config.data.wrappedNativeTokenAddress);
|
|
201
|
+
calldata.push(wethUnwrapData);
|
|
202
|
+
values.push('0');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const swapData = this.swETHInterface.encodeFunctionData(
|
|
206
|
+
swETHFunctions.deposit,
|
|
207
|
+
[],
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
callees.push(this.swETHAddress);
|
|
211
|
+
calldata.push(swapData);
|
|
212
|
+
values.push(srcAmount);
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
callees,
|
|
216
|
+
calldata,
|
|
217
|
+
values,
|
|
218
|
+
networkFee: '0',
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
getCalldataGasCost(poolPrices: PoolPrices<SwellData>): number | number[] {
|
|
223
|
+
return CALLDATA_GAS_COST.DEX_OVERHEAD + CALLDATA_GAS_COST.LENGTH_SMALL;
|
|
224
|
+
}
|
|
225
|
+
getAdapters(side: SwapSide): { name: string; index: number }[] | null {
|
|
226
|
+
return this.adapters?.[side] || null;
|
|
227
|
+
}
|
|
228
|
+
getTopPoolsForToken(
|
|
229
|
+
tokenAddress: string,
|
|
230
|
+
limit: number,
|
|
231
|
+
): AsyncOrSync<PoolLiquidity[]> {
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import { IDexHelper } from '../../dex-helper';
|
|
3
|
+
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
|
|
4
|
+
import { Address, Log, Logger } from '../../types';
|
|
5
|
+
import { AsyncOrSync, DeepReadonly } from 'ts-essentials';
|
|
6
|
+
import { SWETHPoolState } from './type';
|
|
7
|
+
import { getOnChainState } from './utils';
|
|
8
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
9
|
+
|
|
10
|
+
export class SwethPool extends StatefulEventSubscriber<SWETHPoolState> {
|
|
11
|
+
decoder = (log: Log) => this.poolInterface.parseLog(log);
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
parentName: string,
|
|
15
|
+
protected dexHelper: IDexHelper,
|
|
16
|
+
private poolAddress: Address,
|
|
17
|
+
private poolInterface: Interface,
|
|
18
|
+
logger: Logger,
|
|
19
|
+
) {
|
|
20
|
+
super(parentName, 'sweth', dexHelper, logger);
|
|
21
|
+
this.addressesSubscribed = [poolAddress];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected processLog(
|
|
25
|
+
state: DeepReadonly<SWETHPoolState>,
|
|
26
|
+
log: Readonly<Log>,
|
|
27
|
+
): AsyncOrSync<DeepReadonly<SWETHPoolState> | null> {
|
|
28
|
+
const event = this.decoder(log);
|
|
29
|
+
if (event.name === 'Reprice')
|
|
30
|
+
return {
|
|
31
|
+
swETHToETHRateFixed: BigInt(event.args.newSwETHToETHRate),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async generateState(
|
|
38
|
+
blockNumber: number | 'latest' = 'latest',
|
|
39
|
+
): Promise<DeepReadonly<SWETHPoolState>> {
|
|
40
|
+
const state = await getOnChainState(
|
|
41
|
+
this.dexHelper.multiContract,
|
|
42
|
+
this.poolAddress,
|
|
43
|
+
this.poolInterface,
|
|
44
|
+
blockNumber,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return state;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getPrice(blockNumber: number, ethAmount: bigint): bigint {
|
|
51
|
+
const state = this.getState(blockNumber);
|
|
52
|
+
if (!state) throw new Error('Cannot compute price');
|
|
53
|
+
const { swETHToETHRateFixed } = state;
|
|
54
|
+
|
|
55
|
+
// calculation in contract are made with UD60x18 precision
|
|
56
|
+
return (ethAmount * BI_POWS[18]) / swETHToETHRateFixed;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Contract } from 'web3-eth-contract';
|
|
2
|
+
import { SWETHPoolState } from './type';
|
|
3
|
+
import { Interface, AbiCoder } from '@ethersproject/abi';
|
|
4
|
+
|
|
5
|
+
const coder = new AbiCoder();
|
|
6
|
+
|
|
7
|
+
export async function getOnChainState(
|
|
8
|
+
multiContract: Contract,
|
|
9
|
+
poolAddress: string,
|
|
10
|
+
poolInterface: Interface,
|
|
11
|
+
blockNumber: number | 'latest',
|
|
12
|
+
): Promise<SWETHPoolState> {
|
|
13
|
+
const data: { returnData: any[] } = await multiContract.methods
|
|
14
|
+
.aggregate([
|
|
15
|
+
{
|
|
16
|
+
target: poolAddress,
|
|
17
|
+
callData: poolInterface.encodeFunctionData('swETHToETHRate', []),
|
|
18
|
+
},
|
|
19
|
+
])
|
|
20
|
+
.call({}, blockNumber);
|
|
21
|
+
|
|
22
|
+
const decodedData = coder.decode(['uint256'], data.returnData[0]);
|
|
23
|
+
|
|
24
|
+
const swETHToETHRateFixed = BigInt(decodedData[0].toString());
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
swETHToETHRateFixed,
|
|
28
|
+
};
|
|
29
|
+
}
|
package/tests/constants-e2e.ts
CHANGED