@paraswap/dex-lib 3.7.2 → 3.7.3

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 (236) hide show
  1. package/build/abi/Redstone.json +739 -0
  2. package/build/abi/aavev3stata/Factory.json +128 -0
  3. package/build/abi/aavev3stata/Token.json +735 -0
  4. package/build/abi/angle-transmuter/MorphoOracle.json +193 -0
  5. package/build/abi/angle-transmuter/MorphoVault.json +2506 -0
  6. package/build/abi/angle-transmuter/Pyth.json +1534 -0
  7. package/build/abi/angle-transmuter/Transmuter.json +1711 -0
  8. package/build/abi/angle-transmuter/TransmuterSidechain.json +1798 -0
  9. package/build/abi/idle-dao/idle-cdo-factory.json +38 -0
  10. package/build/abi/idle-dao/idle-cdo.json +1245 -0
  11. package/build/dex/aave-v1/aave-v1.d.ts +2 -1
  12. package/build/dex/aave-v1/aave-v1.js +22 -0
  13. package/build/dex/aave-v1/aave-v1.js.map +1 -1
  14. package/build/dex/aave-v3-stata/aave-v3-stata.d.ts +50 -0
  15. package/build/dex/aave-v3-stata/aave-v3-stata.js +365 -0
  16. package/build/dex/aave-v3-stata/aave-v3-stata.js.map +1 -0
  17. package/build/dex/aave-v3-stata/config.d.ts +4 -0
  18. package/build/dex/aave-v3-stata/config.js +50 -0
  19. package/build/dex/aave-v3-stata/config.js.map +1 -0
  20. package/build/dex/aave-v3-stata/tokens.d.ts +9 -0
  21. package/build/dex/aave-v3-stata/tokens.js +37 -0
  22. package/build/dex/aave-v3-stata/tokens.js.map +1 -0
  23. package/build/dex/aave-v3-stata/types.d.ts +46 -0
  24. package/build/dex/aave-v3-stata/types.js +23 -0
  25. package/build/dex/aave-v3-stata/types.js.map +1 -0
  26. package/build/dex/aave-v3-stata/utils.d.ts +4 -0
  27. package/build/dex/aave-v3-stata/utils.js +67 -0
  28. package/build/dex/aave-v3-stata/utils.js.map +1 -0
  29. package/build/dex/angle-transmuter/angle-transmuter-pool.d.ts +67 -0
  30. package/build/dex/angle-transmuter/angle-transmuter-pool.js +448 -0
  31. package/build/dex/angle-transmuter/angle-transmuter-pool.js.map +1 -0
  32. package/build/dex/angle-transmuter/angle-transmuter.d.ts +59 -0
  33. package/build/dex/angle-transmuter/angle-transmuter.js +264 -0
  34. package/build/dex/angle-transmuter/angle-transmuter.js.map +1 -0
  35. package/build/dex/angle-transmuter/backedOracle.d.ts +19 -0
  36. package/build/dex/angle-transmuter/backedOracle.js +56 -0
  37. package/build/dex/angle-transmuter/backedOracle.js.map +1 -0
  38. package/build/dex/angle-transmuter/config.d.ts +4 -0
  39. package/build/dex/angle-transmuter/config.js +50 -0
  40. package/build/dex/angle-transmuter/config.js.map +1 -0
  41. package/build/dex/angle-transmuter/constants.d.ts +9 -0
  42. package/build/dex/angle-transmuter/constants.js +136 -0
  43. package/build/dex/angle-transmuter/constants.js.map +1 -0
  44. package/build/dex/angle-transmuter/morphoOracle.d.ts +42 -0
  45. package/build/dex/angle-transmuter/morphoOracle.js +179 -0
  46. package/build/dex/angle-transmuter/morphoOracle.js.map +1 -0
  47. package/build/dex/angle-transmuter/morphoVault.d.ts +20 -0
  48. package/build/dex/angle-transmuter/morphoVault.js +84 -0
  49. package/build/dex/angle-transmuter/morphoVault.js.map +1 -0
  50. package/build/dex/angle-transmuter/pyth.d.ts +19 -0
  51. package/build/dex/angle-transmuter/pyth.js +70 -0
  52. package/build/dex/angle-transmuter/pyth.js.map +1 -0
  53. package/build/dex/angle-transmuter/redstone.d.ts +20 -0
  54. package/build/dex/angle-transmuter/redstone.js +64 -0
  55. package/build/dex/angle-transmuter/redstone.js.map +1 -0
  56. package/build/dex/angle-transmuter/transmuter.d.ts +55 -0
  57. package/build/dex/angle-transmuter/transmuter.js +398 -0
  58. package/build/dex/angle-transmuter/transmuter.js.map +1 -0
  59. package/build/dex/angle-transmuter/types.d.ts +189 -0
  60. package/build/dex/angle-transmuter/types.js +33 -0
  61. package/build/dex/angle-transmuter/types.js.map +1 -0
  62. package/build/dex/angle-transmuter/utils.d.ts +9 -0
  63. package/build/dex/angle-transmuter/utils.js +257 -0
  64. package/build/dex/angle-transmuter/utils.js.map +1 -0
  65. package/build/dex/idle-dao/config.d.ts +6 -0
  66. package/build/dex/idle-dao/config.js +307 -0
  67. package/build/dex/idle-dao/config.js.map +1 -0
  68. package/build/dex/idle-dao/idle-dao-pool.d.ts +56 -0
  69. package/build/dex/idle-dao/idle-dao-pool.js +176 -0
  70. package/build/dex/idle-dao/idle-dao-pool.js.map +1 -0
  71. package/build/dex/idle-dao/idle-dao-pooling-pool.d.ts +16 -0
  72. package/build/dex/idle-dao/idle-dao-pooling-pool.js +57 -0
  73. package/build/dex/idle-dao/idle-dao-pooling-pool.js.map +1 -0
  74. package/build/dex/idle-dao/idle-dao.d.ts +41 -0
  75. package/build/dex/idle-dao/idle-dao.js +238 -0
  76. package/build/dex/idle-dao/idle-dao.js.map +1 -0
  77. package/build/dex/idle-dao/scripts.d.ts +9 -0
  78. package/build/dex/idle-dao/scripts.js +552 -0
  79. package/build/dex/idle-dao/scripts.js.map +1 -0
  80. package/build/dex/idle-dao/tokens.d.ts +9 -0
  81. package/build/dex/idle-dao/tokens.js +65 -0
  82. package/build/dex/idle-dao/tokens.js.map +1 -0
  83. package/build/dex/idle-dao/types.d.ts +35 -0
  84. package/build/dex/idle-dao/types.js +11 -0
  85. package/build/dex/idle-dao/types.js.map +1 -0
  86. package/build/dex/idle-dao/utils.d.ts +8 -0
  87. package/build/dex/idle-dao/utils.js +148 -0
  88. package/build/dex/idle-dao/utils.js.map +1 -0
  89. package/build/dex/index.js +2 -0
  90. package/build/dex/index.js.map +1 -1
  91. package/build/dex/platypus/platypus.d.ts +2 -1
  92. package/build/dex/platypus/platypus.js +31 -0
  93. package/build/dex/platypus/platypus.js.map +1 -1
  94. package/build/dex/swaap-v1/swaap-v1.d.ts +2 -1
  95. package/build/dex/swaap-v1/swaap-v1.js +10 -0
  96. package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
  97. package/build/lib/chainlink.d.ts +2 -0
  98. package/build/lib/chainlink.js +9 -0
  99. package/build/lib/chainlink.js.map +1 -1
  100. package/build/utils.d.ts +1 -1
  101. package/package.json +1 -1
  102. package/src/abi/Redstone.json +739 -0
  103. package/src/abi/angle-transmuter/ChainlinkAccessControlledOffchainAggregator.json +1246 -0
  104. package/src/abi/angle-transmuter/ChainlinkEACAggregatorProxy.json +509 -0
  105. package/src/abi/angle-transmuter/MorphoOracle.json +193 -0
  106. package/src/abi/angle-transmuter/MorphoVault.json +2506 -0
  107. package/src/abi/angle-transmuter/Pyth.json +1534 -0
  108. package/src/abi/angle-transmuter/Transmuter.json +1711 -0
  109. package/src/abi/angle-transmuter/TransmuterSidechain.json +1798 -0
  110. package/src/dex/angle-transmuter/angle-transmuter-e2e.test.ts +156 -0
  111. package/src/dex/angle-transmuter/angle-transmuter-events.test.ts +365 -0
  112. package/src/dex/angle-transmuter/angle-transmuter-integration.test.ts +390 -0
  113. package/src/dex/angle-transmuter/angle-transmuter-pool.ts +895 -0
  114. package/src/dex/angle-transmuter/angle-transmuter.ts +408 -0
  115. package/src/dex/angle-transmuter/backedOracle.ts +91 -0
  116. package/src/dex/angle-transmuter/config.ts +50 -0
  117. package/src/dex/angle-transmuter/constants.ts +138 -0
  118. package/src/dex/angle-transmuter/morphoOracle.ts +335 -0
  119. package/src/dex/angle-transmuter/morphoVault.ts +134 -0
  120. package/src/dex/angle-transmuter/pyth.ts +105 -0
  121. package/src/dex/angle-transmuter/redstone.ts +105 -0
  122. package/src/dex/angle-transmuter/transmuter.ts +619 -0
  123. package/src/dex/angle-transmuter/types.ts +203 -0
  124. package/src/dex/angle-transmuter/utils.ts +358 -0
  125. package/src/dex/index.ts +2 -0
  126. package/src/lib/chainlink.ts +15 -0
  127. package/tests/constants-e2e.ts +48 -3
  128. package/build/abi/Uncompressor.json +0 -250
  129. package/build/dex/bProtocol.d.ts +0 -18
  130. package/build/dex/bProtocol.js +0 -39
  131. package/build/dex/bProtocol.js.map +0 -1
  132. package/build/dex/bancor.d.ts +0 -26
  133. package/build/dex/bancor.js +0 -58
  134. package/build/dex/bancor.js.map +0 -1
  135. package/build/dex/compound.d.ts +0 -18
  136. package/build/dex/compound.js +0 -46
  137. package/build/dex/compound.js.map +0 -1
  138. package/build/dex/curve-v2.d.ts +0 -58
  139. package/build/dex/curve-v2.js +0 -180
  140. package/build/dex/curve-v2.js.map +0 -1
  141. package/build/dex/dodo-v1.d.ts +0 -33
  142. package/build/dex/dodo-v1.js +0 -63
  143. package/build/dex/dodo-v1.js.map +0 -1
  144. package/build/dex/etherfi/etherfi.d.ts +0 -26
  145. package/build/dex/etherfi/etherfi.js +0 -96
  146. package/build/dex/etherfi/etherfi.js.map +0 -1
  147. package/build/dex/lido.d.ts +0 -19
  148. package/build/dex/lido.js +0 -42
  149. package/build/dex/lido.js.map +0 -1
  150. package/build/dex/onebit.d.ts +0 -25
  151. package/build/dex/onebit.js +0 -42
  152. package/build/dex/onebit.js.map +0 -1
  153. package/build/dex/sdai/config.d.ts +0 -11
  154. package/build/dex/sdai/config.js +0 -21
  155. package/build/dex/sdai/config.js.map +0 -1
  156. package/build/dex/sdai/constants.d.ts +0 -2
  157. package/build/dex/sdai/constants.js +0 -6
  158. package/build/dex/sdai/constants.js.map +0 -1
  159. package/build/dex/sdai/scripts/validate-state.d.ts +0 -1
  160. package/build/dex/sdai/scripts/validate-state.js +0 -102
  161. package/build/dex/sdai/scripts/validate-state.js.map +0 -1
  162. package/build/dex/sdai/sdai-pool.d.ts +0 -16
  163. package/build/dex/sdai/sdai-pool.js +0 -85
  164. package/build/dex/sdai/sdai-pool.js.map +0 -1
  165. package/build/dex/sdai/sdai.d.ts +0 -51
  166. package/build/dex/sdai/sdai.js +0 -172
  167. package/build/dex/sdai/sdai.js.map +0 -1
  168. package/build/dex/sdai/types.d.ts +0 -21
  169. package/build/dex/sdai/types.js +0 -11
  170. package/build/dex/sdai/types.js.map +0 -1
  171. package/build/dex/sdai/utils.d.ts +0 -4
  172. package/build/dex/sdai/utils.js +0 -39
  173. package/build/dex/sdai/utils.js.map +0 -1
  174. package/build/dex/smoothy.d.ts +0 -26
  175. package/build/dex/smoothy.js +0 -48
  176. package/build/dex/smoothy.js.map +0 -1
  177. package/build/dex/stable-pool.d.ts +0 -28
  178. package/build/dex/stable-pool.js +0 -62
  179. package/build/dex/stable-pool.js.map +0 -1
  180. package/build/dex/trader-joe-v2.1.d.ts +0 -43
  181. package/build/dex/trader-joe-v2.1.js +0 -79
  182. package/build/dex/trader-joe-v2.1.js.map +0 -1
  183. package/build/executor/compressor/Compressor.d.ts +0 -23
  184. package/build/executor/compressor/Compressor.js +0 -144
  185. package/build/executor/compressor/Compressor.js.map +0 -1
  186. package/build/executor/compressor/compress.d.ts +0 -17
  187. package/build/executor/compressor/compress.js +0 -187
  188. package/build/executor/compressor/compress.js.map +0 -1
  189. package/build/executor/compressor/compress_functions/addressSubstitution.d.ts +0 -6
  190. package/build/executor/compressor/compress_functions/addressSubstitution.js +0 -29
  191. package/build/executor/compressor/compress_functions/addressSubstitution.js.map +0 -1
  192. package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.d.ts +0 -10
  193. package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.js +0 -40
  194. package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.js.map +0 -1
  195. package/build/executor/compressor/compress_functions/byteSubstitution.d.ts +0 -11
  196. package/build/executor/compressor/compress_functions/byteSubstitution.js +0 -64
  197. package/build/executor/compressor/compress_functions/byteSubstitution.js.map +0 -1
  198. package/build/executor/compressor/compress_functions/ffSubstitution.d.ts +0 -7
  199. package/build/executor/compressor/compress_functions/ffSubstitution.js +0 -54
  200. package/build/executor/compressor/compress_functions/ffSubstitution.js.map +0 -1
  201. package/build/executor/compressor/compress_functions/findLongestAndSubstitute.d.ts +0 -8
  202. package/build/executor/compressor/compress_functions/findLongestAndSubstitute.js +0 -67
  203. package/build/executor/compressor/compress_functions/findLongestAndSubstitute.js.map +0 -1
  204. package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.d.ts +0 -8
  205. package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.js +0 -61
  206. package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.js.map +0 -1
  207. package/build/executor/compressor/compress_functions/reverseAddressSubstitution.d.ts +0 -6
  208. package/build/executor/compressor/compress_functions/reverseAddressSubstitution.js +0 -37
  209. package/build/executor/compressor/compress_functions/reverseAddressSubstitution.js.map +0 -1
  210. package/build/executor/compressor/compress_functions/searchUnusedBytes.d.ts +0 -9
  211. package/build/executor/compressor/compress_functions/searchUnusedBytes.js +0 -33
  212. package/build/executor/compressor/compress_functions/searchUnusedBytes.js.map +0 -1
  213. package/build/executor/compressor/fetchSaved.d.ts +0 -0
  214. package/build/executor/compressor/fetchSaved.js +0 -17
  215. package/build/executor/compressor/fetchSaved.js.map +0 -1
  216. package/build/executor/compressor/utils/computeCostL2.d.ts +0 -2
  217. package/build/executor/compressor/utils/computeCostL2.js +0 -14
  218. package/build/executor/compressor/utils/computeCostL2.js.map +0 -1
  219. package/build/executor/compressor/utils/findLongestDuplicatedString.d.ts +0 -2
  220. package/build/executor/compressor/utils/findLongestDuplicatedString.js +0 -30
  221. package/build/executor/compressor/utils/findLongestDuplicatedString.js.map +0 -1
  222. package/build/executor/compressor/utils/getAllIndexes.d.ts +0 -2
  223. package/build/executor/compressor/utils/getAllIndexes.js +0 -12
  224. package/build/executor/compressor/utils/getAllIndexes.js.map +0 -1
  225. package/build/executor/compressor/utils/getByteForAddress.d.ts +0 -2
  226. package/build/executor/compressor/utils/getByteForAddress.js +0 -14
  227. package/build/executor/compressor/utils/getByteForAddress.js.map +0 -1
  228. package/build/executor/compressor/utils/intTo2Bytes.d.ts +0 -2
  229. package/build/executor/compressor/utils/intTo2Bytes.js +0 -14
  230. package/build/executor/compressor/utils/intTo2Bytes.js.map +0 -1
  231. package/build/executor/compressor/utils/intTo3Bytes.d.ts +0 -2
  232. package/build/executor/compressor/utils/intTo3Bytes.js +0 -18
  233. package/build/executor/compressor/utils/intTo3Bytes.js.map +0 -1
  234. package/build/executor/compressor/utils/intToByte.d.ts +0 -2
  235. package/build/executor/compressor/utils/intToByte.js +0 -10
  236. package/build/executor/compressor/utils/intToByte.js.map +0 -1
@@ -0,0 +1,408 @@
1
+ import { AsyncOrSync } from 'ts-essentials';
2
+ import {
3
+ Token,
4
+ Address,
5
+ ExchangePrices,
6
+ PoolPrices,
7
+ AdapterExchangeParam,
8
+ SimpleExchangeParam,
9
+ PoolLiquidity,
10
+ Logger,
11
+ NumberAsString,
12
+ DexExchangeParam,
13
+ } from '../../types';
14
+ import { SwapSide, Network } from '../../constants';
15
+ import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
16
+ import { getDexKeysWithNetwork } from '../../utils';
17
+ import { Context, IDex } from '../../dex/idex';
18
+ import { IDexHelper } from '../../dex-helper/idex-helper';
19
+ import { AngleTransmuterData, DexParams } from './types';
20
+ import { SimpleExchange } from '../simple-exchange';
21
+ import { AngleTransmuterConfig, Adapters } from './config';
22
+ import { AngleTransmuterEventPool } from './angle-transmuter-pool';
23
+ import { Interface, formatUnits, parseUnits } from 'ethers/lib/utils';
24
+ import { TransmuterSubscriber } from './transmuter';
25
+ import ERC20ABI from '../../abi/erc20.json';
26
+ import { extractReturnAmountPosition } from '../../executor/utils';
27
+
28
+ const TransmuterGasCost = 350000;
29
+
30
+ export class AngleTransmuter
31
+ extends SimpleExchange
32
+ implements IDex<AngleTransmuterData>
33
+ {
34
+ protected eventPools: { [key: string]: AngleTransmuterEventPool } = {};
35
+ protected supportedTokensMap: {
36
+ [key: string]: { [address: string]: boolean };
37
+ } = {};
38
+ protected supportedTokens: { [key: string]: Token[] } = {};
39
+ protected transmuterUSDLiquidity: { [key: string]: number } = {};
40
+ stablecoinList: string[];
41
+
42
+ public static erc20Interface = new Interface(ERC20ABI);
43
+
44
+ readonly hasConstantPriceLargeAmounts = false;
45
+ readonly needWrapNative = true;
46
+
47
+ readonly isFeeOnTransferSupported = false;
48
+
49
+ public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
50
+ getDexKeysWithNetwork(AngleTransmuterConfig);
51
+
52
+ logger: Logger;
53
+
54
+ constructor(
55
+ readonly network: Network,
56
+ readonly dexKey: string,
57
+ readonly dexHelper: IDexHelper,
58
+ protected adapters = Adapters[network] || {},
59
+ protected params: DexParams = AngleTransmuterConfig[dexKey][network],
60
+ ) {
61
+ super(dexHelper, dexKey);
62
+ this.logger = dexHelper.getLogger(dexKey);
63
+ this.stablecoinList = Object.keys(params);
64
+ this.stablecoinList.forEach(stablecoin => {
65
+ this.supportedTokensMap[stablecoin] = {};
66
+ this.supportedTokens[stablecoin] = [];
67
+ this.transmuterUSDLiquidity[stablecoin] = 0;
68
+ });
69
+ this.stablecoinList.forEach(stablecoin => {
70
+ this.supportedTokensMap[stablecoin][
71
+ params[stablecoin as keyof DexParams]!.stablecoin.address.toLowerCase()
72
+ ] = true;
73
+ });
74
+ }
75
+
76
+ // Initialize pricing is called once in the start of
77
+ // pricing service. It is intended to setup the integration
78
+ // for pricing requests. It is optional for a DEX to
79
+ // implement this function
80
+ async initializePricing(blockNumber: number) {
81
+ for (const stablecoin of this.stablecoinList) {
82
+ const config = await AngleTransmuterEventPool.getConfig(
83
+ this.params[stablecoin as keyof DexParams]!,
84
+ blockNumber,
85
+ this.dexHelper.multiContract,
86
+ );
87
+ config.collaterals.forEach(
88
+ (token: Address) =>
89
+ (this.supportedTokensMap[stablecoin][token.toLowerCase()] = true),
90
+ );
91
+ this.eventPools[stablecoin] = new AngleTransmuterEventPool(
92
+ this.dexKey,
93
+ this.network,
94
+ this.dexHelper,
95
+ this.logger,
96
+ config,
97
+ );
98
+ await this.eventPools[stablecoin].initialize(blockNumber);
99
+ }
100
+ }
101
+
102
+ // Returns the list of contract adapters (name and index)
103
+ // for a buy/sell. Return null if there are no adapters.
104
+ getAdapters(side: SwapSide): { name: string; index: number }[] | null {
105
+ return this.adapters[side] ? this.adapters[side] : null;
106
+ }
107
+
108
+ // Returns list of pool identifiers that can be used
109
+ // for a given swap. poolIdentifiers must be unique
110
+ // across DEXes. It is recommended to use
111
+ // ${dexKey}_${poolAddress} as a poolIdentifier
112
+ async getPoolIdentifiers(
113
+ srcToken: Token,
114
+ destToken: Token,
115
+ side: SwapSide,
116
+ blockNumber: number,
117
+ ): Promise<string[]> {
118
+ const knownInfo = this._knownAddress(srcToken, destToken);
119
+ if (!knownInfo.known) return [];
120
+ return [`${this.dexKey}_${knownInfo.agToken!.toLowerCase()}`];
121
+ }
122
+
123
+ // Returns pool prices for amounts.
124
+ // If limitPools is defined only pools in limitPools
125
+ // should be used. If limitPools is undefined then
126
+ // any pools can be used.
127
+ async getPricesVolume(
128
+ srcToken: Token,
129
+ destToken: Token,
130
+ amounts: bigint[],
131
+ side: SwapSide,
132
+ blockNumber: number,
133
+ limitPools?: string[],
134
+ ): Promise<null | ExchangePrices<AngleTransmuterData>> {
135
+ const knownInfo = this._knownAddress(srcToken, destToken);
136
+ const pool = `${this.dexKey}_${knownInfo.agToken!.toLowerCase()}`;
137
+ if (
138
+ !knownInfo.known ||
139
+ (limitPools && limitPools.length > 0 && !limitPools.includes(pool))
140
+ )
141
+ return null;
142
+
143
+ const fiat = knownInfo.fiatName! as keyof DexParams;
144
+ const preProcessDecimals =
145
+ side === SwapSide.SELL ? srcToken.decimals : destToken.decimals;
146
+ const postProcessDecimals =
147
+ side === SwapSide.SELL ? destToken.decimals : srcToken.decimals;
148
+ const unitVolume = 1;
149
+ const amountsFloat = amounts.map(amount =>
150
+ Number.parseFloat(formatUnits(amount.toString(), preProcessDecimals)),
151
+ );
152
+
153
+ const prices = await this.eventPools[fiat]!.getAmountOut(
154
+ srcToken.address.toLowerCase(),
155
+ destToken.address.toLowerCase(),
156
+ side,
157
+ [unitVolume, ...amountsFloat],
158
+ blockNumber,
159
+ );
160
+
161
+ if (!prices) return null;
162
+
163
+ const pricesBigInt = prices.map(price =>
164
+ BigInt(
165
+ parseUnits(
166
+ price.toFixed(postProcessDecimals).toString(),
167
+ postProcessDecimals,
168
+ ).toString(),
169
+ ),
170
+ );
171
+
172
+ return [
173
+ {
174
+ prices: pricesBigInt.slice(1),
175
+ unit: pricesBigInt[0],
176
+ gasCost: TransmuterGasCost,
177
+ exchange: this.dexKey,
178
+ data: { exchange: this.params[fiat]!.transmuter },
179
+ poolAddresses: [this.params[fiat]!.transmuter],
180
+ },
181
+ ];
182
+ }
183
+
184
+ // Returns estimated gas cost of calldata for this DEX in multiSwap
185
+ getCalldataGasCost(
186
+ poolPrices: PoolPrices<AngleTransmuterData>,
187
+ ): number | number[] {
188
+ return CALLDATA_GAS_COST.DEX_NO_PAYLOAD;
189
+ }
190
+
191
+ // Encode params required by the exchange adapter
192
+ // Used for multiSwap, buy & megaSwap
193
+ // Hint: abiCoder.encodeParameter() could be useful
194
+ getAdapterParam(
195
+ srcToken: string,
196
+ destToken: string,
197
+ srcAmount: string,
198
+ destAmount: string,
199
+ data: AngleTransmuterData,
200
+ side: SwapSide,
201
+ ): AdapterExchangeParam {
202
+ const { exchange } = data;
203
+
204
+ // Encode here the payload for adapter
205
+ const payload = '';
206
+
207
+ return {
208
+ targetExchange: exchange,
209
+ payload,
210
+ networkFee: '0',
211
+ };
212
+ }
213
+
214
+ getDexParam(
215
+ srcToken: Address,
216
+ destToken: Address,
217
+ srcAmount: NumberAsString,
218
+ destAmount: NumberAsString,
219
+ recipient: Address,
220
+ data: AngleTransmuterData,
221
+ side: SwapSide,
222
+ _: Context,
223
+ executorAddress: Address,
224
+ ): DexExchangeParam {
225
+ const { exchange } = data;
226
+
227
+ // Encode here the transaction arguments
228
+ const swapData =
229
+ TransmuterSubscriber.transmuterCrosschainInterface.encodeFunctionData(
230
+ side === SwapSide.SELL ? 'swapExactInput' : 'swapExactOutput',
231
+ [
232
+ side === SwapSide.SELL ? srcAmount : destAmount,
233
+ side === SwapSide.SELL ? destAmount : srcAmount,
234
+ srcToken,
235
+ destToken,
236
+ recipient,
237
+ 0,
238
+ ],
239
+ );
240
+
241
+ return {
242
+ needWrapNative: this.needWrapNative,
243
+ dexFuncHasRecipient: true,
244
+ exchangeData: swapData,
245
+ targetExchange: exchange,
246
+ returnAmountPos:
247
+ side === SwapSide.SELL
248
+ ? extractReturnAmountPosition(
249
+ TransmuterSubscriber.transmuterCrosschainInterface,
250
+ 'swapExactInput',
251
+ 'amountOut',
252
+ )
253
+ : undefined,
254
+ };
255
+ }
256
+
257
+ async updatePoolState(): Promise<void> {
258
+ for (const stablecoin of this.stablecoinList) {
259
+ const fiat = stablecoin as keyof DexParams;
260
+ const paramFiat = this.params[fiat]!;
261
+
262
+ if (!this.supportedTokens.length) {
263
+ let tokenAddresses = await AngleTransmuterEventPool.getCollateralsList(
264
+ paramFiat.transmuter,
265
+ 'latest',
266
+ this.dexHelper.multiContract,
267
+ );
268
+ tokenAddresses = tokenAddresses.concat([paramFiat.stablecoin.address]);
269
+
270
+ const decimalsCallData =
271
+ AngleTransmuter.erc20Interface.encodeFunctionData('decimals');
272
+ const tokenBalanceMultiCall = tokenAddresses.map(t => ({
273
+ target: t,
274
+ callData: decimalsCallData,
275
+ }));
276
+ const res = (
277
+ await this.dexHelper.multiContract.methods
278
+ .aggregate(tokenBalanceMultiCall)
279
+ .call()
280
+ ).returnData;
281
+
282
+ const tokenDecimals = res.map((r: any) =>
283
+ Number.parseInt(
284
+ AngleTransmuter.erc20Interface
285
+ .decodeFunctionResult('decimals', r)[0]
286
+ .toString(),
287
+ ),
288
+ );
289
+
290
+ this.supportedTokens[fiat] = tokenAddresses.map((t, i) => ({
291
+ address: t,
292
+ decimals: tokenDecimals[i],
293
+ }));
294
+ }
295
+
296
+ // Only work if there are no managers
297
+ const erc20BalanceCalldata =
298
+ AngleTransmuter.erc20Interface.encodeFunctionData('balanceOf', [
299
+ paramFiat.transmuter,
300
+ ]);
301
+ const tokenBalanceMultiCall = this.supportedTokens[fiat].map(t => ({
302
+ target: t.address,
303
+ callData: erc20BalanceCalldata,
304
+ }));
305
+ const res = (
306
+ await this.dexHelper.multiContract.methods
307
+ .aggregate(tokenBalanceMultiCall)
308
+ .call()
309
+ ).returnData;
310
+ const tokenBalances = res.map((r: any) =>
311
+ BigInt(
312
+ AngleTransmuter.erc20Interface
313
+ .decodeFunctionResult('balanceOf', r)[0]
314
+ .toString(),
315
+ ),
316
+ );
317
+
318
+ // TODO bC3M price not detected
319
+ const tokenBalancesUSD = await Promise.all(
320
+ this.supportedTokens[fiat].map((t, i) =>
321
+ this.dexHelper.getTokenUSDPrice(t, tokenBalances[i]),
322
+ ),
323
+ );
324
+ this.transmuterUSDLiquidity[fiat] = tokenBalancesUSD.reduce(
325
+ (sum: number, curr: number) => sum + curr,
326
+ );
327
+ }
328
+ }
329
+
330
+ // Returns list of top pools based on liquidity. Max
331
+ // limit number pools should be returned.
332
+ async getTopPoolsForToken(
333
+ tokenAddress: Address,
334
+ limit: number,
335
+ ): Promise<PoolLiquidity[]> {
336
+ const tokenAddressLower = tokenAddress.toLowerCase();
337
+ for (const stablecoin of this.stablecoinList) {
338
+ const fiat = stablecoin as keyof DexParams;
339
+ const paramFiat = this.params[fiat]!;
340
+ const stableCoinLowercase = paramFiat.stablecoin.address.toLowerCase();
341
+
342
+ // If not this stable let's check another one
343
+ if (
344
+ !this.supportedTokens[fiat].some(
345
+ t => t.address.toLowerCase() === tokenAddressLower,
346
+ )
347
+ )
348
+ continue;
349
+
350
+ const connectorTokens =
351
+ tokenAddressLower === stableCoinLowercase
352
+ ? this.supportedTokens[fiat].filter(
353
+ token => token.address.toLowerCase() !== stableCoinLowercase,
354
+ )
355
+ : [paramFiat.stablecoin];
356
+
357
+ return [
358
+ {
359
+ exchange: this.dexKey,
360
+ address: paramFiat.transmuter,
361
+ connectorTokens: connectorTokens.slice(0, limit),
362
+ // liquidity is potentially infinite if swapping for agXXX, otherwise at most reserves value
363
+ liquidityUSD:
364
+ tokenAddressLower === stableCoinLowercase
365
+ ? this.transmuterUSDLiquidity[fiat]
366
+ : 1e9,
367
+ },
368
+ ];
369
+ }
370
+ return [];
371
+ }
372
+
373
+ releaseResources(): AsyncOrSync<void> {
374
+ Object.values(this.eventPools).forEach(pool => pool.releaseResources());
375
+ }
376
+
377
+ _knownAddress(
378
+ srcToken: Token,
379
+ destToken: Token,
380
+ ): { known: boolean; agToken: string | null; fiatName: string | null } {
381
+ const srcAddress = this.dexHelper.config
382
+ .wrapETH(srcToken)
383
+ .address.toLowerCase();
384
+ const destAddress = this.dexHelper.config
385
+ .wrapETH(destToken)
386
+ .address.toLowerCase();
387
+
388
+ for (const stablecoin of this.stablecoinList) {
389
+ const fiat = stablecoin as keyof DexParams;
390
+ const paramFiat = this.params[fiat]!;
391
+ if (
392
+ srcAddress !== destAddress &&
393
+ this.supportedTokensMap[stablecoin][srcAddress] &&
394
+ this.supportedTokensMap[stablecoin][destAddress] &&
395
+ // check that at least one of the tokens is EURA
396
+ (srcAddress === paramFiat.stablecoin.address.toLowerCase() ||
397
+ destAddress === paramFiat.stablecoin.address.toLowerCase())
398
+ ) {
399
+ return {
400
+ known: true,
401
+ agToken: paramFiat.stablecoin.address.toLowerCase(),
402
+ fiatName: stablecoin,
403
+ };
404
+ }
405
+ }
406
+ return { known: false, agToken: null, fiatName: null };
407
+ }
408
+ }
@@ -0,0 +1,91 @@
1
+ import { DeepReadonly } from 'ts-essentials';
2
+ import { PartialEventSubscriber } from '../../composed-event-subscriber';
3
+ import {
4
+ Address,
5
+ BlockHeader,
6
+ Log,
7
+ Logger,
8
+ MultiCallInput,
9
+ MultiCallOutput,
10
+ } from '../../types';
11
+ import { Lens } from '../../lens';
12
+ import { Interface } from '@ethersproject/abi';
13
+ import ProxyABI from '../../abi/chainlink.json';
14
+ import { ChainLinkState } from '../../lib/chainlink';
15
+
16
+ export class BackedSubscriber<State> extends PartialEventSubscriber<
17
+ State,
18
+ ChainLinkState
19
+ > {
20
+ static readonly proxyInterface = new Interface(ProxyABI);
21
+ static readonly ANSWER_UPDATED_TOPIC =
22
+ BackedSubscriber.proxyInterface.getEventTopic('AnswerUpdated');
23
+
24
+ constructor(
25
+ private proxy: Address,
26
+ private aggregator: Address,
27
+ lens: Lens<DeepReadonly<State>, DeepReadonly<ChainLinkState>>,
28
+ logger: Logger,
29
+ ) {
30
+ super([aggregator], lens, logger);
31
+ }
32
+
33
+ static getReadDecimal(proxy: Address): MultiCallInput {
34
+ return {
35
+ target: proxy,
36
+ callData: BackedSubscriber.proxyInterface.encodeFunctionData('decimals'),
37
+ };
38
+ }
39
+
40
+ static readDecimals(multicallOutput: MultiCallOutput): Address {
41
+ return BackedSubscriber.proxyInterface.decodeFunctionResult(
42
+ 'decimals',
43
+ multicallOutput,
44
+ )[0];
45
+ }
46
+
47
+ public processLog(
48
+ state: DeepReadonly<ChainLinkState>,
49
+ log: Readonly<Log>,
50
+ blockHeader: Readonly<BlockHeader>,
51
+ ): DeepReadonly<ChainLinkState> | null {
52
+ if (log.topics[0] !== BackedSubscriber.ANSWER_UPDATED_TOPIC) return null; // Ignore other events
53
+ const decoded = BackedSubscriber.proxyInterface.decodeEventLog(
54
+ 'AnswerUpdated',
55
+ log.data,
56
+ log.topics,
57
+ );
58
+ return {
59
+ answer: BigInt(decoded.current.toString()),
60
+ timestamp: BigInt(decoded.updatedAt.toString()),
61
+ };
62
+ }
63
+
64
+ public getGenerateStateMultiCallInputs(): MultiCallInput[] {
65
+ return [
66
+ {
67
+ target: this.proxy,
68
+ callData:
69
+ BackedSubscriber.proxyInterface.encodeFunctionData('latestRoundData'),
70
+ },
71
+ ];
72
+ }
73
+
74
+ public generateState(
75
+ multicallOutputs: MultiCallOutput[],
76
+ blockNumber?: number | 'latest',
77
+ ): DeepReadonly<ChainLinkState> {
78
+ const decoded = BackedSubscriber.proxyInterface.decodeFunctionResult(
79
+ 'latestRoundData',
80
+ multicallOutputs[0],
81
+ );
82
+ return {
83
+ answer: BigInt(decoded.answer.toString()),
84
+ timestamp: BigInt(decoded.updatedAt.toString()),
85
+ };
86
+ }
87
+
88
+ public getLatestRoundData(state: DeepReadonly<State>): bigint {
89
+ return this.lens.get()(state).answer;
90
+ }
91
+ }
@@ -0,0 +1,50 @@
1
+ import { DexParams } from './types';
2
+ import { DexConfigMap, AdapterMappings } from '../../types';
3
+ import { Network, SwapSide } from '../../constants';
4
+
5
+ export const AngleTransmuterConfig: DexConfigMap<DexParams> = {
6
+ AngleTransmuter: {
7
+ [Network.MAINNET]: {
8
+ EUR: {
9
+ stablecoin: {
10
+ address: '0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8',
11
+ decimals: 18,
12
+ },
13
+ transmuter: '0x00253582b2a3FE112feEC532221d9708c64cEFAb',
14
+ pyth: '0x4305FB66699C3B2702D4d05CF36551390A4c69C6',
15
+ },
16
+ USD: {
17
+ stablecoin: {
18
+ address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
19
+ decimals: 18,
20
+ },
21
+ transmuter: '0x222222fD79264BBE280b4986F6FEfBC3524d0137',
22
+ pyth: '0x4305FB66699C3B2702D4d05CF36551390A4c69C6',
23
+ },
24
+ },
25
+ [Network.ARBITRUM]: {
26
+ USD: {
27
+ stablecoin: {
28
+ address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
29
+ decimals: 18,
30
+ },
31
+ transmuter: '0xD253b62108d1831aEd298Fc2434A5A8e4E418053',
32
+ pyth: '0xff1a0f4744e8582DF1aE09D5611b887B6a12925C',
33
+ },
34
+ },
35
+ [Network.BASE]: {
36
+ USD: {
37
+ stablecoin: {
38
+ address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
39
+ decimals: 18,
40
+ },
41
+ transmuter: '0x222222880e079445Df703c0604706E71a538Fd4f',
42
+ pyth: '0x8250f4aF4B972684F7b336503E2D6dFeDeB1487a',
43
+ },
44
+ },
45
+ },
46
+ };
47
+
48
+ export const Adapters: Record<number, AdapterMappings> = {
49
+ [Network.MAINNET]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
50
+ };
@@ -0,0 +1,138 @@
1
+ import { ethers } from 'ethers';
2
+ import { bigIntify } from '../../utils';
3
+ import { ChainlinkConfig, MorphoConfig, PoolConfig, PythConfig } from './types';
4
+
5
+ export const CBETH = '0xBe9895146f7AF43049ca1c1AE358B0541Ea49704';
6
+ export const RETH = '0xae78736Cd615f374D3085123A210448E74Fc6393';
7
+ export const STETH = '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84';
8
+ export const SFRXETH = '0xac3E018457B222d93114458476f3E3416Abbe38F';
9
+
10
+ export const configEUR: PoolConfig = {
11
+ stablecoin: {
12
+ address: '0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8',
13
+ decimals: 18,
14
+ },
15
+ transmuter: '0x00253582b2a3FE112feEC532221d9708c64cEFAb',
16
+ collaterals: [
17
+ '0x3f95AA88dDbB7D9D484aa3D482bf0a80009c52c9',
18
+ '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
19
+ '0x2F123cF3F37CE3328CC9B5b8415f9EC5109b45e7',
20
+ ],
21
+ oracles: {
22
+ chainlink: {},
23
+ backed: {
24
+ '0x83Ec02059F686E747392A22ddfED7833bA0d7cE3': {
25
+ proxy: '0x83Ec02059F686E747392A22ddfED7833bA0d7cE3',
26
+ aggregator: '0x83Ec02059F686E747392A22ddfED7833bA0d7cE3',
27
+ decimals: 8,
28
+ },
29
+ '0x475855DAe09af1e3f2d380d766b9E630926ad3CE': {
30
+ proxy: '0x475855DAe09af1e3f2d380d766b9E630926ad3CE',
31
+ aggregator: '0x475855DAe09af1e3f2d380d766b9E630926ad3CE',
32
+ decimals: 8,
33
+ },
34
+ },
35
+ redstone: {
36
+ '0x6E27A25999B3C665E44D903B2139F5a4Be2B6C26': {
37
+ proxy: '0x6E27A25999B3C665E44D903B2139F5a4Be2B6C26',
38
+ aggregator: '0x5BeEFeFE23aecccC77d164AB8E9Ff74e056588f1',
39
+ decimals: 8,
40
+ },
41
+ },
42
+ morpho: {},
43
+ pyth: {
44
+ proxy: '0x4305FB66699C3B2702D4d05CF36551390A4c69C6',
45
+ ids: [
46
+ '0x76fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5c',
47
+ '0xa995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b',
48
+ ],
49
+ },
50
+ },
51
+ };
52
+
53
+ export const configUSD: PoolConfig = {
54
+ stablecoin: {
55
+ address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
56
+ decimals: 18,
57
+ },
58
+ transmuter: '0x222222fD79264BBE280b4986F6FEfBC3524d0137',
59
+ collaterals: [
60
+ '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
61
+ '0xCA30c93B02514f86d5C86a6e375E3A330B435Fb5',
62
+ '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB',
63
+ ],
64
+ oracles: {
65
+ backed: {} as ChainlinkConfig,
66
+ chainlink: {
67
+ '0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6': {
68
+ proxy: '0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6',
69
+ aggregator: '0x789190466E21a8b78b8027866CBBDc151542A26C',
70
+ decimals: 8,
71
+ },
72
+ '0x32d1463EB53b73C095625719Afa544D5426354cB': {
73
+ proxy: '0x32d1463EB53b73C095625719Afa544D5426354cB',
74
+ aggregator: '0x5EE6Ee50c1cB3E8Da20eE83D57818184387433e8',
75
+ decimals: 8,
76
+ },
77
+ },
78
+ redstone: {} as ChainlinkConfig,
79
+ morpho: {
80
+ '0x025106374196586E8BC91eE8818dD7B0Efd2B78B': {
81
+ baseVault: '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB',
82
+ baseVaultConversion: bigIntify('1000000000000000000'),
83
+ quoteVault: ethers.constants.AddressZero,
84
+ quoteVaultConversion: bigIntify('1'),
85
+ baseFeed1: '0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6',
86
+ baseFeed2: ethers.constants.AddressZero,
87
+ quoteFeed1: ethers.constants.AddressZero,
88
+ quoteFeed2: ethers.constants.AddressZero,
89
+ scaleFactor: bigIntify('1000000000000000000'),
90
+ },
91
+ },
92
+ pyth: {} as PythConfig,
93
+ },
94
+ };
95
+
96
+ export const configUSDBase: PoolConfig = {
97
+ stablecoin: {
98
+ address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
99
+ decimals: 18,
100
+ },
101
+ transmuter: '0x222222880e079445Df703c0604706E71a538Fd4f',
102
+ collaterals: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'],
103
+ oracles: {
104
+ backed: {} as ChainlinkConfig,
105
+ chainlink: {
106
+ '0x7e860098F58bBFC8648a4311b374B1D669a2bc6B': {
107
+ proxy: '0x7e860098F58bBFC8648a4311b374B1D669a2bc6B',
108
+ aggregator: '0x0Ee7145e1370653533e2F2E824424bE2AA95A4Aa',
109
+ decimals: 8,
110
+ },
111
+ },
112
+ redstone: {} as ChainlinkConfig,
113
+ morpho: {} as MorphoConfig,
114
+ pyth: {} as PythConfig,
115
+ },
116
+ };
117
+
118
+ export const configUSDArbitrum: PoolConfig = {
119
+ stablecoin: {
120
+ address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274',
121
+ decimals: 18,
122
+ },
123
+ transmuter: '0xD253b62108d1831aEd298Fc2434A5A8e4E418053',
124
+ collaterals: ['0xaf88d065e77c8cC2239327C5EDb3A432268e5831'],
125
+ oracles: {
126
+ backed: {} as ChainlinkConfig,
127
+ chainlink: {
128
+ '0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3': {
129
+ proxy: '0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3',
130
+ aggregator: '0x2946220288DbBF77dF0030fCecc2a8348CbBE32C',
131
+ decimals: 8,
132
+ },
133
+ },
134
+ redstone: {} as ChainlinkConfig,
135
+ morpho: {} as MorphoConfig,
136
+ pyth: {} as PythConfig,
137
+ },
138
+ };