@paraswap/dex-lib 3.8.30 → 3.8.32-aave-gsm

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 (237) hide show
  1. package/build/abi/AaveV1_lending_pool.json +27 -0
  2. package/build/abi/Aave_GSM.json +751 -0
  3. package/build/abi/aave-gsm/Aave_GSM.json +751 -0
  4. package/build/abi/aave-gsm/IFeeStrategy.json +78 -0
  5. package/build/abi/inception/inception-ineth-pool.json +1062 -0
  6. package/build/abi/inception/inception-ineth.json +609 -0
  7. package/build/abi/inception/inception-ratio-feed.json +329 -0
  8. package/build/abi/inception/inception-vault.json +991 -0
  9. package/build/abi/platypus/asset.json +490 -0
  10. package/build/abi/platypus/avax-pool.json +820 -0
  11. package/build/abi/platypus/oracle.json +119 -0
  12. package/build/abi/platypus/pool.json +677 -0
  13. package/build/abi/smardex/all/smardex-router.json +648 -0
  14. package/build/abi/smardex/layer-1/smardex-factory.json +242 -0
  15. package/build/abi/smardex/layer-1/smardex-pool.json +506 -0
  16. package/build/abi/smardex/layer-2/smardex-factory.json +185 -0
  17. package/build/abi/smardex/layer-2/smardex-pool.json +578 -0
  18. package/build/abi/stkGHO.json +1131 -0
  19. package/build/abi/swaap-v1/pool.json +1346 -0
  20. package/build/abi/usual-bond/usd0pp.abi.json +867 -0
  21. package/build/dex/aave-gsm/aave-gsm-pool.d.ts +31 -0
  22. package/build/dex/aave-gsm/aave-gsm-pool.js +147 -0
  23. package/build/dex/aave-gsm/aave-gsm-pool.js.map +1 -0
  24. package/build/dex/aave-gsm/aave-gsm.d.ts +45 -0
  25. package/build/dex/aave-gsm/aave-gsm.js +326 -0
  26. package/build/dex/aave-gsm/aave-gsm.js.map +1 -0
  27. package/build/dex/aave-gsm/config.d.ts +3 -0
  28. package/build/dex/aave-gsm/config.js +17 -0
  29. package/build/dex/aave-gsm/config.js.map +1 -0
  30. package/build/dex/aave-gsm/types.d.ts +19 -0
  31. package/build/dex/aave-gsm/types.js +3 -0
  32. package/build/dex/aave-gsm/types.js.map +1 -0
  33. package/build/dex/aave-v1/aave-v1.d.ts +34 -0
  34. package/build/dex/aave-v1/aave-v1.js +180 -0
  35. package/build/dex/aave-v1/aave-v1.js.map +1 -0
  36. package/build/dex/aave-v1/config.d.ts +11 -0
  37. package/build/dex/aave-v1/config.js +20 -0
  38. package/build/dex/aave-v1/config.js.map +1 -0
  39. package/build/dex/aave-v1/tokens-mainnet.json +134 -0
  40. package/build/dex/aave-v1/tokens.d.ts +3 -0
  41. package/build/dex/aave-v1/tokens.js +50 -0
  42. package/build/dex/aave-v1/tokens.js.map +1 -0
  43. package/build/dex/aave-v1/types.d.ts +12 -0
  44. package/build/dex/aave-v1/types.js +3 -0
  45. package/build/dex/aave-v1/types.js.map +1 -0
  46. package/build/dex/idle-dao/idle-dao-pool.d.ts +56 -0
  47. package/build/dex/idle-dao/idle-dao-pool.js +176 -0
  48. package/build/dex/idle-dao/idle-dao-pool.js.map +1 -0
  49. package/build/dex/idle-dao/idle-dao-pooling-pool.d.ts +16 -0
  50. package/build/dex/idle-dao/idle-dao-pooling-pool.js +57 -0
  51. package/build/dex/idle-dao/idle-dao-pooling-pool.js.map +1 -0
  52. package/build/dex/idle-dao/scripts.d.ts +9 -0
  53. package/build/dex/idle-dao/scripts.js +552 -0
  54. package/build/dex/idle-dao/scripts.js.map +1 -0
  55. package/build/dex/inception/config.d.ts +4 -0
  56. package/build/dex/inception/config.js +109 -0
  57. package/build/dex/inception/config.js.map +1 -0
  58. package/build/dex/inception/inception-event-pool.d.ts +16 -0
  59. package/build/dex/inception/inception-event-pool.js +51 -0
  60. package/build/dex/inception/inception-event-pool.js.map +1 -0
  61. package/build/dex/inception/inception-native.d.ts +43 -0
  62. package/build/dex/inception/inception-native.js +131 -0
  63. package/build/dex/inception/inception-native.js.map +1 -0
  64. package/build/dex/inception/inception-pool.d.ts +18 -0
  65. package/build/dex/inception/inception-pool.js +32 -0
  66. package/build/dex/inception/inception-pool.js.map +1 -0
  67. package/build/dex/inception/inception-price-feed.d.ts +19 -0
  68. package/build/dex/inception/inception-price-feed.js +51 -0
  69. package/build/dex/inception/inception-price-feed.js.map +1 -0
  70. package/build/dex/inception/inception.d.ts +43 -0
  71. package/build/dex/inception/inception.js +196 -0
  72. package/build/dex/inception/inception.js.map +1 -0
  73. package/build/dex/inception/tokens.d.ts +9 -0
  74. package/build/dex/inception/tokens.js +28 -0
  75. package/build/dex/inception/tokens.js.map +1 -0
  76. package/build/dex/inception/types.d.ts +22 -0
  77. package/build/dex/inception/types.js +3 -0
  78. package/build/dex/inception/types.js.map +1 -0
  79. package/build/dex/inception/utils.d.ts +7 -0
  80. package/build/dex/inception/utils.js +58 -0
  81. package/build/dex/inception/utils.js.map +1 -0
  82. package/build/dex/index.js +4 -0
  83. package/build/dex/index.js.map +1 -1
  84. package/build/dex/platypus/asset.d.ts +14 -0
  85. package/build/dex/platypus/asset.js +97 -0
  86. package/build/dex/platypus/asset.js.map +1 -0
  87. package/build/dex/platypus/config.d.ts +11 -0
  88. package/build/dex/platypus/config.js +69 -0
  89. package/build/dex/platypus/config.js.map +1 -0
  90. package/build/dex/platypus/platypus.d.ts +63 -0
  91. package/build/dex/platypus/platypus.js +473 -0
  92. package/build/dex/platypus/platypus.js.map +1 -0
  93. package/build/dex/platypus/pool-avax.d.ts +8 -0
  94. package/build/dex/platypus/pool-avax.js +54 -0
  95. package/build/dex/platypus/pool-avax.js.map +1 -0
  96. package/build/dex/platypus/pool-base.d.ts +19 -0
  97. package/build/dex/platypus/pool-base.js +86 -0
  98. package/build/dex/platypus/pool-base.js.map +1 -0
  99. package/build/dex/platypus/pool-pure.d.ts +8 -0
  100. package/build/dex/platypus/pool-pure.js +37 -0
  101. package/build/dex/platypus/pool-pure.js.map +1 -0
  102. package/build/dex/platypus/pool-subscriber.d.ts +14 -0
  103. package/build/dex/platypus/pool-subscriber.js +167 -0
  104. package/build/dex/platypus/pool-subscriber.js.map +1 -0
  105. package/build/dex/platypus/pool.d.ts +8 -0
  106. package/build/dex/platypus/pool.js +58 -0
  107. package/build/dex/platypus/pool.js.map +1 -0
  108. package/build/dex/platypus/types.d.ts +92 -0
  109. package/build/dex/platypus/types.js +10 -0
  110. package/build/dex/platypus/types.js.map +1 -0
  111. package/build/dex/quickswap/spiritswap-v3.d.ts +6 -0
  112. package/build/dex/quickswap/spiritswap-v3.js +19 -0
  113. package/build/dex/quickswap/spiritswap-v3.js.map +1 -0
  114. package/build/dex/smardex/config.d.ts +4 -0
  115. package/build/dex/smardex/config.js +64 -0
  116. package/build/dex/smardex/config.js.map +1 -0
  117. package/build/dex/smardex/constants.d.ts +18 -0
  118. package/build/dex/smardex/constants.js +33 -0
  119. package/build/dex/smardex/constants.js.map +1 -0
  120. package/build/dex/smardex/sdk/constants.d.ts +6 -0
  121. package/build/dex/smardex/sdk/constants.js +13 -0
  122. package/build/dex/smardex/sdk/constants.js.map +1 -0
  123. package/build/dex/smardex/sdk/core.d.ts +113 -0
  124. package/build/dex/smardex/sdk/core.js +499 -0
  125. package/build/dex/smardex/sdk/core.js.map +1 -0
  126. package/build/dex/smardex/sdk/errors.d.ts +15 -0
  127. package/build/dex/smardex/sdk/errors.js +22 -0
  128. package/build/dex/smardex/sdk/errors.js.map +1 -0
  129. package/build/dex/smardex/sdk/types.d.ts +62 -0
  130. package/build/dex/smardex/sdk/types.js +3 -0
  131. package/build/dex/smardex/sdk/types.js.map +1 -0
  132. package/build/dex/smardex/sdk/utils.d.ts +44 -0
  133. package/build/dex/smardex/sdk/utils.js +133 -0
  134. package/build/dex/smardex/sdk/utils.js.map +1 -0
  135. package/build/dex/smardex/smardex-event-pool.d.ts +28 -0
  136. package/build/dex/smardex/smardex-event-pool.js +119 -0
  137. package/build/dex/smardex/smardex-event-pool.js.map +1 -0
  138. package/build/dex/smardex/smardex.d.ts +65 -0
  139. package/build/dex/smardex/smardex.js +519 -0
  140. package/build/dex/smardex/smardex.js.map +1 -0
  141. package/build/dex/smardex/types.d.ts +55 -0
  142. package/build/dex/smardex/types.js +3 -0
  143. package/build/dex/smardex/types.js.map +1 -0
  144. package/build/dex/solidly/forks-override/cone.d.ts +22 -0
  145. package/build/dex/solidly/forks-override/cone.js +53 -0
  146. package/build/dex/solidly/forks-override/cone.js.map +1 -0
  147. package/build/dex/solidly/forks-override/solisnek.d.ts +8 -0
  148. package/build/dex/solidly/forks-override/solisnek.js +15 -0
  149. package/build/dex/solidly/forks-override/solisnek.js.map +1 -0
  150. package/build/dex/stkgho/config.d.ts +3 -0
  151. package/build/dex/stkgho/config.js +14 -0
  152. package/build/dex/stkgho/config.js.map +1 -0
  153. package/build/dex/stkgho/stkgho-pool.d.ts +41 -0
  154. package/build/dex/stkgho/stkgho-pool.js +81 -0
  155. package/build/dex/stkgho/stkgho-pool.js.map +1 -0
  156. package/build/dex/stkgho/stkgho.d.ts +41 -0
  157. package/build/dex/stkgho/stkgho.js +163 -0
  158. package/build/dex/stkgho/stkgho.js.map +1 -0
  159. package/build/dex/stkgho/types.d.ts +11 -0
  160. package/build/dex/stkgho/types.js +3 -0
  161. package/build/dex/stkgho/types.js.map +1 -0
  162. package/build/dex/swaap-v1/config.d.ts +17 -0
  163. package/build/dex/swaap-v1/config.js +56 -0
  164. package/build/dex/swaap-v1/config.js.map +1 -0
  165. package/build/dex/swaap-v1/constants.d.ts +6 -0
  166. package/build/dex/swaap-v1/constants.js +17 -0
  167. package/build/dex/swaap-v1/constants.js.map +1 -0
  168. package/build/dex/swaap-v1/libraries/ChainlinkUtils.d.ts +25 -0
  169. package/build/dex/swaap-v1/libraries/ChainlinkUtils.js +62 -0
  170. package/build/dex/swaap-v1/libraries/ChainlinkUtils.js.map +1 -0
  171. package/build/dex/swaap-v1/libraries/Const.d.ts +18 -0
  172. package/build/dex/swaap-v1/libraries/Const.js +26 -0
  173. package/build/dex/swaap-v1/libraries/Const.js.map +1 -0
  174. package/build/dex/swaap-v1/libraries/GeometricBrownianMotion.d.ts +77 -0
  175. package/build/dex/swaap-v1/libraries/GeometricBrownianMotion.js +316 -0
  176. package/build/dex/swaap-v1/libraries/GeometricBrownianMotion.js.map +1 -0
  177. package/build/dex/swaap-v1/libraries/LogExpMath.d.ts +75 -0
  178. package/build/dex/swaap-v1/libraries/LogExpMath.js +418 -0
  179. package/build/dex/swaap-v1/libraries/LogExpMath.js.map +1 -0
  180. package/build/dex/swaap-v1/libraries/MathMMM.d.ts +185 -0
  181. package/build/dex/swaap-v1/libraries/MathMMM.js +453 -0
  182. package/build/dex/swaap-v1/libraries/MathMMM.js.map +1 -0
  183. package/build/dex/swaap-v1/libraries/Num.d.ts +31 -0
  184. package/build/dex/swaap-v1/libraries/Num.js +167 -0
  185. package/build/dex/swaap-v1/libraries/Num.js.map +1 -0
  186. package/build/dex/swaap-v1/libraries/PoolQuotations.d.ts +23 -0
  187. package/build/dex/swaap-v1/libraries/PoolQuotations.js +131 -0
  188. package/build/dex/swaap-v1/libraries/PoolQuotations.js.map +1 -0
  189. package/build/dex/swaap-v1/libraries/Struct.d.ts +56 -0
  190. package/build/dex/swaap-v1/libraries/Struct.js +3 -0
  191. package/build/dex/swaap-v1/libraries/Struct.js.map +1 -0
  192. package/build/dex/swaap-v1/swaap-v1-pool.d.ts +45 -0
  193. package/build/dex/swaap-v1/swaap-v1-pool.js +656 -0
  194. package/build/dex/swaap-v1/swaap-v1-pool.js.map +1 -0
  195. package/build/dex/swaap-v1/swaap-v1.d.ts +62 -0
  196. package/build/dex/swaap-v1/swaap-v1.js +379 -0
  197. package/build/dex/swaap-v1/swaap-v1.js.map +1 -0
  198. package/build/dex/swaap-v1/types.d.ts +106 -0
  199. package/build/dex/swaap-v1/types.js +9 -0
  200. package/build/dex/swaap-v1/types.js.map +1 -0
  201. package/build/dex/usual-bond/config.d.ts +3 -0
  202. package/build/dex/usual-bond/config.js +13 -0
  203. package/build/dex/usual-bond/config.js.map +1 -0
  204. package/build/dex/usual-bond/types.d.ts +7 -0
  205. package/build/dex/usual-bond/types.js +3 -0
  206. package/build/dex/usual-bond/types.js.map +1 -0
  207. package/build/dex/usual-bond/usual-bond.d.ts +35 -0
  208. package/build/dex/usual-bond/usual-bond.js +162 -0
  209. package/build/dex/usual-bond/usual-bond.js.map +1 -0
  210. package/build/dex/zerox/index.d.ts +1 -1
  211. package/build/dex/zerox/index.js.map +1 -1
  212. package/package.json +2 -3
  213. package/src/abi/aave-gsm/Aave_GSM.json +751 -0
  214. package/src/abi/aave-gsm/IFeeStrategy.json +78 -0
  215. package/src/abi/stkGHO.json +1131 -0
  216. package/src/dex/aave-gsm/aave-gsm-e2e.test.ts +110 -0
  217. package/src/dex/aave-gsm/aave-gsm-events.test.ts +82 -0
  218. package/src/dex/aave-gsm/aave-gsm-integration.test.ts +522 -0
  219. package/src/dex/aave-gsm/aave-gsm-pool.ts +225 -0
  220. package/src/dex/aave-gsm/aave-gsm.ts +436 -0
  221. package/src/dex/aave-gsm/config.ts +16 -0
  222. package/src/dex/aave-gsm/types.ts +24 -0
  223. package/src/dex/index.ts +4 -0
  224. package/src/dex/stkgho/config.ts +14 -0
  225. package/src/dex/stkgho/stkgho-e2e.test.ts +77 -0
  226. package/src/dex/stkgho/stkgho-events.test.ts +79 -0
  227. package/src/dex/stkgho/stkgho-integration.test.ts +226 -0
  228. package/src/dex/stkgho/stkgho-pool.ts +111 -0
  229. package/src/dex/stkgho/stkgho.ts +221 -0
  230. package/src/dex/stkgho/types.ts +14 -0
  231. package/tests/constants-e2e.ts +4 -0
  232. package/.idea/codeStyles/Project.xml +0 -59
  233. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  234. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  235. package/.idea/modules.xml +0 -8
  236. package/.idea/paraswap-dex-lib.iml +0 -12
  237. package/.idea/vcs.xml +0 -6
@@ -0,0 +1,225 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import { DeepReadonly } from 'ts-essentials';
3
+ import { Log, Logger } from '../../types';
4
+ import { catchParseLogError } from '../../utils';
5
+ import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
6
+ import { IDexHelper } from '../../dex-helper/idex-helper';
7
+ import { PoolState } from './types';
8
+ import GSM_ABI from '../../abi/aave-gsm/Aave_GSM.json';
9
+ import FEE_STRATEGY_ABI from '../../abi/aave-gsm/IFeeStrategy.json';
10
+ import {
11
+ addressDecode,
12
+ booleanDecode,
13
+ uint256ToBigInt,
14
+ } from '../../lib/decoders';
15
+
16
+ export class AaveGsmEventPool extends StatefulEventSubscriber<PoolState> {
17
+ handlers: {
18
+ [event: string]: (
19
+ event: any,
20
+ state: DeepReadonly<PoolState>,
21
+ log: Readonly<Log>,
22
+ ) => Promise<DeepReadonly<PoolState> | null>;
23
+ } = {};
24
+
25
+ logDecoder: (log: Log) => any;
26
+
27
+ addressesSubscribed: string[];
28
+
29
+ constructor(
30
+ readonly gsm: string,
31
+ readonly parentName: string,
32
+ protected network: number,
33
+ protected dexHelper: IDexHelper,
34
+ logger: Logger,
35
+ protected aaveGsmIface = new Interface(GSM_ABI),
36
+ protected feeStrategyIface = new Interface(FEE_STRATEGY_ABI),
37
+ protected PERCENT_FACTOR = 10_000n,
38
+ ) {
39
+ super(parentName, `${parentName}_${gsm}`, dexHelper, logger);
40
+
41
+ this.logDecoder = (log: Log) => this.aaveGsmIface.parseLog(log);
42
+ this.addressesSubscribed = [gsm];
43
+
44
+ // Add handlers
45
+ this.handlers['FeeStrategyUpdated'] =
46
+ this.handleFeeStrategyUpdated.bind(this);
47
+
48
+ this.handlers['SwapFreeze'] = this.handleSwapFreeze.bind(this);
49
+ this.handlers['Seized'] = this.handleSeized.bind(this);
50
+ this.handlers['ExposureCapUpdated'] =
51
+ this.handleExposureCapUpdated.bind(this);
52
+ this.handlers['BuyAsset'] = this.handleBuyAsset.bind(this);
53
+ this.handlers['SellAsset'] = this.handleSellAsset.bind(this);
54
+ }
55
+
56
+ getIdentifier(): string {
57
+ return `${this.parentName}_${this.gsm}`;
58
+ }
59
+
60
+ protected async processLog(
61
+ state: DeepReadonly<PoolState>,
62
+ log: Readonly<Log>,
63
+ ): Promise<DeepReadonly<PoolState> | null> {
64
+ try {
65
+ const event = this.logDecoder(log);
66
+ if (event.name in this.handlers) {
67
+ return await this.handlers[event.name](event, state, log);
68
+ }
69
+ } catch (e) {
70
+ catchParseLogError(e, this.logger);
71
+ }
72
+
73
+ return null;
74
+ }
75
+
76
+ async getOnChainState(
77
+ address: string,
78
+ blockNumber: number | string = 'latest',
79
+ ): Promise<PoolState> {
80
+ const callData = [
81
+ {
82
+ target: address,
83
+ callData: this.feeStrategyIface.encodeFunctionData('getBuyFee', [
84
+ this.PERCENT_FACTOR,
85
+ ]),
86
+ decodeFunction: uint256ToBigInt,
87
+ },
88
+ {
89
+ target: address,
90
+ callData: this.feeStrategyIface.encodeFunctionData('getSellFee', [
91
+ this.PERCENT_FACTOR,
92
+ ]),
93
+ decodeFunction: uint256ToBigInt,
94
+ },
95
+ {
96
+ target: this.gsm,
97
+ callData: this.aaveGsmIface.encodeFunctionData(
98
+ 'getAvailableLiquidity',
99
+ [],
100
+ ),
101
+ decodeFunction: uint256ToBigInt,
102
+ },
103
+ {
104
+ target: this.gsm,
105
+ callData: this.aaveGsmIface.encodeFunctionData('getIsFrozen', []),
106
+ decodeFunction: booleanDecode,
107
+ },
108
+ {
109
+ target: this.gsm,
110
+ callData: this.aaveGsmIface.encodeFunctionData('getIsSeized', []),
111
+ decodeFunction: booleanDecode,
112
+ },
113
+ {
114
+ target: this.gsm,
115
+ callData: this.aaveGsmIface.encodeFunctionData('getExposureCap', []),
116
+ decodeFunction: uint256ToBigInt,
117
+ },
118
+ ];
119
+
120
+ const results = await this.dexHelper.multiWrapper.tryAggregate<
121
+ bigint | boolean
122
+ >(true, callData, blockNumber);
123
+
124
+ return {
125
+ buyFee: results[0].returnData as bigint,
126
+ sellFee: results[1].returnData as bigint,
127
+ underlyingLiquidity: results[2].returnData as bigint,
128
+ isFrozen: results[3].returnData as boolean,
129
+ isSeized: results[4].returnData as boolean,
130
+ exposureCap: results[5].returnData as bigint,
131
+ };
132
+ }
133
+
134
+ async generateState(
135
+ blockNumber: number | string = 'latest',
136
+ ): Promise<DeepReadonly<PoolState>> {
137
+ const callData = [
138
+ {
139
+ target: this.gsm,
140
+ callData: this.aaveGsmIface.encodeFunctionData('getFeeStrategy', []),
141
+ decodeFunction: addressDecode,
142
+ },
143
+ ];
144
+
145
+ const feeStrategy = await this.dexHelper.multiWrapper.tryAggregate<string>(
146
+ true,
147
+ callData,
148
+ blockNumber,
149
+ );
150
+
151
+ const result = await this.getOnChainState(
152
+ feeStrategy[0].returnData,
153
+ blockNumber,
154
+ );
155
+
156
+ return result;
157
+ }
158
+
159
+ async handleFeeStrategyUpdated(
160
+ event: any,
161
+ state: DeepReadonly<PoolState>,
162
+ log: Readonly<Log>,
163
+ ): Promise<DeepReadonly<PoolState> | null> {
164
+ return await this.getOnChainState(event.args.newFeeStrategy);
165
+ }
166
+
167
+ async handleSwapFreeze(
168
+ event: any,
169
+ state: DeepReadonly<PoolState>,
170
+ log: Readonly<Log>,
171
+ ): Promise<DeepReadonly<PoolState> | null> {
172
+ return {
173
+ ...state,
174
+ isFrozen: event.args.enabled,
175
+ };
176
+ }
177
+
178
+ async handleSeized(
179
+ event: any,
180
+ state: DeepReadonly<PoolState>,
181
+ log: Readonly<Log>,
182
+ ): Promise<DeepReadonly<PoolState> | null> {
183
+ return {
184
+ ...state,
185
+ isSeized: true,
186
+ exposureCap: BigInt(0),
187
+ underlyingLiquidity: BigInt(0),
188
+ };
189
+ }
190
+
191
+ async handleExposureCapUpdated(
192
+ event: any,
193
+ state: DeepReadonly<PoolState>,
194
+ log: Readonly<Log>,
195
+ ): Promise<DeepReadonly<PoolState> | null> {
196
+ return {
197
+ ...state,
198
+ exposureCap: BigInt(event.args.newExposureCap),
199
+ };
200
+ }
201
+
202
+ async handleBuyAsset(
203
+ event: any,
204
+ state: DeepReadonly<PoolState>,
205
+ log: Readonly<Log>,
206
+ ): Promise<DeepReadonly<PoolState> | null> {
207
+ return {
208
+ ...state,
209
+ underlyingLiquidity:
210
+ state.underlyingLiquidity - BigInt(event.args.underlyingAmount),
211
+ };
212
+ }
213
+
214
+ async handleSellAsset(
215
+ event: any,
216
+ state: DeepReadonly<PoolState>,
217
+ log: Readonly<Log>,
218
+ ): Promise<DeepReadonly<PoolState> | null> {
219
+ return {
220
+ ...state,
221
+ underlyingLiquidity:
222
+ state.underlyingLiquidity + BigInt(event.args.underlyingAmount),
223
+ };
224
+ }
225
+ }
@@ -0,0 +1,436 @@
1
+ import {
2
+ Token,
3
+ Address,
4
+ ExchangePrices,
5
+ PoolPrices,
6
+ AdapterExchangeParam,
7
+ PoolLiquidity,
8
+ Logger,
9
+ NumberAsString,
10
+ DexExchangeParam,
11
+ } from '../../types';
12
+ import { SwapSide, Network } from '../../constants';
13
+ import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
14
+ import { getDexKeysWithNetwork } from '../../utils';
15
+ import { IDex } from '../../dex/idex';
16
+ import { IDexHelper } from '../../dex-helper/idex-helper';
17
+ import { AaveGsmData, DexParams, PoolState } from './types';
18
+ import { SimpleExchange } from '../simple-exchange';
19
+ import { AaveGsmConfig } from './config';
20
+
21
+ import GSM_ABI from '../../abi/aave-gsm/Aave_GSM.json';
22
+ import { Interface } from '@ethersproject/abi';
23
+ import { formatUnits, parseUnits } from 'ethers/lib/utils';
24
+ import { AaveGsmEventPool } from './aave-gsm-pool';
25
+ import { MMath } from '../maverick-v1/maverick-math/maverick-basic-math';
26
+ import {
27
+ RETURN_AMOUNT_POS_0,
28
+ RETURN_AMOUNT_POS_32,
29
+ } from '../../executor/constants';
30
+
31
+ export class AaveGsm extends SimpleExchange implements IDex<AaveGsmData> {
32
+ static readonly gsmInterface = new Interface(GSM_ABI);
33
+ protected eventPools: Record<string, AaveGsmEventPool>;
34
+
35
+ protected config: DexParams;
36
+
37
+ readonly hasConstantPriceLargeAmounts = false;
38
+ readonly needWrapNative = false;
39
+
40
+ readonly isFeeOnTransferSupported = false;
41
+
42
+ public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
43
+ getDexKeysWithNetwork(AaveGsmConfig);
44
+
45
+ logger: Logger;
46
+
47
+ constructor(
48
+ readonly network: Network,
49
+ readonly dexKey: string,
50
+ readonly dexHelper: IDexHelper,
51
+ ) {
52
+ super(dexHelper, dexKey);
53
+ const config = AaveGsmConfig[dexKey][network];
54
+ this.config = {
55
+ GSM_USDT: config.GSM_USDT.toLowerCase(),
56
+ GSM_USDC: config.GSM_USDC.toLowerCase(),
57
+ USDT: config.USDT.toLowerCase(),
58
+ USDC: config.USDC.toLowerCase(),
59
+ GHO: config.GHO.toLowerCase(),
60
+ };
61
+
62
+ this.logger = dexHelper.getLogger(dexKey);
63
+
64
+ this.eventPools = {
65
+ [this.config.GSM_USDT]: new AaveGsmEventPool(
66
+ this.config.GSM_USDT,
67
+ this.dexKey,
68
+ this.network,
69
+ this.dexHelper,
70
+ this.logger,
71
+ ),
72
+ [this.config.GSM_USDC]: new AaveGsmEventPool(
73
+ this.config.GSM_USDC,
74
+ this.dexKey,
75
+ this.network,
76
+ this.dexHelper,
77
+ this.logger,
78
+ ),
79
+ };
80
+ }
81
+
82
+ async initializePoolPricing(pool: AaveGsmEventPool, blockNumber: number) {
83
+ const state = await pool.generateState(blockNumber);
84
+
85
+ pool.initialize(blockNumber, {
86
+ state,
87
+ });
88
+ }
89
+
90
+ async initializePricing(blockNumber: number) {
91
+ await this.initializePoolPricing(
92
+ this.eventPools[this.config.GSM_USDT],
93
+ blockNumber,
94
+ );
95
+ await this.initializePoolPricing(
96
+ this.eventPools[this.config.GSM_USDC],
97
+ blockNumber,
98
+ );
99
+ }
100
+
101
+ getAdapters(side: SwapSide): { name: string; index: number }[] | null {
102
+ return null;
103
+ }
104
+
105
+ async getPoolIdentifiers(
106
+ srcToken: Token,
107
+ destToken: Token,
108
+ side: SwapSide,
109
+ blockNumber: number,
110
+ ): Promise<string[]> {
111
+ const srcTokenAddress = srcToken.address.toLowerCase();
112
+ const destTokenAddress = destToken.address.toLowerCase();
113
+
114
+ if (
115
+ (srcTokenAddress === this.config.GHO &&
116
+ destTokenAddress === this.config.USDT) ||
117
+ (srcTokenAddress === this.config.USDT &&
118
+ destTokenAddress === this.config.GHO)
119
+ ) {
120
+ return [`${this.dexKey}_${this.config.GSM_USDT}`];
121
+ } else if (
122
+ (srcTokenAddress === this.config.GHO &&
123
+ destTokenAddress === this.config.USDC) ||
124
+ (srcTokenAddress === this.config.USDC &&
125
+ destTokenAddress === this.config.GHO)
126
+ ) {
127
+ return [`${this.dexKey}_${this.config.GSM_USDC}`];
128
+ } else {
129
+ return [];
130
+ }
131
+ }
132
+
133
+ async updatePoolState(): Promise<void> {
134
+ const blockNumber = await this.dexHelper.web3Provider.eth.getBlockNumber();
135
+ await this.initializePricing(blockNumber);
136
+ }
137
+
138
+ async getPoolState(gsm: string, blockNumber?: number): Promise<PoolState> {
139
+ if (!blockNumber) {
140
+ return this.eventPools[gsm].getStaleState()!;
141
+ }
142
+ const eventState = this.eventPools[gsm].getState(blockNumber);
143
+ if (eventState) return eventState;
144
+ const onChainState = await this.eventPools[gsm].generateState(blockNumber);
145
+ this.eventPools[gsm].setState(onChainState, blockNumber);
146
+ return onChainState;
147
+ }
148
+
149
+ canBuyAsset(assetAmount: bigint, state: PoolState) {
150
+ return assetAmount > 0n && state.underlyingLiquidity >= assetAmount;
151
+ }
152
+
153
+ canSellAsset(assetAmount: bigint, state: PoolState) {
154
+ return (
155
+ assetAmount > 0n &&
156
+ state.underlyingLiquidity + assetAmount <= state.exposureCap
157
+ );
158
+ }
159
+
160
+ getGhoAmountForBuyAsset(assetAmount: bigint, state: PoolState) {
161
+ if (!this.canBuyAsset(assetAmount, state)) {
162
+ return 0n;
163
+ }
164
+
165
+ const grossAmount = assetAmount * 1_000_000_000_000n; // 18 - 6 = 12 (decimals)
166
+ const fee = MMath.mulDiv(grossAmount, state.buyFee, 10_000n, true);
167
+
168
+ const result = grossAmount + fee;
169
+
170
+ return result;
171
+ }
172
+
173
+ getAssetAmountForBuyAsset(ghoAmount: bigint, state: PoolState) {
174
+ const grossAmount = (ghoAmount * 10_000n) / (10_000n + state.buyFee);
175
+
176
+ const result = grossAmount / 1_000_000_000_000n; // 18 - 6 = 12 (decimals)
177
+
178
+ if (this.canBuyAsset(result, state)) {
179
+ return result;
180
+ }
181
+ return 0n;
182
+ }
183
+
184
+ getGhoAmountForSellAsset(assetAmount: bigint, state: PoolState) {
185
+ if (!this.canSellAsset(assetAmount, state)) {
186
+ return 0n;
187
+ }
188
+
189
+ const grossAmount = assetAmount * 1_000_000_000_000n; // 18 - 6 = 12 (decimals)
190
+ const fee = MMath.mulDiv(grossAmount, state.sellFee, 10_000n, true);
191
+
192
+ return grossAmount - fee;
193
+ }
194
+
195
+ getAssetAmountForSellAsset(ghoAmount: bigint, state: PoolState) {
196
+ const grossAmount = MMath.mulDiv(
197
+ ghoAmount,
198
+ 10_000n,
199
+ 10_000n - state.sellFee,
200
+ true,
201
+ );
202
+
203
+ const result = MMath.mulDiv(grossAmount, 1n, 1_000_000_000_000n, true); // 18 - 6 = 12 (decimals)
204
+
205
+ if (this.canSellAsset(result, state)) {
206
+ return result;
207
+ }
208
+ return 0n;
209
+ }
210
+
211
+ async getPricesVolume(
212
+ srcToken: Token,
213
+ destToken: Token,
214
+ amounts: bigint[],
215
+ side: SwapSide,
216
+ blockNumber: number,
217
+ limitPools?: string[],
218
+ ): Promise<null | ExchangePrices<AaveGsmData>> {
219
+ const srcTokenAddress = srcToken.address.toLowerCase();
220
+ const destTokenAddress = destToken.address.toLowerCase();
221
+
222
+ if (
223
+ !(
224
+ (srcTokenAddress === this.config.GHO &&
225
+ (destTokenAddress === this.config.USDC ||
226
+ destTokenAddress === this.config.USDT)) ||
227
+ (destTokenAddress === this.config.GHO &&
228
+ (srcTokenAddress === this.config.USDC ||
229
+ srcTokenAddress === this.config.USDT))
230
+ )
231
+ ) {
232
+ return null;
233
+ }
234
+
235
+ let endpoint: Function;
236
+ let target: string;
237
+ let gas: number;
238
+
239
+ if (
240
+ srcTokenAddress === this.config.USDT ||
241
+ destTokenAddress === this.config.USDT
242
+ ) {
243
+ target = this.config.GSM_USDT;
244
+ } else {
245
+ target = this.config.GSM_USDC;
246
+ }
247
+
248
+ if (srcTokenAddress === this.config.GHO && side === SwapSide.BUY) {
249
+ // amount = destAmount = assetAmount
250
+ endpoint = this.getGhoAmountForBuyAsset.bind(this);
251
+ gas = 80_000;
252
+ } else if (srcTokenAddress === this.config.GHO && side === SwapSide.SELL) {
253
+ // amount = srcAmount = ghoAmount
254
+ endpoint = this.getAssetAmountForBuyAsset.bind(this);
255
+ gas = 80_000;
256
+ } else if (destTokenAddress === this.config.GHO && side === SwapSide.SELL) {
257
+ // amount = srcAmount = assetAmount
258
+ endpoint = this.getGhoAmountForSellAsset.bind(this);
259
+ gas = 70_000;
260
+ } else {
261
+ // amount = destAmount = ghoAmount
262
+ endpoint = this.getAssetAmountForSellAsset.bind(this);
263
+ gas = 70_000;
264
+ }
265
+
266
+ const unit = parseUnits(
267
+ '1',
268
+ side === SwapSide.SELL ? srcToken.decimals : destToken.decimals,
269
+ ).toBigInt();
270
+
271
+ const poolState = await this.getPoolState(target, blockNumber);
272
+
273
+ if (poolState.isFrozen || poolState.isSeized) {
274
+ return null;
275
+ }
276
+
277
+ return [
278
+ {
279
+ unit: endpoint(unit, poolState),
280
+ prices: amounts.map(amount => endpoint(amount, poolState)),
281
+ data: {
282
+ exchange: this.dexKey,
283
+ },
284
+ poolAddresses: [target],
285
+ exchange: this.dexKey,
286
+ gasCost: gas,
287
+ poolIdentifier: `${this.dexKey}_${target}`,
288
+ },
289
+ ];
290
+ }
291
+
292
+ getCalldataGasCost(poolPrices: PoolPrices<AaveGsmData>): number | number[] {
293
+ return CALLDATA_GAS_COST.DEX_NO_PAYLOAD;
294
+ }
295
+
296
+ getAdapterParam(
297
+ srcToken: string,
298
+ destToken: string,
299
+ srcAmount: string,
300
+ destAmount: string,
301
+ data: AaveGsmData,
302
+ side: SwapSide,
303
+ ): AdapterExchangeParam {
304
+ const { exchange } = data;
305
+
306
+ const payload = '';
307
+
308
+ return {
309
+ targetExchange: exchange,
310
+ payload,
311
+ networkFee: '0',
312
+ };
313
+ }
314
+
315
+ async getDexParam(
316
+ srcToken: Address,
317
+ destToken: Address,
318
+ srcAmount: NumberAsString,
319
+ destAmount: NumberAsString,
320
+ recipient: Address,
321
+ data: AaveGsmData,
322
+ side: SwapSide,
323
+ ): Promise<DexExchangeParam> {
324
+ const isSrcGho = srcToken.toLowerCase() === this.config.GHO;
325
+ const swapFunction = isSrcGho ? 'buyAsset' : 'sellAsset';
326
+ const ghoAmount = isSrcGho ? srcAmount : destAmount;
327
+ let assetAmount = isSrcGho ? destAmount : srcAmount;
328
+ const targetExchange =
329
+ srcToken.toLowerCase() === this.config.USDT ||
330
+ destToken.toLowerCase() === this.config.USDT
331
+ ? this.config.GSM_USDT
332
+ : this.config.GSM_USDC;
333
+
334
+ if (BigInt(assetAmount) === 1n) {
335
+ const poolState = await this.getPoolState(targetExchange);
336
+ assetAmount = isSrcGho
337
+ ? this.getAssetAmountForBuyAsset(
338
+ BigInt(ghoAmount),
339
+ poolState,
340
+ ).toString()
341
+ : this.getAssetAmountForSellAsset(
342
+ BigInt(ghoAmount),
343
+ poolState,
344
+ ).toString();
345
+ }
346
+
347
+ const exchangeData = AaveGsm.gsmInterface.encodeFunctionData(swapFunction, [
348
+ assetAmount,
349
+ recipient,
350
+ ]);
351
+
352
+ return {
353
+ needWrapNative: this.needWrapNative,
354
+ dexFuncHasRecipient: true,
355
+ exchangeData,
356
+ targetExchange,
357
+ returnAmountPos:
358
+ side === SwapSide.SELL
359
+ ? isSrcGho
360
+ ? RETURN_AMOUNT_POS_0
361
+ : RETURN_AMOUNT_POS_32
362
+ : undefined,
363
+ };
364
+ }
365
+
366
+ async getTopPoolsForToken(
367
+ tokenAddress: Address,
368
+ limit: number,
369
+ ): Promise<PoolLiquidity[]> {
370
+ tokenAddress = tokenAddress.toLowerCase();
371
+
372
+ if (tokenAddress === this.config.GHO) {
373
+ const usdtState = this.eventPools[this.config.GSM_USDT].getStaleState();
374
+ const usdcState = this.eventPools[this.config.GSM_USDC].getStaleState();
375
+
376
+ return [
377
+ {
378
+ exchange: this.dexKey,
379
+ address: this.config.GSM_USDT,
380
+ connectorTokens: [
381
+ {
382
+ decimals: 6,
383
+ address: this.config.USDT,
384
+ },
385
+ ],
386
+ liquidityUSD: usdtState
387
+ ? +formatUnits(usdtState.underlyingLiquidity, 6)
388
+ : 1000000000,
389
+ },
390
+ {
391
+ exchange: this.dexKey,
392
+ address: this.config.GSM_USDC,
393
+ connectorTokens: [
394
+ {
395
+ decimals: 6,
396
+ address: this.config.USDC,
397
+ },
398
+ ],
399
+ liquidityUSD: usdcState
400
+ ? +formatUnits(usdcState.underlyingLiquidity, 6)
401
+ : 1000000000,
402
+ },
403
+ ];
404
+ } else if (tokenAddress === this.config.USDC) {
405
+ return [
406
+ {
407
+ exchange: this.dexKey,
408
+ address: this.config.GSM_USDC,
409
+ connectorTokens: [
410
+ {
411
+ decimals: 18,
412
+ address: this.config.GHO,
413
+ },
414
+ ],
415
+ liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred
416
+ },
417
+ ];
418
+ } else if (tokenAddress === this.config.USDT) {
419
+ return [
420
+ {
421
+ exchange: this.dexKey,
422
+ address: this.config.GSM_USDT,
423
+ connectorTokens: [
424
+ {
425
+ decimals: 18,
426
+ address: this.config.GHO,
427
+ },
428
+ ],
429
+ liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred
430
+ },
431
+ ];
432
+ } else {
433
+ return [];
434
+ }
435
+ }
436
+ }
@@ -0,0 +1,16 @@
1
+ import { DexParams } from './types';
2
+ import { DexConfigMap } from '../../types';
3
+ import { Network } from '../../constants';
4
+ import { AaveV3Ethereum, MiscEthereum } from '@bgd-labs/aave-address-book';
5
+
6
+ export const AaveGsmConfig: DexConfigMap<DexParams> = {
7
+ AaveGsm: {
8
+ [Network.MAINNET]: {
9
+ GSM_USDT: MiscEthereum.GSM_USDT,
10
+ GSM_USDC: MiscEthereum.GSM_USDC,
11
+ USDT: AaveV3Ethereum.ASSETS.USDT.UNDERLYING,
12
+ USDC: AaveV3Ethereum.ASSETS.USDC.UNDERLYING,
13
+ GHO: AaveV3Ethereum.ASSETS.GHO.UNDERLYING,
14
+ },
15
+ },
16
+ };
@@ -0,0 +1,24 @@
1
+ import { Address } from '../../types';
2
+
3
+ export type PoolState = {
4
+ buyFee: bigint;
5
+ sellFee: bigint;
6
+ underlyingLiquidity: bigint;
7
+ isFrozen: boolean;
8
+ isSeized: boolean;
9
+ exposureCap: bigint;
10
+ };
11
+
12
+ export type AaveGsmData = {
13
+ // returned by the API that can be used for
14
+ // tx building. The data structure should be minimal.
15
+ exchange: Address;
16
+ };
17
+
18
+ export type DexParams = {
19
+ GSM_USDT: string;
20
+ GSM_USDC: string;
21
+ USDT: string;
22
+ USDC: string;
23
+ GHO: string;
24
+ };