@paraswap/dex-lib 3.8.37 → 3.8.38

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.
Files changed (46) hide show
  1. package/build/abi/cables/CablesMainnetRFQ.json +1073 -0
  2. package/build/dex/cables/cables.d.ts +64 -0
  3. package/build/dex/cables/cables.js +445 -0
  4. package/build/dex/cables/cables.js.map +1 -0
  5. package/build/dex/cables/config.d.ts +4 -0
  6. package/build/dex/cables/config.js +15 -0
  7. package/build/dex/cables/config.js.map +1 -0
  8. package/build/dex/cables/constants.d.ts +19 -0
  9. package/build/dex/cables/constants.js +26 -0
  10. package/build/dex/cables/constants.js.map +1 -0
  11. package/build/dex/cables/rate-fetcher.d.ts +34 -0
  12. package/build/dex/cables/rate-fetcher.js +117 -0
  13. package/build/dex/cables/rate-fetcher.js.map +1 -0
  14. package/build/dex/cables/types.d.ts +106 -0
  15. package/build/dex/cables/types.js +12 -0
  16. package/build/dex/cables/types.js.map +1 -0
  17. package/build/dex/cables/validators.d.ts +5 -0
  18. package/build/dex/cables/validators.js +49 -0
  19. package/build/dex/cables/validators.js.map +1 -0
  20. package/build/dex/spark/config.js +25 -0
  21. package/build/dex/spark/config.js.map +1 -1
  22. package/build/dex/spark/scripts/validate-state.js +1 -1
  23. package/build/dex/spark/scripts/validate-state.js.map +1 -1
  24. package/build/dex/spark/spark-sdai-pool.d.ts +7 -3
  25. package/build/dex/spark/spark-sdai-pool.js +24 -28
  26. package/build/dex/spark/spark-sdai-pool.js.map +1 -1
  27. package/build/dex/spark/spark.d.ts +10 -5
  28. package/build/dex/spark/spark.js +46 -31
  29. package/build/dex/spark/spark.js.map +1 -1
  30. package/build/dex/spark/types.d.ts +6 -0
  31. package/build/dex/spark/types.js.map +1 -1
  32. package/build/dex/spark/utils.d.ts +3 -1
  33. package/build/dex/spark/utils.js +43 -7
  34. package/build/dex/spark/utils.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/abi/sdai/SavingsUSDS.abi.json +720 -0
  37. package/src/dex/spark/config.ts +24 -0
  38. package/src/dex/spark/scripts/validate-state.ts +1 -0
  39. package/src/dex/spark/spark-e2e.test.ts +25 -21
  40. package/src/dex/spark/spark-events.test.ts +77 -62
  41. package/src/dex/spark/spark-integration.test.ts +290 -7
  42. package/src/dex/spark/spark-sdai-pool.ts +22 -19
  43. package/src/dex/spark/spark.ts +62 -36
  44. package/src/dex/spark/types.ts +6 -0
  45. package/src/dex/spark/utils.ts +83 -19
  46. package/tests/constants-e2e.ts +5 -0
@@ -1,6 +1,11 @@
1
1
  import { SimpleExchange } from '../simple-exchange';
2
2
  import { Context, IDex } from '../idex';
3
- import { SparkParams, SparkData, SparkSDaiFunctions } from './types';
3
+ import {
4
+ SparkParams,
5
+ SparkData,
6
+ SparkSDaiFunctions,
7
+ SparkSDaiPoolState,
8
+ } from './types';
4
9
  import { Network, SwapSide } from '../../constants';
5
10
  import { getDexKeysWithNetwork } from '../../utils';
6
11
  import { Adapters, SDaiConfig } from './config';
@@ -21,7 +26,7 @@ import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
21
26
  import PotAbi from '../../abi/maker-psm/pot.json';
22
27
  import SavingsDaiAbi from '../../abi/sdai/SavingsDai.abi.json';
23
28
  import { Interface } from 'ethers/lib/utils';
24
- import { SparkSDaiEventPool } from './spark-sdai-pool';
29
+ import { calcChi, RAY, SparkSDaiEventPool } from './spark-sdai-pool';
25
30
  import { BI_POWS } from '../../bigint-constants';
26
31
  import { SDAI_DEPOSIT_GAS_COST, SDAI_REDEEM_GAS_COST } from './constants';
27
32
  import { extractReturnAmountPosition } from '../../executor/utils';
@@ -42,25 +47,29 @@ export class Spark
42
47
  constructor(
43
48
  protected network: Network,
44
49
  dexKey: string,
45
- protected dexHelper: IDexHelper,
50
+ readonly dexHelper: IDexHelper,
46
51
 
47
52
  readonly daiAddress: string = SDaiConfig[dexKey][network].daiAddress,
48
53
  readonly sdaiAddress: string = SDaiConfig[dexKey][network].sdaiAddress,
49
54
  readonly potAddress: string = SDaiConfig[dexKey][network].potAddress,
55
+ readonly abiInterface: Interface = SDaiConfig[dexKey][network]
56
+ .poolInterface,
50
57
 
51
58
  protected adapters = Adapters[network] || {},
52
59
  protected sdaiInterface = new Interface(SavingsDaiAbi),
53
- protected potInterface = new Interface(PotAbi),
54
60
  ) {
55
61
  super(dexHelper, dexKey);
56
62
  this.logger = dexHelper.getLogger(dexKey);
57
63
  this.eventPool = new SparkSDaiEventPool(
58
64
  this.dexKey,
65
+ this.network,
59
66
  `${this.daiAddress}_${this.sdaiAddress}`,
60
67
  dexHelper,
61
68
  this.potAddress,
62
- this.potInterface,
69
+ this.abiInterface,
63
70
  this.logger,
71
+ SDaiConfig[dexKey][network].savingsRate.topic,
72
+ SDaiConfig[dexKey][network].savingsRate.symbol,
64
73
  );
65
74
  }
66
75
 
@@ -107,41 +116,38 @@ export class Spark
107
116
  limitPools?: string[],
108
117
  ): Promise<null | ExchangePrices<SparkData>> {
109
118
  if (!this.isAppropriatePair(srcToken, destToken)) return null;
110
- if (!this.eventPool.getState(blockNumber)) return null;
119
+ const state = this.eventPool.getState(blockNumber);
120
+ if (!state) return null;
121
+
122
+ const isSrcAsset = this.isDai(srcToken.address);
123
+
124
+ let calcFunction: Function;
111
125
 
112
126
  if (side === SwapSide.SELL) {
113
- const calcSellFn = (blockNumber: number, amountIn: bigint) =>
114
- this.isDai(srcToken.address)
115
- ? this.eventPool.convertToSDai(amountIn, blockNumber)
116
- : this.eventPool.convertToDai(amountIn, blockNumber);
117
-
118
- return [
119
- {
120
- prices: amounts.map(amount => calcSellFn(blockNumber, amount)),
121
- unit: calcSellFn(blockNumber, BI_POWS[18]),
122
- gasCost: SDAI_DEPOSIT_GAS_COST,
123
- exchange: this.dexKey,
124
- data: { exchange: `${this.sdaiAddress}` },
125
- poolAddresses: [`${this.sdaiAddress}`],
126
- },
127
- ];
127
+ if (isSrcAsset) {
128
+ calcFunction = this.previewDeposit.bind(this);
129
+ } else {
130
+ calcFunction = this.previewRedeem.bind(this);
131
+ }
128
132
  } else {
129
- const calcBuyFn = (blockNumber: number, amountIn: bigint) =>
130
- this.isDai(srcToken.address)
131
- ? this.eventPool.convertToDai(amountIn, blockNumber)
132
- : this.eventPool.convertToSDai(amountIn, blockNumber);
133
-
134
- return [
135
- {
136
- prices: amounts.map(amount => calcBuyFn(blockNumber, amount)),
137
- unit: calcBuyFn(blockNumber, BI_POWS[18]),
138
- gasCost: SDAI_REDEEM_GAS_COST,
139
- exchange: this.dexKey,
140
- data: { exchange: `${this.sdaiAddress}` },
141
- poolAddresses: [`${this.sdaiAddress}`],
142
- },
143
- ];
133
+ if (isSrcAsset) {
134
+ calcFunction = this.previewMint.bind(this);
135
+ } else {
136
+ calcFunction = this.previewWithdraw.bind(this);
137
+ }
144
138
  }
139
+
140
+ return [
141
+ {
142
+ // cannot produce 1:1 price without making an rpc call for block.timestamp and using it for price calculation in `calcChi` function
143
+ prices: amounts.map(amount => calcFunction(amount, state)),
144
+ unit: BI_POWS[18],
145
+ gasCost: SDAI_DEPOSIT_GAS_COST,
146
+ exchange: this.dexKey,
147
+ data: { exchange: `${this.sdaiAddress}` },
148
+ poolAddresses: [`${this.sdaiAddress}`],
149
+ },
150
+ ];
145
151
  }
146
152
 
147
153
  // Returns estimated gas cost of calldata for this DEX in multiSwap
@@ -286,4 +292,24 @@ export class Spark
286
292
  networkFee: '0',
287
293
  };
288
294
  }
295
+
296
+ previewRedeem(shares: bigint, state: SparkSDaiPoolState) {
297
+ return (shares * calcChi(state)) / RAY;
298
+ }
299
+
300
+ previewMint(shares: bigint, state: SparkSDaiPoolState) {
301
+ return this.divUp(shares * calcChi(state), RAY);
302
+ }
303
+
304
+ previewWithdraw(assets: bigint, state: SparkSDaiPoolState) {
305
+ return this.divUp(assets * RAY, calcChi(state));
306
+ }
307
+
308
+ previewDeposit(assets: bigint, state: SparkSDaiPoolState) {
309
+ return (assets * RAY) / calcChi(state);
310
+ }
311
+
312
+ divUp(x: bigint, y: bigint): bigint {
313
+ return x !== 0n ? (x - 1n) / y + 1n : 0n;
314
+ }
289
315
  }
@@ -1,3 +1,4 @@
1
+ import { Interface } from '@ethersproject/abi';
1
2
  import { Address } from '../../types';
2
3
 
3
4
  export type SparkData = { exchange: Address };
@@ -6,6 +7,11 @@ export type SparkParams = {
6
7
  sdaiAddress: Address;
7
8
  daiAddress: Address;
8
9
  potAddress: Address;
10
+ savingsRate: {
11
+ symbol: 'dsr' | 'ssr';
12
+ topic: string;
13
+ };
14
+ poolInterface: Interface;
9
15
  };
10
16
 
11
17
  export enum SparkSDaiFunctions {
@@ -4,34 +4,60 @@ import { Interface, AbiCoder } from '@ethersproject/abi';
4
4
 
5
5
  const coder = new AbiCoder();
6
6
 
7
- // - `dsr`: the Dai Savings Rate
7
+ // - `dsr` || `ssr`: the Dai Savings Rate or USDS savings rate
8
8
  // - `chi`: the Rate Accumulator
9
9
  // - `rho`: time of last drip
10
10
  export async function getOnChainState(
11
11
  multiContract: Contract,
12
12
  potAddress: string,
13
13
  potInterface: Interface,
14
+ savingsRateSymbol: 'dsr' | 'ssr',
14
15
  blockNumber: number | 'latest',
15
16
  ): Promise<SparkSDaiPoolState> {
17
+ if (savingsRateSymbol === 'dsr') {
18
+ return getOnChainStateSDAI(
19
+ multiContract,
20
+ potAddress,
21
+ potInterface,
22
+ blockNumber,
23
+ );
24
+ }
25
+
26
+ return getOnChainStateUSDS(
27
+ multiContract,
28
+ potAddress,
29
+ potInterface,
30
+ blockNumber,
31
+ );
32
+ }
33
+
34
+ export async function getOnChainStateSDAI(
35
+ multiContract: Contract,
36
+ potAddress: string,
37
+ potInterface: Interface,
38
+ blockNumber: number | 'latest',
39
+ ): Promise<SparkSDaiPoolState> {
40
+ const calls = [
41
+ {
42
+ target: potAddress,
43
+ callData: potInterface.encodeFunctionData('dsr', []),
44
+ },
45
+ {
46
+ target: potAddress,
47
+ callData: potInterface.encodeFunctionData('chi', []),
48
+ },
49
+ {
50
+ target: potAddress,
51
+ callData: potInterface.encodeFunctionData('rho', []),
52
+ },
53
+ {
54
+ target: potAddress,
55
+ callData: potInterface.encodeFunctionData('live', []),
56
+ },
57
+ ];
58
+
16
59
  const data: { returnData: any[] } = await multiContract.methods
17
- .aggregate([
18
- {
19
- target: potAddress,
20
- callData: potInterface.encodeFunctionData('dsr', []),
21
- },
22
- {
23
- target: potAddress,
24
- callData: potInterface.encodeFunctionData('chi', []),
25
- },
26
- {
27
- target: potAddress,
28
- callData: potInterface.encodeFunctionData('rho', []),
29
- },
30
- {
31
- target: potAddress,
32
- callData: potInterface.encodeFunctionData('live', []),
33
- },
34
- ])
60
+ .aggregate(calls)
35
61
  .call({}, blockNumber);
36
62
 
37
63
  const [dsr, chi, rho, live] = data.returnData.map(item =>
@@ -45,3 +71,41 @@ export async function getOnChainState(
45
71
  rho,
46
72
  };
47
73
  }
74
+
75
+ export async function getOnChainStateUSDS(
76
+ multiContract: Contract,
77
+ potAddress: string,
78
+ potInterface: Interface,
79
+ blockNumber: number | 'latest',
80
+ ): Promise<SparkSDaiPoolState> {
81
+ const calls = [
82
+ {
83
+ target: potAddress,
84
+ callData: potInterface.encodeFunctionData('ssr', []),
85
+ },
86
+ {
87
+ target: potAddress,
88
+ callData: potInterface.encodeFunctionData('chi', []),
89
+ },
90
+ {
91
+ target: potAddress,
92
+ callData: potInterface.encodeFunctionData('rho', []),
93
+ },
94
+ ];
95
+
96
+ const data: { returnData: any[] } = await multiContract.methods
97
+ .aggregate(calls)
98
+ .call({}, blockNumber);
99
+
100
+ const [dsr, chi, rho] = data.returnData.map(item =>
101
+ coder.decode(['uint256'], item)[0].toString(),
102
+ );
103
+
104
+ return {
105
+ // 'hack' - sUSDS doesn't have global shutdown and no notion of `live`, so it's always `live`
106
+ live: true,
107
+ dsr,
108
+ chi,
109
+ rho,
110
+ };
111
+ }
@@ -19,6 +19,10 @@ export const Tokens: {
19
19
  [network: number]: { [symbol: string]: SmartTokenParams };
20
20
  } = {
21
21
  [Network.MAINNET]: {
22
+ sUSDS: {
23
+ address: '0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD',
24
+ decimals: 18,
25
+ },
22
26
  USDS: {
23
27
  address: '0xdC035D45d973E3EC169d2276DDab16f1e407384F',
24
28
  decimals: 18,
@@ -1511,6 +1515,7 @@ export const Holders: {
1511
1515
  } = {
1512
1516
  [Network.MAINNET]: {
1513
1517
  USDS: '0xB1796E8f1eEcF23027c1E3C00fE303629A189d10',
1518
+ sUSDS: '0xd564B3aE673CAa49D054Bf185bD72a6853763eE7',
1514
1519
  SKY: '0x0ddda327A6614130CCb20bc0097313A282176A01',
1515
1520
  MKR: '0xe9aAA7A9DDc0877626C1779AbC29993aD89A6c1f',
1516
1521
  // Idle tokens