@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,619 @@
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 { CBETH, RETH, SFRXETH, STETH } from './constants';
12
+ import { Lens } from '../../lens';
13
+ import { Interface } from '@ethersproject/abi';
14
+ import TransmuterABI from '../../abi/angle-transmuter/Transmuter.json';
15
+ import TransmuterSidechainABI from '../../abi/angle-transmuter/TransmuterSidechain.json';
16
+ import {
17
+ DecodedOracleConfig,
18
+ Chainlink,
19
+ OracleFeed,
20
+ OracleReadType,
21
+ Pyth,
22
+ TransmuterState,
23
+ Fees,
24
+ Oracle,
25
+ CollateralState,
26
+ MaxOracle,
27
+ MorphoOracle,
28
+ } from './types';
29
+ import _ from 'lodash';
30
+ import { BigNumber, ethers } from 'ethers';
31
+ import { formatEther, formatUnits } from 'ethers/lib/utils';
32
+ import { filterDictionaryOnly } from './utils';
33
+ import { Network } from '../../constants';
34
+
35
+ export class TransmuterSubscriber<State> extends PartialEventSubscriber<
36
+ State,
37
+ TransmuterState
38
+ > {
39
+ static readonly transmuterCrosschainInterface = new Interface(TransmuterABI);
40
+ public readonly interface;
41
+
42
+ constructor(
43
+ private EURA: Address,
44
+ private transmuter: Address,
45
+ private collaterals: Address[],
46
+ protected network: number,
47
+ lens: Lens<DeepReadonly<State>, DeepReadonly<TransmuterState>>,
48
+ logger: Logger,
49
+ ) {
50
+ super([transmuter], lens, logger);
51
+ if (network === Network.MAINNET)
52
+ this.interface = new Interface(TransmuterABI);
53
+ else this.interface = new Interface(TransmuterSidechainABI);
54
+ }
55
+
56
+ public processLog(
57
+ state: DeepReadonly<TransmuterState>,
58
+ log: Readonly<Log>,
59
+ blockHeader: Readonly<BlockHeader>,
60
+ ): DeepReadonly<TransmuterState> | null {
61
+ try {
62
+ const parsed = this.interface.parseLog(log);
63
+ const _state: TransmuterState = _.cloneDeep(state) as TransmuterState;
64
+ switch (parsed.name) {
65
+ case 'FeesSet':
66
+ return this._handleFeesSet(parsed, _state);
67
+ case 'RedemptionCurveParamsSet':
68
+ return this._handleRedemptionCurveSet(parsed, _state);
69
+ case 'OracleSet':
70
+ return this._handleOracleSet(parsed, _state, blockHeader.number);
71
+ case 'Swap':
72
+ return this._handleSwap(parsed, _state);
73
+ case 'Redeemed':
74
+ return this._handleRedeem(parsed, _state);
75
+ case 'ReservesAdjusted':
76
+ return this._handleAdjustStablecoins(parsed, _state);
77
+ case 'CollateralAdded':
78
+ return this._handleAddCollateral(parsed, _state);
79
+ case 'CollateralRevoked':
80
+ return this._handleRevokeCollateral(parsed, _state);
81
+ case 'CollateralWhitelistStatusUpdated':
82
+ return this._handleSetWhitelistedStatus(parsed, _state);
83
+ case 'WhitelistStatusToggled':
84
+ return this._handleIsWhitelistedForType(parsed, _state);
85
+ case 'StablecoinCapSet':
86
+ return this._handleStablecoinCapSet(parsed, _state);
87
+ default:
88
+ return null;
89
+ }
90
+ } catch (e) {
91
+ this.logger.error('Failed to parse log', e);
92
+ return null;
93
+ }
94
+ }
95
+
96
+ public getGenerateStateMultiCallInputs(): MultiCallInput[] {
97
+ const multicallInput = [
98
+ ...this.collaterals.map(collat => ({
99
+ target: this.transmuter,
100
+ callData: this.interface.encodeFunctionData('getIssuedByCollateral', [
101
+ collat,
102
+ ]),
103
+ })),
104
+ ...this.collaterals.map(collat => ({
105
+ target: this.transmuter,
106
+ callData: this.interface.encodeFunctionData('getOracle', [collat]),
107
+ })),
108
+ ...this.collaterals.map(collat => ({
109
+ target: this.transmuter,
110
+ callData: this.interface.encodeFunctionData('getCollateralMintFees', [
111
+ collat,
112
+ ]),
113
+ })),
114
+ ...this.collaterals.map(collat => ({
115
+ target: this.transmuter,
116
+ callData: this.interface.encodeFunctionData('getCollateralBurnFees', [
117
+ collat,
118
+ ]),
119
+ })),
120
+ ...this.collaterals.map(collat => ({
121
+ target: this.transmuter,
122
+ callData: this.interface.encodeFunctionData('isWhitelistedCollateral', [
123
+ collat,
124
+ ]),
125
+ })),
126
+ ...this.collaterals.map(collat => ({
127
+ target: this.transmuter,
128
+ callData: this.interface.encodeFunctionData(
129
+ 'getCollateralWhitelistData',
130
+ [collat],
131
+ ),
132
+ })),
133
+ ];
134
+ if (this.network !== Network.MAINNET) {
135
+ multicallInput.push(
136
+ ...this.collaterals.map(collat => ({
137
+ target: this.transmuter,
138
+ callData: this.interface.encodeFunctionData('getStablecoinCap', [
139
+ collat,
140
+ ]),
141
+ })),
142
+ );
143
+ }
144
+ multicallInput.push(
145
+ ...[
146
+ {
147
+ target: this.transmuter,
148
+ callData: this.interface.encodeFunctionData('getRedemptionFees'),
149
+ },
150
+ {
151
+ target: this.transmuter,
152
+ callData: this.interface.encodeFunctionData('getTotalIssued'),
153
+ },
154
+ ],
155
+ );
156
+ return multicallInput;
157
+ }
158
+
159
+ public generateState(
160
+ multicallOutputs: MultiCallOutput[],
161
+ blockNumber?: number | 'latest',
162
+ ): DeepReadonly<TransmuterState> {
163
+ const transmuterState = {
164
+ collaterals: {} as {
165
+ [token: string]: CollateralState;
166
+ },
167
+ isWhitelisted: {} as {
168
+ [token: string]: Set<string>;
169
+ },
170
+ totalStablecoinIssued: 0,
171
+ xRedemptionCurve: [],
172
+ yRedemptionCurve: [],
173
+ } as TransmuterState;
174
+
175
+ const nbrCollaterals = this.collaterals.length;
176
+ const indexStableIssued = 0;
177
+ const indexOracleFees = 1;
178
+ const indexMintFees = 2;
179
+ const indexBurnFees = 3;
180
+ const indexWhitelistStatus = 4;
181
+ const indexWhitelistData = 5;
182
+ const indexStablecoinCap = 6;
183
+
184
+ this.collaterals.forEach(
185
+ (collat: Address, i: number) =>
186
+ (transmuterState.collaterals[collat] = {
187
+ fees: {
188
+ xFeeMint: (
189
+ this.interface.decodeFunctionResult(
190
+ 'getCollateralMintFees',
191
+ multicallOutputs[indexMintFees * nbrCollaterals + i],
192
+ )[0] as BigNumber[]
193
+ ).map(f => Number.parseFloat(formatUnits(f, 9))),
194
+ yFeeMint: (
195
+ this.interface.decodeFunctionResult(
196
+ 'getCollateralMintFees',
197
+ multicallOutputs[indexMintFees * nbrCollaterals + i],
198
+ )[1] as BigNumber[]
199
+ ).map(f => Number.parseFloat(formatUnits(f, 9))),
200
+ xFeeBurn: (
201
+ this.interface.decodeFunctionResult(
202
+ 'getCollateralBurnFees',
203
+ multicallOutputs[indexBurnFees * nbrCollaterals + i],
204
+ )[0] as BigNumber[]
205
+ ).map(f => Number.parseFloat(formatUnits(f, 9))),
206
+ yFeeBurn: (
207
+ this.interface.decodeFunctionResult(
208
+ 'getCollateralBurnFees',
209
+ multicallOutputs[indexBurnFees * nbrCollaterals + i],
210
+ )[1] as BigNumber[]
211
+ ).map(f => Number.parseFloat(formatUnits(f, 9))),
212
+ } as Fees,
213
+ stablecoinsIssued: Number.parseFloat(
214
+ formatUnits(
215
+ this.interface.decodeFunctionResult(
216
+ 'getIssuedByCollateral',
217
+ multicallOutputs[indexStableIssued * nbrCollaterals + i],
218
+ )[0],
219
+ 18,
220
+ ),
221
+ ),
222
+ stablecoinCap:
223
+ this.network === Network.MAINNET
224
+ ? -1
225
+ : Number.parseFloat(
226
+ formatUnits(
227
+ this.interface.decodeFunctionResult(
228
+ 'getStablecoinCap',
229
+ multicallOutputs[indexStablecoinCap * nbrCollaterals + i],
230
+ )[0],
231
+ 18,
232
+ ),
233
+ ),
234
+ config: this._setOracleConfig(
235
+ multicallOutputs[indexOracleFees * nbrCollaterals + i],
236
+ ),
237
+ whitelist: {
238
+ status: this.interface.decodeFunctionResult(
239
+ 'isWhitelistedCollateral',
240
+ multicallOutputs[indexWhitelistStatus * nbrCollaterals + i],
241
+ )[0] as boolean,
242
+ data: this.interface.decodeFunctionResult(
243
+ 'getCollateralWhitelistData',
244
+ multicallOutputs[indexWhitelistData * nbrCollaterals + i],
245
+ )[0] as string,
246
+ },
247
+ }),
248
+ );
249
+ transmuterState.xRedemptionCurve = (
250
+ this.interface.decodeFunctionResult(
251
+ 'getRedemptionFees',
252
+ multicallOutputs[multicallOutputs.length - 2],
253
+ )[0] as BigNumber[]
254
+ ).map(f => Number.parseFloat(formatUnits(f, 9)));
255
+ transmuterState.yRedemptionCurve = (
256
+ this.interface.decodeFunctionResult(
257
+ 'getRedemptionFees',
258
+ multicallOutputs[multicallOutputs.length - 2],
259
+ )[1] as BigNumber[]
260
+ ).map(f => Number.parseFloat(formatUnits(f, 9)));
261
+ transmuterState.totalStablecoinIssued = Number.parseFloat(
262
+ formatUnits(
263
+ this.interface.decodeFunctionResult(
264
+ 'getTotalIssued',
265
+ multicallOutputs[multicallOutputs.length - 1],
266
+ )[0],
267
+ 18,
268
+ ),
269
+ );
270
+
271
+ return transmuterState;
272
+ }
273
+
274
+ /**
275
+ * Update Mint and Burn fees parameters
276
+ */
277
+ _handleFeesSet(
278
+ event: ethers.utils.LogDescription,
279
+ state: TransmuterState,
280
+ ): Readonly<TransmuterState> | null {
281
+ const isMint: boolean = event.args.mint;
282
+ const collateral: string = event.args.collateral;
283
+ const xFee: BigNumber[] = event.args.xFee;
284
+ const yFee: BigNumber[] = event.args.yFee;
285
+ if (isMint) {
286
+ state.collaterals[collateral].fees.xFeeMint = xFee.map(f =>
287
+ Number.parseFloat(formatUnits(f, 9)),
288
+ );
289
+ state.collaterals[collateral].fees.yFeeMint = yFee.map(f =>
290
+ Number.parseFloat(formatUnits(f, 9)),
291
+ );
292
+ } else {
293
+ state.collaterals[collateral].fees.xFeeBurn = xFee.map(f =>
294
+ Number.parseFloat(formatUnits(f, 9)),
295
+ );
296
+ state.collaterals[collateral].fees.yFeeBurn = yFee.map(f =>
297
+ Number.parseFloat(formatUnits(f, 9)),
298
+ );
299
+ }
300
+ return state;
301
+ }
302
+
303
+ /**
304
+ * Update redemption curve parameters
305
+ */
306
+ _handleRedemptionCurveSet(
307
+ event: ethers.utils.LogDescription,
308
+ state: TransmuterState,
309
+ ): Readonly<TransmuterState> | null {
310
+ const xFee: BigNumber[] = event.args.xFee;
311
+ const yFee: BigNumber[] = event.args.yFee;
312
+ state.xRedemptionCurve = xFee.map(f =>
313
+ Number.parseFloat(formatUnits(f, 9)),
314
+ );
315
+ state.yRedemptionCurve = yFee.map(f =>
316
+ Number.parseFloat(formatUnits(f, 9)),
317
+ );
318
+ return state;
319
+ }
320
+
321
+ /**
322
+ * Adapt collateral exposure after a swap event
323
+ */
324
+ _handleSwap(
325
+ event: ethers.utils.LogDescription,
326
+ state: TransmuterState,
327
+ ): Readonly<TransmuterState> | null {
328
+ const tokenIn: string = event.args.tokenIn.toLowerCase();
329
+ const tokenOut: string = event.args.tokenOut.toLowerCase();
330
+ // in case of a burn
331
+ if (tokenIn === this.EURA.toLowerCase()) {
332
+ const amount: number = Number.parseFloat(
333
+ formatUnits(event.args.amountIn, 18),
334
+ );
335
+ state.collaterals[tokenOut].stablecoinsIssued -= amount;
336
+ state.totalStablecoinIssued -= amount;
337
+ } else {
338
+ const amount: number = Number.parseFloat(
339
+ formatUnits(event.args.amountOut, 18),
340
+ );
341
+ state.collaterals[tokenIn].stablecoinsIssued += amount;
342
+ state.totalStablecoinIssued += amount;
343
+ }
344
+ return state;
345
+ }
346
+
347
+ /**
348
+ * Adapt collateral balances after a redeem event
349
+ */
350
+ _handleRedeem(
351
+ event: ethers.utils.LogDescription,
352
+ state: TransmuterState,
353
+ ): Readonly<TransmuterState> | null {
354
+ const amount: number = Number.parseFloat(
355
+ formatUnits(event.args.amount, 18),
356
+ );
357
+ const currentStablecoinEmission = state.totalStablecoinIssued;
358
+ for (const collat of Object.keys(state.collaterals)) {
359
+ state.collaterals[collat].stablecoinsIssued -=
360
+ (amount / currentStablecoinEmission) *
361
+ state.collaterals[collat].stablecoinsIssued;
362
+ }
363
+ state.totalStablecoinIssued -= amount;
364
+
365
+ return state;
366
+ }
367
+
368
+ _handleAddCollateral(
369
+ event: ethers.utils.LogDescription,
370
+ state: TransmuterState,
371
+ ): Readonly<TransmuterState> | null {
372
+ this.collaterals.push(event.args.collateral);
373
+ state.collaterals[event.args.collateral] = {} as CollateralState;
374
+ return state;
375
+ }
376
+
377
+ _handleRevokeCollateral(
378
+ event: ethers.utils.LogDescription,
379
+ state: TransmuterState,
380
+ ): Readonly<TransmuterState> | null {
381
+ const index = this.collaterals.indexOf(event.args.collateral);
382
+ if (index > -1) this.collaterals.splice(index, 1);
383
+ delete state.collaterals[event.args.collateral];
384
+
385
+ return state;
386
+ }
387
+
388
+ _handleAdjustStablecoins(
389
+ event: ethers.utils.LogDescription,
390
+ state: TransmuterState,
391
+ ): Readonly<TransmuterState> | null {
392
+ const collateral = event.args.collateral.toLowerCase();
393
+ const isIncrease: boolean = event.args.increase;
394
+ const amount: number =
395
+ Number.parseFloat(formatUnits(event.args.amount, 18)) *
396
+ Number(isIncrease);
397
+ state.totalStablecoinIssued += amount;
398
+ state.collaterals[collateral].stablecoinsIssued += amount;
399
+ return state;
400
+ }
401
+
402
+ _handleSetWhitelistedStatus(
403
+ event: ethers.utils.LogDescription,
404
+ state: TransmuterState,
405
+ ): Readonly<TransmuterState> | null {
406
+ const status: number = event.args.whitelistStatus;
407
+ const collateral: string = event.args.collateral;
408
+ const data: string = event.args.whitelistData;
409
+ if (!state.collaterals[collateral])
410
+ state.collaterals[collateral] = {} as CollateralState;
411
+ if (status === 1) state.collaterals[collateral].whitelist.data = data;
412
+ state.collaterals[collateral].whitelist.status = status > 0;
413
+ return state;
414
+ }
415
+
416
+ _handleIsWhitelistedForType(
417
+ event: ethers.utils.LogDescription,
418
+ state: TransmuterState,
419
+ ): Readonly<TransmuterState> | null {
420
+ const status: number = event.args.whitelistStatus;
421
+ const who: string = event.args.who;
422
+ const whitelistType: number = event.args.whitelistType;
423
+ if (!state.isWhitelisted[whitelistType])
424
+ state.isWhitelisted[whitelistType] = new Set();
425
+ if (status === 0 && state.isWhitelisted[whitelistType].has(who))
426
+ state.isWhitelisted[whitelistType].delete(who);
427
+ else if (status !== 0 && !state.isWhitelisted[whitelistType].has(who))
428
+ state.isWhitelisted[whitelistType].add(who);
429
+ return state;
430
+ }
431
+
432
+ _handleStablecoinCapSet(
433
+ event: ethers.utils.LogDescription,
434
+ state: TransmuterState,
435
+ ): Readonly<TransmuterState> | null {
436
+ const capAmount: number = event.args.stablecoinCap;
437
+ const collateral: string = event.args.collateral;
438
+ state.collaterals[collateral].stablecoinCap = capAmount;
439
+ return state;
440
+ }
441
+
442
+ /**
443
+ * Keep track of used oracles for each collaterals
444
+ */
445
+ _handleOracleSet(
446
+ event: ethers.utils.LogDescription,
447
+ state: TransmuterState,
448
+ blockNumber: number,
449
+ ): Readonly<TransmuterState> | null {
450
+ const collateral: string = event.args.collateral;
451
+ const oracleConfig: string = event.args.oracleConfig;
452
+
453
+ state.collaterals[collateral].config = this._setOracleConfig(oracleConfig);
454
+ return state;
455
+ }
456
+
457
+ /**
458
+ * Keep track of used oracles for each collaterals
459
+ */
460
+ _setOracleConfig(oracleConfig: string): Oracle {
461
+ const configOracle = {} as Oracle;
462
+ const oracleConfigDecoded =
463
+ TransmuterSubscriber._decodeOracleConfig(oracleConfig);
464
+
465
+ configOracle.oracleType = oracleConfigDecoded.oracleType;
466
+ configOracle.targetType = oracleConfigDecoded.targetType;
467
+ configOracle.hyperparameters = oracleConfigDecoded.hyperparameters;
468
+ if (oracleConfigDecoded.oracleType === OracleReadType.EXTERNAL) {
469
+ const externalOracle: Address = ethers.utils.defaultAbiCoder.decode(
470
+ [`address externalOracle`],
471
+ oracleConfigDecoded.oracleData,
472
+ )[0];
473
+ configOracle.externalOracle = externalOracle;
474
+ } else {
475
+ configOracle.oracleFeed = TransmuterSubscriber._decodeOracleFeed(
476
+ oracleConfigDecoded.oracleType,
477
+ oracleConfigDecoded.oracleData,
478
+ );
479
+ configOracle.targetFeed = TransmuterSubscriber._decodeOracleFeed(
480
+ oracleConfigDecoded.targetType,
481
+ oracleConfigDecoded.targetData,
482
+ );
483
+ }
484
+ return configOracle;
485
+ }
486
+
487
+ static _decodeOracleConfig(oracleConfig: string): DecodedOracleConfig {
488
+ const oracleConfigDecoded = filterDictionaryOnly(
489
+ ethers.utils.defaultAbiCoder.decode(
490
+ [
491
+ 'uint8 oracleType',
492
+ 'uint8 targetType',
493
+ 'bytes oracleData',
494
+ 'bytes targetData',
495
+ 'bytes hyperparameters',
496
+ ],
497
+ oracleConfig,
498
+ ),
499
+ ) as unknown as DecodedOracleConfig;
500
+
501
+ return oracleConfigDecoded;
502
+ }
503
+
504
+ static _decodeOracleFeed(
505
+ readType: OracleReadType,
506
+ oracleData: string,
507
+ ): OracleFeed {
508
+ if (readType === OracleReadType.CHAINLINK_FEEDS)
509
+ return {
510
+ isChainlink: true,
511
+ isPyth: false,
512
+ isMorpho: false,
513
+ chainlink: TransmuterSubscriber._decodeChainlinkOracle(oracleData),
514
+ };
515
+ if (readType === OracleReadType.PYTH)
516
+ return {
517
+ isChainlink: false,
518
+ isPyth: true,
519
+ isMorpho: false,
520
+ pyth: TransmuterSubscriber._decodePythOracle(oracleData),
521
+ };
522
+ if (readType === OracleReadType.MAX)
523
+ return {
524
+ isChainlink: false,
525
+ isPyth: false,
526
+ isMorpho: false,
527
+ maxValue: TransmuterSubscriber._decodeMaxOracle(oracleData),
528
+ };
529
+ if (readType === OracleReadType.MORPHO_ORACLE)
530
+ return {
531
+ isChainlink: false,
532
+ isPyth: false,
533
+ isMorpho: true,
534
+ morpho: TransmuterSubscriber._decodeMorphoOracle(oracleData),
535
+ };
536
+ if (readType === OracleReadType.WSTETH)
537
+ return {
538
+ isChainlink: false,
539
+ isPyth: false,
540
+ isMorpho: false,
541
+ otherContract: STETH,
542
+ };
543
+ if (readType === OracleReadType.CBETH)
544
+ return {
545
+ isChainlink: false,
546
+ isPyth: false,
547
+ isMorpho: false,
548
+ otherContract: CBETH,
549
+ };
550
+ if (readType === OracleReadType.RETH)
551
+ return {
552
+ isChainlink: false,
553
+ isPyth: false,
554
+ isMorpho: false,
555
+ otherContract: RETH,
556
+ };
557
+ if (readType === OracleReadType.SFRXETH)
558
+ return {
559
+ isChainlink: false,
560
+ isPyth: false,
561
+ isMorpho: false,
562
+ otherContract: SFRXETH,
563
+ };
564
+ return { isChainlink: false, isPyth: false, isMorpho: false };
565
+ }
566
+
567
+ static _decodeChainlinkOracle(oracleData: string): Chainlink {
568
+ const chainlinkOracleDecoded = filterDictionaryOnly(
569
+ ethers.utils.defaultAbiCoder.decode(
570
+ [
571
+ 'address[] circuitChainlink',
572
+ 'uint32[] stalePeriods',
573
+ 'uint8[] circuitChainIsMultiplied',
574
+ 'uint8[] chainlinkDecimals',
575
+ 'uint8 quoteType',
576
+ ],
577
+ oracleData,
578
+ ),
579
+ ) as unknown as Chainlink;
580
+
581
+ return chainlinkOracleDecoded;
582
+ }
583
+
584
+ static _decodePythOracle(oracleData: string): Pyth {
585
+ const pythOracleDecoded = filterDictionaryOnly(
586
+ ethers.utils.defaultAbiCoder.decode(
587
+ [
588
+ 'address pyth',
589
+ 'bytes32[] feedIds',
590
+ 'uint32[] stalePeriods',
591
+ 'uint8[] isMultiplied',
592
+ 'uint8 quoteType',
593
+ ],
594
+ oracleData,
595
+ ),
596
+ ) as unknown as Pyth;
597
+
598
+ return pythOracleDecoded;
599
+ }
600
+
601
+ static _decodeMaxOracle(oracleData: string): number {
602
+ const maxOracleDecoded = filterDictionaryOnly(
603
+ ethers.utils.defaultAbiCoder.decode(['uint256 maxValue'], oracleData),
604
+ ) as unknown as MaxOracle;
605
+
606
+ return Number.parseFloat(formatEther(maxOracleDecoded.maxValue));
607
+ }
608
+
609
+ static _decodeMorphoOracle(oracleData: string): MorphoOracle {
610
+ const morphoOracleDecoded = filterDictionaryOnly(
611
+ ethers.utils.defaultAbiCoder.decode(
612
+ ['address oracle', 'uint256 normalizationFactor'],
613
+ oracleData,
614
+ ),
615
+ ) as unknown as MorphoOracle;
616
+
617
+ return morphoOracleDecoded;
618
+ }
619
+ }