@paraswap/dex-lib 3.8.18 → 3.8.20-lite-psm

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 (171) hide show
  1. package/build/abi/inception/inception-ineth-pool.json +1062 -0
  2. package/build/abi/inception/inception-ineth.json +609 -0
  3. package/build/abi/inception/inception-ratio-feed.json +93 -0
  4. package/build/abi/inception/inception-vault.json +991 -0
  5. package/build/abi/infusion/InfusionFactory.json +147 -0
  6. package/build/abi/infusion/InfusionPair.json +658 -0
  7. package/build/abi/infusion/InfusionRouter.json +442 -0
  8. package/build/abi/lite-psm/psm.json +468 -0
  9. package/build/abi/oswap/oswap.abi.json +452 -0
  10. package/build/dex/aave-v1/aave-v1.js +0 -1
  11. package/build/dex/aave-v1/aave-v1.js.map +1 -1
  12. package/build/dex/idle-dao/idle-dao-pool.d.ts +56 -0
  13. package/build/dex/idle-dao/idle-dao-pool.js +176 -0
  14. package/build/dex/idle-dao/idle-dao-pool.js.map +1 -0
  15. package/build/dex/idle-dao/idle-dao-pooling-pool.d.ts +16 -0
  16. package/build/dex/idle-dao/idle-dao-pooling-pool.js +57 -0
  17. package/build/dex/idle-dao/idle-dao-pooling-pool.js.map +1 -0
  18. package/build/dex/idle-dao/scripts.d.ts +9 -0
  19. package/build/dex/idle-dao/scripts.js +552 -0
  20. package/build/dex/idle-dao/scripts.js.map +1 -0
  21. package/build/dex/inception/config.d.ts +5 -0
  22. package/build/dex/inception/config.js +112 -0
  23. package/build/dex/inception/config.js.map +1 -0
  24. package/build/dex/inception/inception-event-pool.d.ts +23 -0
  25. package/build/dex/inception/inception-event-pool.js +34 -0
  26. package/build/dex/inception/inception-event-pool.js.map +1 -0
  27. package/build/dex/inception/inception-native.d.ts +43 -0
  28. package/build/dex/inception/inception-native.js +131 -0
  29. package/build/dex/inception/inception-native.js.map +1 -0
  30. package/build/dex/inception/inception-pool.d.ts +18 -0
  31. package/build/dex/inception/inception-pool.js +32 -0
  32. package/build/dex/inception/inception-pool.js.map +1 -0
  33. package/build/dex/inception/inception-price-feed.d.ts +19 -0
  34. package/build/dex/inception/inception-price-feed.js +51 -0
  35. package/build/dex/inception/inception-price-feed.js.map +1 -0
  36. package/build/dex/inception/inception.d.ts +44 -0
  37. package/build/dex/inception/inception.js +162 -0
  38. package/build/dex/inception/inception.js.map +1 -0
  39. package/build/dex/inception/tokens.d.ts +9 -0
  40. package/build/dex/inception/tokens.js +28 -0
  41. package/build/dex/inception/tokens.js.map +1 -0
  42. package/build/dex/inception/types.d.ts +22 -0
  43. package/build/dex/inception/types.js +3 -0
  44. package/build/dex/inception/types.js.map +1 -0
  45. package/build/dex/inception/utils.d.ts +7 -0
  46. package/build/dex/inception/utils.js +58 -0
  47. package/build/dex/inception/utils.js.map +1 -0
  48. package/build/dex/index.js +4 -0
  49. package/build/dex/index.js.map +1 -1
  50. package/build/dex/infusion/config.d.ts +4 -0
  51. package/build/dex/infusion/config.js +25 -0
  52. package/build/dex/infusion/config.js.map +1 -0
  53. package/build/dex/infusion/infusion-stable-pool.d.ts +4 -0
  54. package/build/dex/infusion/infusion-stable-pool.js +74 -0
  55. package/build/dex/infusion/infusion-stable-pool.js.map +1 -0
  56. package/build/dex/infusion/infusion.d.ts +54 -0
  57. package/build/dex/infusion/infusion.js +510 -0
  58. package/build/dex/infusion/infusion.js.map +1 -0
  59. package/build/dex/infusion/types.d.ts +47 -0
  60. package/build/dex/infusion/types.js +3 -0
  61. package/build/dex/infusion/types.js.map +1 -0
  62. package/build/dex/infusion/utils/isStablePair.d.ts +2 -0
  63. package/build/dex/infusion/utils/isStablePair.js +18 -0
  64. package/build/dex/infusion/utils/isStablePair.js.map +1 -0
  65. package/build/dex/lite-psm/config.d.ts +3 -0
  66. package/build/dex/lite-psm/config.js +29 -0
  67. package/build/dex/lite-psm/config.js.map +1 -0
  68. package/build/dex/lite-psm/lite-psm-event-pool.d.ts +29 -0
  69. package/build/dex/lite-psm/lite-psm-event-pool.js +158 -0
  70. package/build/dex/lite-psm/lite-psm-event-pool.js.map +1 -0
  71. package/build/dex/lite-psm/lite-psm.d.ts +53 -0
  72. package/build/dex/lite-psm/lite-psm.js +365 -0
  73. package/build/dex/lite-psm/lite-psm.js.map +1 -0
  74. package/build/dex/lite-psm/types.d.ts +40 -0
  75. package/build/dex/lite-psm/types.js +3 -0
  76. package/build/dex/lite-psm/types.js.map +1 -0
  77. package/build/dex/maker-psm/maker-psm.js +3 -2
  78. package/build/dex/maker-psm/maker-psm.js.map +1 -1
  79. package/build/dex/oswap/config.d.ts +5 -0
  80. package/build/dex/oswap/config.js +31 -0
  81. package/build/dex/oswap/config.js.map +1 -0
  82. package/build/dex/oswap/oswap-pool.d.ts +51 -0
  83. package/build/dex/oswap/oswap-pool.js +150 -0
  84. package/build/dex/oswap/oswap-pool.js.map +1 -0
  85. package/build/dex/oswap/oswap.d.ts +46 -0
  86. package/build/dex/oswap/oswap.js +273 -0
  87. package/build/dex/oswap/oswap.js.map +1 -0
  88. package/build/dex/oswap/types.d.ts +20 -0
  89. package/build/dex/oswap/types.js +3 -0
  90. package/build/dex/oswap/types.js.map +1 -0
  91. package/build/dex/platypus/platypus.js +3 -17
  92. package/build/dex/platypus/platypus.js.map +1 -1
  93. package/build/dex/swaap-v1/swaap-v1.js +0 -4
  94. package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
  95. package/build/dex/trader-joe-v2.1/config.d.ts +3 -0
  96. package/build/dex/trader-joe-v2.1/config.js +5 -1
  97. package/build/dex/trader-joe-v2.1/config.js.map +1 -1
  98. package/build/dex/trader-joe-v2.1/trader-joe-v2.1.d.ts +2 -14
  99. package/build/dex/trader-joe-v2.1/trader-joe-v2.1.js +3 -85
  100. package/build/dex/trader-joe-v2.1/trader-joe-v2.1.js.map +1 -1
  101. package/package.json +1 -1
  102. package/src/abi/lite-psm/psm.json +468 -0
  103. package/src/dex/index.ts +4 -0
  104. package/src/dex/lite-psm/config.ts +29 -0
  105. package/src/dex/lite-psm/lite-psm-e2e.test.ts +79 -0
  106. package/src/dex/lite-psm/lite-psm-event-pool.ts +213 -0
  107. package/src/dex/lite-psm/lite-psm-events.test.ts +61 -0
  108. package/src/dex/lite-psm/lite-psm-integration.test.ts +96 -0
  109. package/src/dex/lite-psm/lite-psm.ts +578 -0
  110. package/src/dex/lite-psm/types.ts +46 -0
  111. package/src/dex/maker-psm/maker-psm.ts +3 -2
  112. package/src/dex/trader-joe-v2.1/base.ts +178 -0
  113. package/src/dex/trader-joe-v2.1/config.ts +5 -0
  114. package/src/dex/trader-joe-v2.1/trader-joe-v2.1.ts +8 -165
  115. package/src/dex/trader-joe-v2.1/trader-joe-v2.2.ts +23 -0
  116. package/.vscode/launch.json +0 -53
  117. package/.vscode/settings.json +0 -2
  118. package/.vscode/tasks.json +0 -15
  119. package/build/abi/maverick-v2/MaverickV2Router.json +0 -778
  120. package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
  121. package/build/abi/wombat/pool.json +0 -1289
  122. package/build/dex/aave-v2/tokens-avalanche.json +0 -44
  123. package/build/dex/aave-v2/tokens-mainnet.json +0 -188
  124. package/build/dex/aave-v2/tokens-polygon.json +0 -44
  125. package/build/dex/bProtocol.d.ts +0 -18
  126. package/build/dex/bProtocol.js +0 -39
  127. package/build/dex/bProtocol.js.map +0 -1
  128. package/build/dex/bancor.d.ts +0 -26
  129. package/build/dex/bancor.js +0 -58
  130. package/build/dex/bancor.js.map +0 -1
  131. package/build/dex/compound.d.ts +0 -18
  132. package/build/dex/compound.js +0 -46
  133. package/build/dex/compound.js.map +0 -1
  134. package/build/dex/curve-v2.d.ts +0 -58
  135. package/build/dex/curve-v2.js +0 -180
  136. package/build/dex/curve-v2.js.map +0 -1
  137. package/build/dex/dodo-v1.d.ts +0 -33
  138. package/build/dex/dodo-v1.js +0 -63
  139. package/build/dex/dodo-v1.js.map +0 -1
  140. package/build/dex/lido.d.ts +0 -19
  141. package/build/dex/lido.js +0 -42
  142. package/build/dex/lido.js.map +0 -1
  143. package/build/dex/maker-psm/scripts/gem.abi.json +0 -136
  144. package/build/dex/maker-psm/scripts/validate-state.d.ts +0 -0
  145. package/build/dex/maker-psm/scripts/validate-state.js +0 -185
  146. package/build/dex/maker-psm/scripts/validate-state.js.map +0 -1
  147. package/build/dex/maker-psm/scripts/vat.abi.json +0 -243
  148. package/build/dex/onebit.d.ts +0 -25
  149. package/build/dex/onebit.js +0 -42
  150. package/build/dex/onebit.js.map +0 -1
  151. package/build/dex/smoothy.d.ts +0 -26
  152. package/build/dex/smoothy.js +0 -48
  153. package/build/dex/smoothy.js.map +0 -1
  154. package/build/dex/solidly-v3/scripts/check-event-pool-event.d.ts +0 -1
  155. package/build/dex/solidly-v3/scripts/check-event-pool-event.js +0 -53
  156. package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +0 -1
  157. package/build/dex/stable-pool.d.ts +0 -28
  158. package/build/dex/stable-pool.js +0 -55
  159. package/build/dex/stable-pool.js.map +0 -1
  160. package/build/dex/trader-joe-v2.1/trader-joe-v2.1-new.d.ts +0 -7
  161. package/build/dex/trader-joe-v2.1/trader-joe-v2.1-new.js +0 -20
  162. package/build/dex/trader-joe-v2.1/trader-joe-v2.1-new.js.map +0 -1
  163. package/build/dex/trader-joe-v2.1.d.ts +0 -43
  164. package/build/dex/trader-joe-v2.1.js +0 -79
  165. package/build/dex/trader-joe-v2.1.js.map +0 -1
  166. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +0 -17
  167. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +0 -64
  168. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +0 -1
  169. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +0 -17
  170. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +0 -79
  171. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +0 -1
@@ -0,0 +1,578 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import {
3
+ Token,
4
+ Address,
5
+ ExchangePrices,
6
+ PoolPrices,
7
+ Log,
8
+ AdapterExchangeParam,
9
+ SimpleExchangeParam,
10
+ PoolLiquidity,
11
+ Logger,
12
+ NumberAsString,
13
+ DexExchangeParam,
14
+ ExchangeTxInfo,
15
+ PreprocessTransactionOptions,
16
+ } from '../../types';
17
+ import { SwapSide, Network, NULL_ADDRESS } from '../../constants';
18
+ import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
19
+ import {
20
+ getDexKeysWithNetwork,
21
+ getBigIntPow,
22
+ uuidToBytes16,
23
+ } from '../../utils';
24
+ import { IDex } from '../../dex/idex';
25
+ import { IDexHelper } from '../../dex-helper/idex-helper';
26
+ import {
27
+ LitePsmData,
28
+ PoolState,
29
+ PoolConfig,
30
+ LitePsmParams,
31
+ LitePsmDirectPayload,
32
+ } from './types';
33
+ import { SimpleExchange } from '../simple-exchange';
34
+ import { LitePsmConfig } from './config';
35
+ import PsmABI from '../../abi/lite-psm/psm.json';
36
+ import { BI_POWS } from '../../bigint-constants';
37
+ import { SpecialDex } from '../../executor/types';
38
+ import { hexConcat, hexZeroPad, hexlify } from '@ethersproject/bytes';
39
+ import {
40
+ ContractMethodV6,
41
+ OptimalSwapExchange,
42
+ ParaSwapVersion,
43
+ } from '@paraswap/core';
44
+ import { BigNumber } from 'ethers';
45
+ import { LitePsmEventPool, getOnChainState } from './lite-psm-event-pool';
46
+ import { extractReturnAmountPosition } from '../../executor/utils';
47
+
48
+ const psmInterface = new Interface(PsmABI);
49
+ const WAD = BI_POWS[18];
50
+
51
+ const ceilDiv = (a: bigint, b: bigint) => (a + b - 1n) / b;
52
+
53
+ export class LitePsm
54
+ extends SimpleExchange
55
+ implements IDex<LitePsmData, LitePsmDirectPayload>
56
+ {
57
+ protected eventPools: { [gemAddress: string]: LitePsmEventPool };
58
+
59
+ // warning: There is limit on swap
60
+ readonly hasConstantPriceLargeAmounts = true;
61
+ readonly isFeeOnTransferSupported = false;
62
+
63
+ public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
64
+ getDexKeysWithNetwork(LitePsmConfig);
65
+
66
+ logger: Logger;
67
+
68
+ constructor(
69
+ protected network: Network,
70
+ dexKey: string,
71
+ protected dexHelper: IDexHelper,
72
+ protected dai: Token = LitePsmConfig[dexKey][network].dai,
73
+ protected vatAddress: Address = LitePsmConfig[dexKey][network].vatAddress,
74
+ protected poolConfigs: PoolConfig[] = LitePsmConfig[dexKey][network].pools,
75
+ ) {
76
+ super(dexHelper, dexKey);
77
+ this.logger = dexHelper.getLogger(dexKey);
78
+ this.eventPools = {};
79
+ poolConfigs.forEach(
80
+ p =>
81
+ (this.eventPools[p.gem.address.toLowerCase()] = new LitePsmEventPool(
82
+ dexKey,
83
+ network,
84
+ dexHelper,
85
+ this.logger,
86
+ p,
87
+ this.vatAddress,
88
+ )),
89
+ );
90
+ }
91
+
92
+ static getDirectFunctionNameV6(): string[] {
93
+ return [ContractMethodV6.swapExactAmountInOutOnMakerPSM];
94
+ }
95
+
96
+ async initializePricing(blockNumber: number) {
97
+ const poolStates = await getOnChainState(
98
+ this.dexHelper.multiContract,
99
+ this.poolConfigs,
100
+ this.vatAddress,
101
+ blockNumber,
102
+ LitePsmConfig[this.dexKey][this.network].dai.address,
103
+ );
104
+ await Promise.all(
105
+ this.poolConfigs.map(async (p, i) => {
106
+ const eventPool = this.eventPools[p.gem.address.toLowerCase()];
107
+ await eventPool.initialize(blockNumber, {
108
+ state: poolStates[i],
109
+ });
110
+ }),
111
+ );
112
+ }
113
+
114
+ // Returns the list of contract adapters (name and index)
115
+ // for a buy/sell. Return null if there are no adapters.
116
+ getAdapters(side: SwapSide): { name: string; index: number }[] | null {
117
+ return null;
118
+ }
119
+
120
+ getEventPool(srcToken: Token, destToken: Token): LitePsmEventPool | null {
121
+ const srcAddress = srcToken.address.toLowerCase();
122
+ const destAddress = destToken.address.toLowerCase();
123
+ return (
124
+ (srcAddress === this.dai.address && this.eventPools[destAddress]) ||
125
+ (destAddress === this.dai.address && this.eventPools[srcAddress]) ||
126
+ null
127
+ );
128
+ }
129
+
130
+ // Returns list of pool identifiers that can be used
131
+ // for a given swap. poolIdentifiers must be unique
132
+ // across DEXes.
133
+ async getPoolIdentifiers(
134
+ srcToken: Token,
135
+ destToken: Token,
136
+ side: SwapSide,
137
+ blockNumber: number,
138
+ ): Promise<string[]> {
139
+ const eventPool = this.getEventPool(srcToken, destToken);
140
+ if (!eventPool) return [];
141
+ return [eventPool.getIdentifier()];
142
+ }
143
+
144
+ async getPoolState(
145
+ pool: LitePsmEventPool,
146
+ blockNumber: number,
147
+ ): Promise<PoolState> {
148
+ const eventState = pool.getState(blockNumber);
149
+ if (eventState) return eventState;
150
+ const onChainState = await pool.generateState(blockNumber);
151
+ pool.setState(onChainState, blockNumber);
152
+ return onChainState;
153
+ }
154
+
155
+ computePrices(
156
+ isSrcDai: boolean,
157
+ to18ConversionFactor: bigint,
158
+ side: SwapSide,
159
+ amounts: bigint[],
160
+ poolState: PoolState,
161
+ ): bigint[] {
162
+ const sellGemCheck = (dart: bigint) => {
163
+ return dart <= poolState.daiBalance;
164
+ };
165
+ const buyGemCheck = (dart: bigint) => {
166
+ return dart <= poolState.gemBalance * to18ConversionFactor;
167
+ };
168
+
169
+ return amounts.map(a => {
170
+ if (side === SwapSide.SELL) {
171
+ if (isSrcDai) {
172
+ const gemAmt18 = (a * WAD) / (WAD + poolState.tout);
173
+ if (buyGemCheck(gemAmt18)) return gemAmt18 / to18ConversionFactor;
174
+ } else {
175
+ const gemAmt18 = to18ConversionFactor * a;
176
+ if (sellGemCheck(gemAmt18))
177
+ return gemAmt18 - (gemAmt18 * poolState.tin) / WAD;
178
+ }
179
+ } else {
180
+ if (isSrcDai) {
181
+ const gemAmt18 = to18ConversionFactor * a;
182
+ if (buyGemCheck(gemAmt18))
183
+ return gemAmt18 + (gemAmt18 * poolState.tout) / WAD;
184
+ } else {
185
+ const gemAmt18 = (a * WAD) / (WAD - poolState.tin);
186
+ if (sellGemCheck(gemAmt18)) return gemAmt18 / to18ConversionFactor;
187
+ }
188
+ }
189
+ return 0n;
190
+ });
191
+ }
192
+
193
+ // Returns pool prices for amounts.
194
+ // If limitPools is defined only pools in limitPools
195
+ // should be used. If limitPools is undefined then
196
+ // any pools can be used.
197
+ async getPricesVolume(
198
+ srcToken: Token,
199
+ destToken: Token,
200
+ amounts: bigint[],
201
+ side: SwapSide,
202
+ blockNumber: number,
203
+ limitPools?: string[],
204
+ ): Promise<null | ExchangePrices<LitePsmData>> {
205
+ const eventPool = this.getEventPool(srcToken, destToken);
206
+ if (!eventPool) return null;
207
+
208
+ const poolIdentifier = eventPool.getIdentifier();
209
+ if (limitPools && !limitPools.includes(poolIdentifier)) return null;
210
+
211
+ const poolState = await this.getPoolState(eventPool, blockNumber);
212
+
213
+ const unitVolume = getBigIntPow(
214
+ (side === SwapSide.SELL ? srcToken : destToken).decimals,
215
+ );
216
+
217
+ const isSrcDai = srcToken.address.toLowerCase() === this.dai.address;
218
+ const gem = isSrcDai ? destToken : srcToken;
219
+ const toll =
220
+ (side === SwapSide.SELL && isSrcDai) ||
221
+ (side === SwapSide.BUY && !isSrcDai)
222
+ ? poolState.tout
223
+ : poolState.tin;
224
+
225
+ const [unit, ...prices] = this.computePrices(
226
+ isSrcDai,
227
+ eventPool.to18ConversionFactor,
228
+ side,
229
+ [unitVolume, ...amounts],
230
+ poolState,
231
+ );
232
+
233
+ return [
234
+ {
235
+ prices,
236
+ unit,
237
+ data: {
238
+ toll: toll.toString(),
239
+ psmAddress: eventPool.poolConfig.psmAddress,
240
+ gemJoinAddress: eventPool.poolConfig.gemJoinAddress,
241
+ gemDecimals: gem.decimals,
242
+ },
243
+ poolAddresses: [eventPool.poolConfig.psmAddress],
244
+ exchange: this.dexKey,
245
+ gasCost: isSrcDai ? 80_000 : 100_000,
246
+ poolIdentifier,
247
+ },
248
+ ];
249
+ }
250
+
251
+ // Returns estimated gas cost of calldata for this DEX in multiSwap
252
+ getCalldataGasCost(poolPrices: PoolPrices<LitePsmData>): number | number[] {
253
+ return (
254
+ CALLDATA_GAS_COST.DEX_OVERHEAD +
255
+ CALLDATA_GAS_COST.LENGTH_SMALL +
256
+ CALLDATA_GAS_COST.ADDRESS +
257
+ // TODO: pools have toll as zero currently but may change
258
+ CALLDATA_GAS_COST.ZERO +
259
+ // Either 1 (18 decimals) or 1e12 = 0xe8d4a51000 (6 decimals)
260
+ CALLDATA_GAS_COST.wordNonZeroBytes(
261
+ poolPrices.data.gemDecimals === 6 ? 4 : 1,
262
+ )
263
+ );
264
+ }
265
+
266
+ getPsmParams(
267
+ srcToken: string,
268
+ srcAmount: string,
269
+ destAmount: string,
270
+ data: LitePsmData,
271
+ side: SwapSide,
272
+ ): { isGemSell: boolean; gemAmount: string } {
273
+ const isSrcDai = srcToken.toLowerCase() === this.dai.address;
274
+ const to18ConversionFactor = getBigIntPow(18 - data.gemDecimals);
275
+ if (side === SwapSide.SELL) {
276
+ if (isSrcDai) {
277
+ const gemAmt18 = (BigInt(srcAmount) * WAD) / (WAD + BigInt(data.toll));
278
+ return {
279
+ isGemSell: false,
280
+ gemAmount: (gemAmt18 / to18ConversionFactor).toString(),
281
+ };
282
+ } else {
283
+ return { isGemSell: true, gemAmount: srcAmount };
284
+ }
285
+ } else {
286
+ if (isSrcDai) {
287
+ return { isGemSell: false, gemAmount: destAmount };
288
+ } else {
289
+ const gemAmt = ceilDiv(
290
+ BigInt(destAmount) * WAD,
291
+ (WAD - BigInt(data.toll)) * to18ConversionFactor,
292
+ );
293
+ return {
294
+ isGemSell: true,
295
+ gemAmount: gemAmt.toString(),
296
+ };
297
+ }
298
+ }
299
+ }
300
+
301
+ // Encode params required by the exchange adapter
302
+ // Used for multiSwap, buy & megaSwap
303
+ getAdapterParam(
304
+ srcToken: string,
305
+ destToken: string,
306
+ srcAmount: string,
307
+ destAmount: string,
308
+ data: LitePsmData,
309
+ side: SwapSide,
310
+ ): AdapterExchangeParam {
311
+ const to18ConversionFactor = getBigIntPow(18 - data.gemDecimals);
312
+ const payload = this.abiCoder.encodeParameter(
313
+ {
314
+ ParentStruct: {
315
+ gemJoinAddress: 'address',
316
+ toll: 'uint256',
317
+ to18ConversionFactor: 'uint256',
318
+ },
319
+ },
320
+ {
321
+ gemJoinAddress: data.gemJoinAddress,
322
+ toll: data.toll,
323
+ to18ConversionFactor,
324
+ },
325
+ );
326
+
327
+ return {
328
+ targetExchange: data.psmAddress,
329
+ networkFee: '0',
330
+ payload,
331
+ };
332
+ }
333
+
334
+ // Encode call data used by simpleSwap like routers
335
+ // Used for simpleSwap & simpleBuy
336
+ async getSimpleParam(
337
+ srcToken: string,
338
+ destToken: string,
339
+ srcAmount: string,
340
+ destAmount: string,
341
+ data: LitePsmData,
342
+ side: SwapSide,
343
+ ): Promise<SimpleExchangeParam> {
344
+ const { isGemSell, gemAmount } = this.getPsmParams(
345
+ srcToken,
346
+ srcAmount,
347
+ destAmount,
348
+ data,
349
+ side,
350
+ );
351
+
352
+ const swapData = psmInterface.encodeFunctionData(
353
+ isGemSell ? 'sellGem' : 'buyGem',
354
+ [this.augustusAddress, gemAmount],
355
+ );
356
+
357
+ return this.buildSimpleParamWithoutWETHConversion(
358
+ srcToken,
359
+ srcAmount,
360
+ destToken,
361
+ destAmount,
362
+ swapData,
363
+ data.psmAddress,
364
+ isGemSell ? data.gemJoinAddress : data.psmAddress,
365
+ );
366
+ }
367
+
368
+ getTokenFromAddress(address: Address): Token {
369
+ return { address, decimals: 0 };
370
+ }
371
+
372
+ async preProcessTransaction?(
373
+ optimalSwapExchange: OptimalSwapExchange<LitePsmData>,
374
+ srcToken: Token,
375
+ destToken: Token,
376
+ side: SwapSide,
377
+ options: PreprocessTransactionOptions,
378
+ ): Promise<[OptimalSwapExchange<LitePsmData>, ExchangeTxInfo]> {
379
+ if (!optimalSwapExchange.data) {
380
+ throw new Error(
381
+ `Error_${this.dexKey}_preProcessTransaction payload is not received`,
382
+ );
383
+ }
384
+
385
+ let isApproved = false;
386
+
387
+ // isApproved is only used in direct method and available only for v6, then no need to check approve for v5
388
+ // because it's either done in getSimpleParam or approve call in the adapter smart contract
389
+ if (options.version === ParaSwapVersion.V6 && options.isDirectMethod) {
390
+ isApproved = await this.dexHelper.augustusApprovals.hasApproval(
391
+ options.executionContractAddress,
392
+ srcToken.address,
393
+ srcToken.address.toLowerCase() === this.dai.address.toLowerCase()
394
+ ? optimalSwapExchange.data.psmAddress
395
+ : optimalSwapExchange.data.gemJoinAddress,
396
+ );
397
+ }
398
+
399
+ return [
400
+ {
401
+ ...optimalSwapExchange,
402
+ data: { ...optimalSwapExchange.data, isApproved },
403
+ },
404
+ {},
405
+ ];
406
+ }
407
+
408
+ getDexParam(
409
+ srcToken: Address,
410
+ destToken: Address,
411
+ srcAmount: NumberAsString,
412
+ destAmount: NumberAsString,
413
+ recipient: Address,
414
+ data: LitePsmData,
415
+ side: SwapSide,
416
+ ): DexExchangeParam {
417
+ const { isGemSell, gemAmount } = this.getPsmParams(
418
+ srcToken,
419
+ srcAmount,
420
+ destAmount,
421
+ data,
422
+ side,
423
+ );
424
+
425
+ let exchangeData = psmInterface.encodeFunctionData(
426
+ isGemSell ? 'sellGem' : 'buyGem',
427
+ [recipient, gemAmount],
428
+ );
429
+
430
+ // append toll and to18ConversionFactor & set specialDexFlag = SWAP_ON_MAKER_PSM to
431
+ // - `buyGem` on Ex1 & Ex2
432
+ // - `sellGem` on Ex3
433
+ let specialDexFlag = SpecialDex.DEFAULT;
434
+ if (
435
+ (side === SwapSide.SELL && !isGemSell) ||
436
+ (side === SwapSide.BUY && isGemSell)
437
+ ) {
438
+ exchangeData = hexConcat([
439
+ exchangeData,
440
+ hexZeroPad(hexlify(BigInt(data.toll)), 32),
441
+ hexZeroPad(hexlify(getBigIntPow(18 - data.gemDecimals)), 32),
442
+ ]);
443
+ specialDexFlag = SpecialDex.SWAP_ON_MAKER_PSM;
444
+ }
445
+
446
+ return {
447
+ needWrapNative: this.needWrapNative,
448
+ dexFuncHasRecipient: true,
449
+ exchangeData,
450
+ targetExchange: data.psmAddress,
451
+ specialDexFlag,
452
+ spender: isGemSell ? data.gemJoinAddress : data.psmAddress,
453
+ returnAmountPos: extractReturnAmountPosition(
454
+ psmInterface,
455
+ isGemSell ? 'sellGem' : 'buyGem',
456
+ isGemSell ? 'daiOutWad' : 'daiInWad',
457
+ ),
458
+ };
459
+ }
460
+
461
+ getDirectParamV6(
462
+ srcToken: Address,
463
+ destToken: Address,
464
+ fromAmount: NumberAsString,
465
+ toAmount: NumberAsString,
466
+ quotedAmount: NumberAsString,
467
+ data: LitePsmData,
468
+ side: SwapSide,
469
+ permit: string,
470
+ uuid: string,
471
+ partnerAndFee: string,
472
+ beneficiary: string,
473
+ blockNumber: number,
474
+ contractMethod: string,
475
+ ) {
476
+ if (!contractMethod) throw new Error(`contractMethod need to be passed`);
477
+ if (!LitePsm.getDirectFunctionNameV6().includes(contractMethod!)) {
478
+ throw new Error(`Invalid contract method ${contractMethod}`);
479
+ }
480
+
481
+ const beneficiaryParam = BigNumber.from(beneficiary);
482
+
483
+ const approveParam = !data.isApproved
484
+ ? BigNumber.from(1).shl(255)
485
+ : BigNumber.from(0);
486
+ const directionParam =
487
+ side === SwapSide.SELL ? BigNumber.from(0) : BigNumber.from(1).shl(254);
488
+
489
+ const beneficiaryDirectionApproveFlag = beneficiaryParam
490
+ .or(directionParam)
491
+ .or(approveParam);
492
+
493
+ const to18ConversionFactor = getBigIntPow(18 - data.gemDecimals);
494
+
495
+ const metadata = hexConcat([
496
+ hexZeroPad(uuidToBytes16(uuid), 16),
497
+ hexZeroPad(hexlify(blockNumber), 16),
498
+ ]);
499
+
500
+ const params: LitePsmParams = [
501
+ srcToken,
502
+ // not used on the contract, but used for analytics
503
+ destToken,
504
+ fromAmount,
505
+ toAmount,
506
+ data.toll,
507
+ to18ConversionFactor.toString(),
508
+ data.psmAddress,
509
+ data.gemJoinAddress,
510
+ metadata,
511
+ beneficiaryDirectionApproveFlag.toString(),
512
+ ];
513
+
514
+ const payload: LitePsmDirectPayload = [params, permit];
515
+
516
+ const encoder = (...params: (string | LitePsmDirectPayload)[]) => {
517
+ return this.augustusV6Interface.encodeFunctionData(
518
+ ContractMethodV6.swapExactAmountInOutOnMakerPSM,
519
+ [...params],
520
+ );
521
+ };
522
+
523
+ return { params: payload, encoder, networkFee: '0' };
524
+ }
525
+
526
+ // Returns list of top pools based on liquidity. Max
527
+ // limit number pools should be returned.
528
+ async getTopPoolsForToken(
529
+ tokenAddress: Address,
530
+ limit: number,
531
+ ): Promise<PoolLiquidity[]> {
532
+ const _tokenAddress = tokenAddress.toLowerCase();
533
+ // Liquidity depends on the swapping side hence we simply use the min
534
+ // Its always in terms of stable coin hence liquidityUSD = liquidity
535
+ const minLiq = (poolState: PoolState, decimals: number) => {
536
+ const buyLimit = poolState.gemBalance * getBigIntPow(18 - decimals);
537
+ const sellLimit = poolState.daiBalance;
538
+ return (
539
+ 2 *
540
+ parseInt(
541
+ (
542
+ (buyLimit > sellLimit ? sellLimit : buyLimit) / BI_POWS[18]
543
+ ).toString(),
544
+ )
545
+ );
546
+ };
547
+
548
+ const isDai = _tokenAddress === this.dai.address;
549
+
550
+ const validPoolConfigs = isDai
551
+ ? this.poolConfigs
552
+ : this.eventPools[_tokenAddress]
553
+ ? [this.eventPools[_tokenAddress].poolConfig]
554
+ : [];
555
+ if (!validPoolConfigs.length) return [];
556
+
557
+ // const poolStates = await getOnChainState(
558
+ // this.dexHelper.multiContract,
559
+ // validPoolConfigs,
560
+ // this.vatAddress,
561
+ // 'latest',
562
+ // );
563
+ const poolStates = await Promise.all(
564
+ Object.values(this.eventPools).map(e =>
565
+ this.getPoolState(
566
+ e,
567
+ this.dexHelper.blockManager.getLatestBlockNumber(),
568
+ ),
569
+ ),
570
+ );
571
+ return validPoolConfigs.map((p, i) => ({
572
+ exchange: this.dexKey,
573
+ address: p.psmAddress,
574
+ liquidityUSD: minLiq(poolStates[i], p.gem.decimals),
575
+ connectorTokens: [isDai ? p.gem : this.dai],
576
+ }));
577
+ }
578
+ }
@@ -0,0 +1,46 @@
1
+ import { Address, NumberAsString, Token } from '../../types';
2
+
3
+ export type PoolState = {
4
+ tin: bigint; // toll in
5
+ tout: bigint; // toll out
6
+ rate: bigint;
7
+ daiBalance: bigint; // `sellGem` ceiling
8
+ gemBalance: bigint; // `buyGem` ceiling
9
+ };
10
+
11
+ export type LitePsmData = {
12
+ psmAddress: Address;
13
+ gemJoinAddress: Address;
14
+ gemDecimals: number;
15
+ toll: string;
16
+ isApproved?: boolean;
17
+ };
18
+
19
+ export type PoolConfig = {
20
+ gem: Token;
21
+ gemJoinAddress: Address; // dai liquidity
22
+ pocketAddress: Address; // gem liquidity
23
+ psmAddress: Address;
24
+ identifier: string; // bytes32 of pool identifier (Eg. bytes32("PSM-USDC-A"))
25
+ };
26
+
27
+ export type DexParams = {
28
+ dai: Token;
29
+ vatAddress: Address;
30
+ pools: PoolConfig[];
31
+ };
32
+
33
+ export type LitePsmParams = [
34
+ srcToken: Address,
35
+ destToken: Address,
36
+ fromAmount: NumberAsString,
37
+ toAmount: NumberAsString,
38
+ toll: NumberAsString,
39
+ to18ConversionFactor: NumberAsString,
40
+ exchange: Address,
41
+ gemJoinAddress: Address,
42
+ metadata: string,
43
+ beneficiaryDirectionApproveFlag: NumberAsString,
44
+ ];
45
+
46
+ export type LitePsmDirectPayload = [params: LitePsmParams, permit: string];
@@ -653,8 +653,9 @@ export class MakerPsm
653
653
  // not used on the contract, but used for analytics
654
654
  destToken,
655
655
  fromAmount,
656
- // as there's no slippage, use instead of toAmount
657
- quotedAmount,
656
+ // // as there's no slippage, use instead of toAmount
657
+ // quotedAmount,
658
+ toAmount,
658
659
  data.toll,
659
660
  to18ConversionFactor.toString(),
660
661
  data.psmAddress,