@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,335 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import type { DeepReadonly } from 'ts-essentials';
3
+ import type {
4
+ BlockHeader,
5
+ Log,
6
+ Logger,
7
+ MultiCallInput,
8
+ MultiCallOutput,
9
+ } from '../../types';
10
+ import { bigIntify, catchParseLogError } from '../../utils';
11
+ import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
12
+ import type { IDexHelper } from '../../dex-helper/idex-helper';
13
+ import type { MorphoOracleState } from './types';
14
+ import MorphoOracleABI from '../../abi/angle-transmuter/MorphoOracle.json';
15
+ import ERC20ABI from '../../abi/erc20.json';
16
+
17
+ export class MorphoOracleEventPool extends StatefulEventSubscriber<MorphoOracleState> {
18
+ handlers: {
19
+ [event: string]: (
20
+ event: any,
21
+ state: DeepReadonly<MorphoOracleState>,
22
+ log: Readonly<Log>,
23
+ blockHeader: Readonly<BlockHeader>,
24
+ ) => DeepReadonly<MorphoOracleState> | null;
25
+ } = {};
26
+
27
+ static morphoOracleIface = new Interface(MorphoOracleABI);
28
+ static erc20Iface = new Interface(ERC20ABI);
29
+
30
+ logDecoder: (log: Log) => any;
31
+
32
+ addressesSubscribed: string[];
33
+
34
+ constructor(
35
+ readonly parentName: string,
36
+ protected network: number,
37
+ protected dexHelper: IDexHelper,
38
+ public morphoOracle: string,
39
+ logger: Logger,
40
+ ) {
41
+ super(parentName, 'Morpho_Oracle', dexHelper, logger);
42
+
43
+ this.logDecoder = (log: Log) =>
44
+ MorphoOracleEventPool.morphoOracleIface.parseLog(log);
45
+ this.addressesSubscribed = [morphoOracle];
46
+ }
47
+
48
+ /**
49
+ * The function is called every time any of the subscribed
50
+ * addresses release log. The function accepts the current
51
+ * state, updates the state according to the log, and returns
52
+ * the updated state.
53
+ * @param state - Current state of event subscriber
54
+ * @param log - Log released by one of the subscribed addresses
55
+ * @returns Updates state of the event subscriber after the log
56
+ */
57
+ protected processLog(
58
+ state: DeepReadonly<MorphoOracleState>,
59
+ log: Readonly<Log>,
60
+ blockHeader: Readonly<BlockHeader>,
61
+ ): DeepReadonly<MorphoOracleState> | null {
62
+ try {
63
+ const event = this.logDecoder(log);
64
+ if (event.name in this.handlers) {
65
+ return this.handlers[event.name](event, state, log, blockHeader);
66
+ }
67
+ } catch (e) {
68
+ catchParseLogError(e, this.logger);
69
+ }
70
+
71
+ return null;
72
+ }
73
+
74
+ /**
75
+ * The function generates state using on-chain calls. This
76
+ * function is called to regenerate state if the event based
77
+ * system fails to fetch events and the local state is no
78
+ * more correct.
79
+ * @param blockNumber - Blocknumber for which the state should
80
+ * should be generated
81
+ * @returns state of the event subscriber at blocknumber
82
+ */
83
+ public async generateState(
84
+ blockNumber: number,
85
+ ): Promise<DeepReadonly<MorphoOracleState>> {
86
+ const poolState = {} as MorphoOracleState;
87
+
88
+ const multicall = [
89
+ {
90
+ target: this.morphoOracle,
91
+ callData:
92
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
93
+ 'BASE_VAULT',
94
+ ),
95
+ },
96
+ {
97
+ target: this.morphoOracle,
98
+ callData: MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
99
+ 'BASE_VAULT_CONVERSION_SAMPLE',
100
+ ),
101
+ },
102
+ {
103
+ target: this.morphoOracle,
104
+ callData:
105
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
106
+ 'QUOTE_VAULT',
107
+ ),
108
+ },
109
+ {
110
+ target: this.morphoOracle,
111
+ callData: MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
112
+ 'QUOTE_VAULT_CONVERSION_SAMPLE',
113
+ ),
114
+ },
115
+ {
116
+ target: this.morphoOracle,
117
+ callData:
118
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
119
+ 'BASE_FEED_1',
120
+ ),
121
+ },
122
+ {
123
+ target: this.morphoOracle,
124
+ callData:
125
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
126
+ 'BASE_FEED_2',
127
+ ),
128
+ },
129
+ {
130
+ target: this.morphoOracle,
131
+ callData:
132
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
133
+ 'QUOTE_FEED_1',
134
+ ),
135
+ },
136
+ {
137
+ target: this.morphoOracle,
138
+ callData:
139
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
140
+ 'QUOTE_FEED_1',
141
+ ),
142
+ },
143
+ {
144
+ target: this.morphoOracle,
145
+ callData:
146
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
147
+ 'SCALE_FACTOR',
148
+ ),
149
+ },
150
+ ];
151
+
152
+ // on chain call
153
+ const returnData = (
154
+ await this.dexHelper.multiContract.methods
155
+ .aggregate(multicall)
156
+ .call({}, blockNumber)
157
+ ).returnData;
158
+
159
+ // Decode
160
+ poolState.baseVault =
161
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
162
+ 'BASE_VAULT',
163
+ returnData[0],
164
+ )[0] as string;
165
+ poolState.baseVaultConversion = bigIntify(
166
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
167
+ 'BASE_VAULT_CONVERSION_SAMPLE',
168
+ returnData[1],
169
+ )[0],
170
+ );
171
+ poolState.quoteVault =
172
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
173
+ 'QUOTE_VAULT',
174
+ returnData[2],
175
+ )[0] as string;
176
+ poolState.quoteVaultConversion = bigIntify(
177
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
178
+ 'QUOTE_VAULT_CONVERSION_SAMPLE',
179
+ returnData[3],
180
+ )[0],
181
+ );
182
+ poolState.baseFeed1 =
183
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
184
+ 'BASE_FEED_1',
185
+ returnData[4],
186
+ )[0] as string;
187
+ poolState.baseFeed2 =
188
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
189
+ 'BASE_FEED_2',
190
+ returnData[5],
191
+ )[0] as string;
192
+ poolState.quoteFeed1 =
193
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
194
+ 'QUOTE_FEED_1',
195
+ returnData[6],
196
+ )[0] as string;
197
+ poolState.quoteFeed2 =
198
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
199
+ 'QUOTE_FEED_2',
200
+ returnData[7],
201
+ )[0] as string;
202
+ poolState.scaleFactor = bigIntify(
203
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
204
+ 'SCALE_FACTOR',
205
+ returnData[8],
206
+ )[0],
207
+ );
208
+
209
+ return poolState;
210
+ }
211
+
212
+ static getGenerateInfoMultiCallInput(morphoOracle: string): MultiCallInput[] {
213
+ return [
214
+ {
215
+ target: morphoOracle,
216
+ callData:
217
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
218
+ 'BASE_VAULT',
219
+ ),
220
+ },
221
+ {
222
+ target: morphoOracle,
223
+ callData: MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
224
+ 'BASE_VAULT_CONVERSION_SAMPLE',
225
+ ),
226
+ },
227
+ {
228
+ target: morphoOracle,
229
+ callData:
230
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
231
+ 'QUOTE_VAULT',
232
+ ),
233
+ },
234
+ {
235
+ target: morphoOracle,
236
+ callData: MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
237
+ 'QUOTE_VAULT_CONVERSION_SAMPLE',
238
+ ),
239
+ },
240
+ {
241
+ target: morphoOracle,
242
+ callData:
243
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
244
+ 'BASE_FEED_1',
245
+ ),
246
+ },
247
+ {
248
+ target: morphoOracle,
249
+ callData:
250
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
251
+ 'BASE_FEED_2',
252
+ ),
253
+ },
254
+ {
255
+ target: morphoOracle,
256
+ callData:
257
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
258
+ 'QUOTE_FEED_1',
259
+ ),
260
+ },
261
+ {
262
+ target: morphoOracle,
263
+ callData:
264
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
265
+ 'QUOTE_FEED_1',
266
+ ),
267
+ },
268
+ {
269
+ target: morphoOracle,
270
+ callData:
271
+ MorphoOracleEventPool.morphoOracleIface.encodeFunctionData(
272
+ 'SCALE_FACTOR',
273
+ ),
274
+ },
275
+ ];
276
+ }
277
+
278
+ static generateInfo(
279
+ multicallOutputs: MultiCallOutput[],
280
+ ): DeepReadonly<MorphoOracleState> {
281
+ const poolState = {} as MorphoOracleState;
282
+
283
+ // Decode
284
+ poolState.baseVault =
285
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
286
+ 'BASE_VAULT',
287
+ multicallOutputs[0],
288
+ )[0] as string;
289
+ poolState.baseVaultConversion = bigIntify(
290
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
291
+ 'BASE_VAULT_CONVERSION_SAMPLE',
292
+ multicallOutputs[1],
293
+ )[0],
294
+ );
295
+ poolState.quoteVault =
296
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
297
+ 'QUOTE_VAULT',
298
+ multicallOutputs[2],
299
+ )[0] as string;
300
+ poolState.quoteVaultConversion = bigIntify(
301
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
302
+ 'QUOTE_VAULT_CONVERSION_SAMPLE',
303
+ multicallOutputs[3],
304
+ )[0],
305
+ );
306
+ poolState.baseFeed1 =
307
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
308
+ 'BASE_FEED_1',
309
+ multicallOutputs[4],
310
+ )[0] as string;
311
+ poolState.baseFeed2 =
312
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
313
+ 'BASE_FEED_2',
314
+ multicallOutputs[5],
315
+ )[0] as string;
316
+ poolState.quoteFeed1 =
317
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
318
+ 'QUOTE_FEED_1',
319
+ multicallOutputs[6],
320
+ )[0] as string;
321
+ poolState.quoteFeed2 =
322
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
323
+ 'QUOTE_FEED_2',
324
+ multicallOutputs[7],
325
+ )[0] as string;
326
+ poolState.scaleFactor = bigIntify(
327
+ MorphoOracleEventPool.morphoOracleIface.decodeFunctionResult(
328
+ 'SCALE_FACTOR',
329
+ multicallOutputs[8],
330
+ )[0],
331
+ );
332
+
333
+ return poolState;
334
+ }
335
+ }
@@ -0,0 +1,134 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import type { DeepReadonly } from 'ts-essentials';
3
+ import type {
4
+ BlockHeader,
5
+ Log,
6
+ Logger,
7
+ MultiCallInput,
8
+ MultiCallOutput,
9
+ } from '../../types';
10
+ import { bigIntify } from '../../utils';
11
+ import type { MorphoVaultState } from './types';
12
+ import MorphoVaultABI from '../../abi/angle-transmuter/MorphoVault.json';
13
+ import { PartialEventSubscriber } from '../../composed-event-subscriber';
14
+ import { Lens } from '../../lens';
15
+ import _ from 'lodash';
16
+ import { ethers } from 'ethers';
17
+
18
+ export class MorphoVaultSubscriber<State> extends PartialEventSubscriber<
19
+ State,
20
+ MorphoVaultState
21
+ > {
22
+ static interface = new Interface(MorphoVaultABI);
23
+
24
+ constructor(
25
+ public morphoVault: string,
26
+ lens: Lens<DeepReadonly<State>, DeepReadonly<MorphoVaultState>>,
27
+ logger: Logger,
28
+ ) {
29
+ super([morphoVault], lens, logger);
30
+ }
31
+
32
+ public processLog(
33
+ state: DeepReadonly<MorphoVaultState>,
34
+ log: Readonly<Log>,
35
+ blockHeader: Readonly<BlockHeader>,
36
+ ): DeepReadonly<MorphoVaultState> | null {
37
+ try {
38
+ const parsed = MorphoVaultSubscriber.interface.parseLog(log);
39
+ const _state: MorphoVaultState = _.cloneDeep(state) as MorphoVaultState;
40
+ switch (parsed.name) {
41
+ case 'UpdateLastTotalAssets':
42
+ return this.handleUpdateLastTotalAssets(parsed, _state);
43
+ case 'AccrueInterest':
44
+ return this.handleAccrueFee(parsed, _state);
45
+ case 'Deposit':
46
+ return this.handleDeposit(parsed, _state);
47
+ case 'Withdraw':
48
+ return this.handleWithdraw(parsed, _state);
49
+ default:
50
+ return null;
51
+ }
52
+ } catch (e) {
53
+ this.logger.error('Failed to parse log', e);
54
+ return null;
55
+ }
56
+ }
57
+
58
+ public getGenerateStateMultiCallInputs(): MultiCallInput[] {
59
+ return [
60
+ {
61
+ target: this.morphoVault,
62
+ callData:
63
+ MorphoVaultSubscriber.interface.encodeFunctionData('totalAssets'),
64
+ },
65
+ {
66
+ target: this.morphoVault,
67
+ callData:
68
+ MorphoVaultSubscriber.interface.encodeFunctionData('totalSupply'),
69
+ },
70
+ ];
71
+ }
72
+
73
+ public generateState(
74
+ multicallOutputs: MultiCallOutput[],
75
+ blockNumber?: number | 'latest',
76
+ ): DeepReadonly<MorphoVaultState> {
77
+ const morphoVaultState = {} as MorphoVaultState;
78
+
79
+ // Decode
80
+ morphoVaultState.totalAssets = bigIntify(
81
+ MorphoVaultSubscriber.interface.decodeFunctionResult(
82
+ 'totalAssets',
83
+ multicallOutputs[0],
84
+ )[0],
85
+ );
86
+ morphoVaultState.totalSupply = bigIntify(
87
+ MorphoVaultSubscriber.interface.decodeFunctionResult(
88
+ 'totalSupply',
89
+ multicallOutputs[1],
90
+ )[0],
91
+ );
92
+ return morphoVaultState;
93
+ }
94
+
95
+ getRate(amount: bigint, state: MorphoVaultState): bigint {
96
+ return amount === 0n || state.totalSupply === 0n
97
+ ? amount
98
+ : (amount * state.totalSupply) / state.totalAssets;
99
+ }
100
+
101
+ handleUpdateLastTotalAssets(
102
+ event: ethers.utils.LogDescription,
103
+ state: MorphoVaultState,
104
+ ): DeepReadonly<MorphoVaultState> | null {
105
+ state.totalAssets = bigIntify(event.args.updatedTotalAssets);
106
+ return state;
107
+ }
108
+
109
+ handleAccrueFee(
110
+ event: ethers.utils.LogDescription,
111
+ state: MorphoVaultState,
112
+ ): DeepReadonly<MorphoVaultState> | null {
113
+ state.totalSupply += bigIntify(event.args.feeShares);
114
+ return state;
115
+ }
116
+
117
+ handleDeposit(
118
+ event: ethers.utils.LogDescription,
119
+ state: MorphoVaultState,
120
+ ): DeepReadonly<MorphoVaultState> | null {
121
+ const shares = bigIntify(event.args.shares);
122
+ state.totalSupply += shares;
123
+ return state;
124
+ }
125
+
126
+ handleWithdraw(
127
+ event: ethers.utils.LogDescription,
128
+ state: MorphoVaultState,
129
+ ): DeepReadonly<MorphoVaultState> | null {
130
+ const shares = bigIntify(event.args.shares);
131
+ state.totalSupply -= shares;
132
+ return state;
133
+ }
134
+ }
@@ -0,0 +1,105 @@
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 PythABI from '../../abi/angle-transmuter/Pyth.json';
14
+ import _ from 'lodash';
15
+ import { formatUnits, parseUnits } from 'ethers/lib/utils';
16
+ import { BigNumber } from 'ethers';
17
+ import { PythState } from './types';
18
+
19
+ export class PythSubscriber<State> extends PartialEventSubscriber<
20
+ State,
21
+ PythState
22
+ > {
23
+ static readonly proxyInterface = new Interface(PythABI);
24
+ static readonly ANSWER_UPDATED_TOPIC =
25
+ PythSubscriber.proxyInterface.getEventTopic('PriceFeedUpdate');
26
+
27
+ constructor(
28
+ private proxy: Address,
29
+ private oracleIds: string[],
30
+ lens: Lens<DeepReadonly<State>, DeepReadonly<PythState>>,
31
+ logger: Logger,
32
+ ) {
33
+ super([proxy], lens, logger);
34
+ }
35
+
36
+ public processLog(
37
+ state: DeepReadonly<PythState>,
38
+ log: Readonly<Log>,
39
+ blockHeader: Readonly<BlockHeader>,
40
+ ): DeepReadonly<PythState> | null {
41
+ if (log.topics[0] !== PythSubscriber.ANSWER_UPDATED_TOPIC) return null; // Ignore other events
42
+ const decoded = PythSubscriber.proxyInterface.decodeEventLog(
43
+ 'PriceFeedUpdate',
44
+ log.data,
45
+ log.topics,
46
+ );
47
+ if (this.oracleIds.indexOf(decoded.id) === -1) return null;
48
+ const _state = _.cloneDeep(state) as PythState;
49
+ const expo = _state[decoded.id].expo;
50
+ _state[decoded.id] = {
51
+ answer: this._processPrice(decoded.price, expo),
52
+ expo: expo,
53
+ timestamp: Number(decoded.publishTime),
54
+ };
55
+ return _state;
56
+ }
57
+
58
+ public getGenerateStateMultiCallInputs(): MultiCallInput[] {
59
+ const oraclesMultiCalls = this.oracleIds.map(id => {
60
+ return {
61
+ target: this.proxy,
62
+ callData: PythSubscriber.proxyInterface.encodeFunctionData(
63
+ 'getPriceUnsafe',
64
+ [id],
65
+ ),
66
+ };
67
+ });
68
+ return oraclesMultiCalls;
69
+ }
70
+
71
+ public generateState(
72
+ multicallOutputs: MultiCallOutput[],
73
+ blockNumber?: number | 'latest',
74
+ ): DeepReadonly<PythState> {
75
+ const decodedOracle = multicallOutputs.map(call => {
76
+ return PythSubscriber.proxyInterface.decodeFunctionResult(
77
+ 'getPriceUnsafe',
78
+ call,
79
+ )[0];
80
+ });
81
+ const _state = {} as PythState;
82
+ this.oracleIds.map((id, index) => {
83
+ const expo = decodedOracle[index].expo;
84
+ _state[id] = {
85
+ answer: this._processPrice(decodedOracle[index].price, expo),
86
+ expo: expo,
87
+ timestamp: Number(decodedOracle[index].publishTime),
88
+ };
89
+ });
90
+ return _state;
91
+ }
92
+
93
+ public getLatestRoundData(
94
+ state: DeepReadonly<State>,
95
+ oracleId: string,
96
+ ): number {
97
+ return this.lens.get()(state)[oracleId].answer;
98
+ }
99
+
100
+ public _processPrice(price: BigNumber, expo: number): number {
101
+ const isNormalizerExpoNeg = expo < 0;
102
+ if (isNormalizerExpoNeg) return Number(formatUnits(price, -expo));
103
+ return Number(parseUnits(price.toString(), expo));
104
+ }
105
+ }
@@ -0,0 +1,105 @@
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/Redstone.json';
14
+ import { ChainLinkState } from '../../lib/chainlink';
15
+
16
+ export class RedstoneSubscriber<State> extends PartialEventSubscriber<
17
+ State,
18
+ ChainLinkState
19
+ > {
20
+ static readonly proxyInterface = new Interface(ProxyABI);
21
+ // static readonly ANSWER_UPDATED_TOPIC =
22
+ // RedstoneSubscriber.proxyInterface.getEventTopic('');
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 getReadAggregatorMultiCallInput(proxy: Address): MultiCallInput {
34
+ return {
35
+ target: proxy,
36
+ callData: RedstoneSubscriber.proxyInterface.encodeFunctionData(
37
+ 'getPriceFeedAdapter',
38
+ ),
39
+ };
40
+ }
41
+
42
+ static readAggregator(multicallOutput: MultiCallOutput): Address {
43
+ return RedstoneSubscriber.proxyInterface.decodeFunctionResult(
44
+ 'getPriceFeedAdapter',
45
+ multicallOutput,
46
+ )[0];
47
+ }
48
+
49
+ static getReadDecimal(proxy: Address): MultiCallInput {
50
+ return {
51
+ target: proxy,
52
+ callData:
53
+ RedstoneSubscriber.proxyInterface.encodeFunctionData('decimals'),
54
+ };
55
+ }
56
+
57
+ static readDecimals(multicallOutput: MultiCallOutput): Address {
58
+ return RedstoneSubscriber.proxyInterface.decodeFunctionResult(
59
+ 'decimals',
60
+ multicallOutput,
61
+ )[0];
62
+ }
63
+
64
+ public processLog(
65
+ state: DeepReadonly<ChainLinkState>,
66
+ log: Readonly<Log>,
67
+ blockHeader: Readonly<BlockHeader>,
68
+ ): DeepReadonly<ChainLinkState> | null {
69
+ // No events with updated info, this is placeholder
70
+ return {
71
+ answer: BigInt('1000000'),
72
+ timestamp: BigInt('1000000'),
73
+ };
74
+ }
75
+
76
+ public getGenerateStateMultiCallInputs(): MultiCallInput[] {
77
+ return [
78
+ {
79
+ target: this.proxy,
80
+ callData:
81
+ RedstoneSubscriber.proxyInterface.encodeFunctionData(
82
+ 'latestRoundData',
83
+ ),
84
+ },
85
+ ];
86
+ }
87
+
88
+ public generateState(
89
+ multicallOutputs: MultiCallOutput[],
90
+ blockNumber?: number | 'latest',
91
+ ): DeepReadonly<ChainLinkState> {
92
+ const decoded = RedstoneSubscriber.proxyInterface.decodeFunctionResult(
93
+ 'latestRoundData',
94
+ multicallOutputs[0],
95
+ );
96
+ return {
97
+ answer: BigInt(decoded.answer.toString()),
98
+ timestamp: BigInt(decoded.updatedAt.toString()),
99
+ };
100
+ }
101
+
102
+ public getLatestRoundData(state: DeepReadonly<State>): bigint {
103
+ return this.lens.get()(state).answer;
104
+ }
105
+ }