@paraswap/dex-lib 2.43.0 → 2.44.0
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 +2 -0
- 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/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 +2 -0
- package/src/dex/simple-exchange.ts +8 -1
- package/src/dex/swell/config.ts +27 -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/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: '0x221cf6d7569b35726e73e5f329bad2ee3836c4fc',
|
|
57
58
|
BuyAdapter: '0x84bEF12C9931cE12662cc9F2366b6a5029E4BD29',
|
|
58
59
|
BuyAdapter02: '0xe53d24CD81cC81bbf271AD7B02D0d67f851D727c',
|
|
59
60
|
},
|
package/src/dex/index.ts
CHANGED
|
@@ -83,6 +83,7 @@ import { NomiswapV2 } from './uniswap-v2/nomiswap-v2';
|
|
|
83
83
|
import { Dexalot } from './dexalot/dexalot';
|
|
84
84
|
import { Smardex } from './smardex/smardex';
|
|
85
85
|
import { Wombat } from './wombat/wombat';
|
|
86
|
+
import { Swell } from './swell/swell';
|
|
86
87
|
|
|
87
88
|
const LegacyDexes = [
|
|
88
89
|
CurveV2,
|
|
@@ -163,6 +164,7 @@ const Dexes = [
|
|
|
163
164
|
SolidlyV3,
|
|
164
165
|
Smardex,
|
|
165
166
|
Wombat,
|
|
167
|
+
Swell,
|
|
166
168
|
];
|
|
167
169
|
|
|
168
170
|
export type LegacyDexConstructor = new (dexHelper: IDexHelper) => IDexTxBuilder<
|
|
@@ -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,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
|
+
}
|