@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,203 @@
1
+ import { BigNumber } from 'ethers';
2
+ import { Address, Token } from '../../types';
3
+ import { ChainLinkState } from '../../lib/chainlink';
4
+
5
+ export type PoolState = {
6
+ stablecoin: Token;
7
+ transmuter: TransmuterState;
8
+ oracles: {
9
+ chainlink: { [address: string]: ChainLinkState };
10
+ pyth: PythState;
11
+ morphoVault: { [address: string]: MorphoVaultState };
12
+ };
13
+ };
14
+
15
+ export type CollateralState = {
16
+ whitelist: { status: boolean; data: string };
17
+ fees: Fees;
18
+ stablecoinsIssued: number;
19
+ config: Oracle;
20
+ stablecoinCap: number;
21
+ };
22
+
23
+ export type TransmuterState = {
24
+ collaterals: {
25
+ [token: string]: CollateralState;
26
+ };
27
+ isWhitelisted: {
28
+ [type: number]: Set<string>;
29
+ };
30
+ xRedemptionCurve: number[];
31
+ yRedemptionCurve: number[];
32
+ totalStablecoinIssued: number;
33
+ };
34
+
35
+ export type ChainlinkConfig = {
36
+ [address: string]: { proxy: Address; aggregator: Address; decimals: number };
37
+ };
38
+
39
+ export type PythConfig = { proxy: Address; ids: string[] };
40
+
41
+ export type MorphoConfig = {
42
+ [address: string]: MorphoOracleState;
43
+ };
44
+
45
+ export type PoolConfig = {
46
+ stablecoin: Token;
47
+ transmuter: Address;
48
+ collaterals: Address[];
49
+ oracles: {
50
+ chainlink: ChainlinkConfig;
51
+ backed: ChainlinkConfig;
52
+ redstone: ChainlinkConfig;
53
+ pyth: PythConfig;
54
+ morpho: MorphoConfig;
55
+ };
56
+ };
57
+
58
+ export type MorphoVaultState = {
59
+ totalAssets: bigint;
60
+ totalSupply: bigint;
61
+ };
62
+
63
+ export type MorphoOracleState = {
64
+ baseVault: Address;
65
+ baseVaultConversion: bigint;
66
+ quoteVault: Address;
67
+ quoteVaultConversion: bigint;
68
+ baseFeed1: Address;
69
+ baseFeed2: Address;
70
+ quoteFeed1: Address;
71
+ quoteFeed2: Address;
72
+ scaleFactor: bigint;
73
+ };
74
+
75
+ export type ChainlinkState = {
76
+ answer: number;
77
+ timestamp: number;
78
+ };
79
+
80
+ export type PythState = {
81
+ [address: string]: {
82
+ answer: number;
83
+ expo: number;
84
+ timestamp: number;
85
+ };
86
+ };
87
+
88
+ export type AngleTransmuterData = {
89
+ exchange: Address;
90
+ };
91
+
92
+ export type TransmuterParams = {
93
+ stablecoin: Token;
94
+ transmuter: Address;
95
+ pyth: Address;
96
+ };
97
+ export type DexParams = {
98
+ EUR?: TransmuterParams;
99
+ USD?: TransmuterParams;
100
+ };
101
+
102
+ export enum QuoteType {
103
+ MintExactInput = 0,
104
+ MintExactOutput = 1,
105
+ BurnExactInput = 2,
106
+ BurnExactOutput = 3,
107
+ }
108
+
109
+ export enum OracleReadType {
110
+ CHAINLINK_FEEDS = 0,
111
+ EXTERNAL = 1,
112
+ NO_ORACLE = 2,
113
+ STABLE = 3,
114
+ WSTETH = 4,
115
+ CBETH = 5,
116
+ RETH = 6,
117
+ SFRXETH = 7,
118
+ PYTH = 8,
119
+ MAX = 9,
120
+ MORPHO_ORACLE = 10,
121
+ }
122
+
123
+ export enum OracleQuoteType {
124
+ UNIT = 0,
125
+ TARGET = 1,
126
+ }
127
+
128
+ export type Fees = {
129
+ xFeeMint: number[];
130
+ yFeeMint: number[];
131
+ xFeeBurn: number[];
132
+ yFeeBurn: number[];
133
+ };
134
+
135
+ export type Pyth = {
136
+ pyth: Address;
137
+ feedIds: string[];
138
+ stalePeriods: number[];
139
+ isMultiplied: number[];
140
+ quoteType: OracleQuoteType;
141
+ };
142
+
143
+ export type Chainlink = {
144
+ circuitChainlink: Address[];
145
+ stalePeriods: number[];
146
+ circuitChainIsMultiplied: number[];
147
+ chainlinkDecimals: number[];
148
+ quoteType: OracleQuoteType;
149
+ };
150
+
151
+ export type MorphoOracle = {
152
+ oracle: Address;
153
+ normalizationFactor: BigNumber;
154
+ };
155
+
156
+ export type MaxOracle = {
157
+ maxValue: number;
158
+ };
159
+
160
+ export type OracleFeed = {
161
+ isChainlink: boolean;
162
+ isPyth: boolean;
163
+ isMorpho: boolean;
164
+ chainlink?: Chainlink;
165
+ pyth?: Pyth;
166
+ morpho?: MorphoOracle;
167
+ otherContract?: Address;
168
+ maxValue?: number;
169
+ };
170
+
171
+ export type Oracle = {
172
+ oracleType: OracleReadType;
173
+ targetType: OracleReadType;
174
+ externalOracle?: Address;
175
+ oracleFeed: OracleFeed;
176
+ targetFeed: OracleFeed;
177
+ hyperparameters: string;
178
+ };
179
+
180
+ export type DecodedOracleConfig = {
181
+ oracleType: OracleReadType;
182
+ targetType: OracleReadType;
183
+ oracleData: string;
184
+ targetData: string;
185
+ hyperparameters: string;
186
+ };
187
+
188
+ export type OracleHyperparameter = {
189
+ userDeviation: BigNumber;
190
+ burnRatioDeviation: BigNumber;
191
+ };
192
+
193
+ export type DecodedStateMultiCallResultPythOracle = {
194
+ price: BigNumber;
195
+ conf: number;
196
+ expo: number;
197
+ publishTime: number;
198
+ };
199
+
200
+ export const BASE_9 = 1; // 1e9
201
+ export const BASE_12 = 1e3; // 1e12
202
+
203
+ export const MAX_BURN_FEE = 0.999; // 999_000_000
@@ -0,0 +1,358 @@
1
+ import { BASE_12, BASE_9, Fees, MAX_BURN_FEE, QuoteType } from './types';
2
+
3
+ /// @notice Computes the `amountOut` of stablecoins to mint from `tokenIn` of a collateral with data `collatInfo`
4
+ export function _quoteMintExactInput(
5
+ oracleValue: number,
6
+ amountIn: number,
7
+ fees: Fees,
8
+ stablecoinsIssued: number,
9
+ otherStablecoinSupply: number,
10
+ stablecoinCap: number,
11
+ ): number {
12
+ let amountOut = oracleValue * amountIn;
13
+ amountOut = _quoteFees(
14
+ fees,
15
+ QuoteType.MintExactInput,
16
+ amountOut,
17
+ stablecoinsIssued,
18
+ otherStablecoinSupply,
19
+ );
20
+ if (stablecoinCap >= 0 && amountOut + stablecoinsIssued > stablecoinCap)
21
+ throw new Error('InvalidSwap');
22
+ return amountOut;
23
+ }
24
+
25
+ /// @notice Computes the `amountIn` of collateral to get during a mint of `amountOut` of stablecoins
26
+ export function _quoteMintExactOutput(
27
+ oracleValue: number,
28
+ amountOut: number,
29
+ fees: Fees,
30
+ stablecoinsIssued: number,
31
+ otherStablecoinSupply: number,
32
+ stablecoinCap: number,
33
+ ): number {
34
+ if (stablecoinCap >= 0 && amountOut + stablecoinsIssued > stablecoinCap)
35
+ throw new Error('InvalidSwap');
36
+ const amountIn = _quoteFees(
37
+ fees,
38
+ QuoteType.MintExactOutput,
39
+ amountOut,
40
+ stablecoinsIssued,
41
+ otherStablecoinSupply,
42
+ );
43
+ return amountIn / oracleValue;
44
+ }
45
+
46
+ /// @notice Computes the `amountIn` of stablecoins to burn to release `amountOut` of `collateral`
47
+ export function _quoteBurnExactOutput(
48
+ oracleValue: number,
49
+ ratio: number,
50
+ amountOut: number,
51
+ fees: Fees,
52
+ stablecoinsIssued: number,
53
+ otherStablecoinSupply: number,
54
+ ): number {
55
+ const amountIn = (amountOut * oracleValue) / ratio;
56
+ return _quoteFees(
57
+ fees,
58
+ QuoteType.BurnExactOutput,
59
+ amountIn,
60
+ stablecoinsIssued,
61
+ otherStablecoinSupply,
62
+ );
63
+ }
64
+
65
+ /// @notice Computes the `amountOut` of `collateral` to give during a burn operation of `amountIn` of stablecoins
66
+ export function _quoteBurnExactInput(
67
+ oracleValue: number,
68
+ ratio: number,
69
+ amountIn: number,
70
+ fees: Fees,
71
+ stablecoinsIssued: number,
72
+ otherStablecoinSupply: number,
73
+ ): number {
74
+ const amountOut = _quoteFees(
75
+ fees,
76
+ QuoteType.BurnExactInput,
77
+ amountIn,
78
+ stablecoinsIssued,
79
+ otherStablecoinSupply,
80
+ );
81
+ return (amountOut * ratio) / oracleValue;
82
+ }
83
+
84
+ export function _quoteFees(
85
+ fees: Fees,
86
+ quoteType: QuoteType,
87
+ amountStable: number,
88
+ stablecoinsIssued: number,
89
+ otherStablecoinSupply: number,
90
+ ): number {
91
+ const isMint = _isMint(quoteType);
92
+ const isExact = _isExact(quoteType);
93
+
94
+ const n = isMint ? fees.xFeeMint.length : fees.xFeeBurn.length;
95
+
96
+ let currentExposure =
97
+ (stablecoinsIssued * BASE_9) / (otherStablecoinSupply + stablecoinsIssued);
98
+
99
+ let amount = 0;
100
+
101
+ // Finding in which segment the current exposure to the collateral is
102
+ let i = findLowerBound(
103
+ isMint,
104
+ isMint ? fees.xFeeMint : fees.xFeeBurn,
105
+ BASE_9,
106
+ currentExposure,
107
+ );
108
+
109
+ let lowerExposure: number;
110
+ let upperExposure: number;
111
+ let lowerFees: number;
112
+ let upperFees: number;
113
+ let amountToNextBreakPoint: number;
114
+
115
+ while (i < n - 1) {
116
+ // We compute a linear by part function on the amount swapped
117
+ // The `amountToNextBreakPoint` variable is the `b_{i+1}` value from the whitepaper
118
+ if (isMint) {
119
+ lowerExposure = fees.xFeeMint[i];
120
+ upperExposure = fees.xFeeMint[i + 1];
121
+ lowerFees = fees.yFeeMint[i];
122
+ upperFees = fees.yFeeMint[i + 1];
123
+ amountToNextBreakPoint =
124
+ (otherStablecoinSupply * upperExposure) / (BASE_9 - upperExposure) -
125
+ stablecoinsIssued;
126
+ } else {
127
+ // The exposures in the burn case are decreasing
128
+ lowerExposure = fees.xFeeBurn[i];
129
+ upperExposure = fees.xFeeBurn[i + 1];
130
+ lowerFees = fees.yFeeBurn[i];
131
+ upperFees = fees.yFeeBurn[i + 1];
132
+ // The `b_{i+1}` value in the burn case is the opposite value of the mint case
133
+ amountToNextBreakPoint =
134
+ stablecoinsIssued -
135
+ (otherStablecoinSupply * upperExposure) / (BASE_9 - upperExposure);
136
+ }
137
+
138
+ let currentFees: number;
139
+ if (lowerExposure * BASE_9 === currentExposure) {
140
+ currentFees = lowerFees;
141
+ } else if (lowerFees === upperFees) {
142
+ currentFees = lowerFees;
143
+ } else {
144
+ // This is the opposite of the `b_i` value from the whitepaper.
145
+ const amountFromPrevBreakPoint = isMint
146
+ ? stablecoinsIssued -
147
+ (otherStablecoinSupply * lowerExposure) / (BASE_9 - lowerExposure)
148
+ : (otherStablecoinSupply * lowerExposure) / (BASE_9 - lowerExposure) -
149
+ stablecoinsIssued;
150
+
151
+ // slope = (upperFees - lowerFees) / (amountToNextBreakPoint + amountFromPrevBreakPoint)
152
+ // `currentFees` is the `g(0)` value from the whitepaper
153
+ currentFees =
154
+ lowerFees +
155
+ ((upperFees - lowerFees) * amountFromPrevBreakPoint) /
156
+ (amountToNextBreakPoint + amountFromPrevBreakPoint);
157
+ }
158
+ {
159
+ const amountToNextBreakPointNormalizer: number = isExact
160
+ ? amountToNextBreakPoint
161
+ : isMint
162
+ ? _invertFeeMint(amountToNextBreakPoint, (upperFees + currentFees) / 2)
163
+ : _applyFeeBurn(amountToNextBreakPoint, (upperFees + currentFees) / 2);
164
+
165
+ if (amountToNextBreakPointNormalizer >= amountStable) {
166
+ let midFee: number;
167
+ if (isExact) {
168
+ // `(g_i(0) + g_i(M)) / 2 = g(0) + (f_{i+1} - g(0)) * M / (2 * b_{i+1})`
169
+ midFee =
170
+ currentFees +
171
+ (amountStable * (upperFees - currentFees)) /
172
+ (2 * amountToNextBreakPointNormalizer);
173
+ } else {
174
+ // Here instead of computing the closed form expression for `m_t` derived in the whitepaper,
175
+ // we are computing: `(g(0)+g_i(m_t))/2 = g(0)+(f_{i+1}-f_i)/(b_{i+1}-b_i)m_t/2
176
+
177
+ // ac4 is the value of `2M(f_{i+1}-f_i)/(b_{i+1}-b_i) = 2M(f_{i+1}-g(0))/b_{i+1}` used
178
+ // in the computation of `m_t` in both the mint and burn case
179
+ const ac4 =
180
+ (BASE_9 * (2 * amountStable * (upperFees - currentFees))) /
181
+ amountToNextBreakPoint;
182
+ if (isMint) {
183
+ // In the mint case:
184
+ // `m_t = (-1-g(0)+sqrt[(1+g(0))**2+2M(f_{i+1}-g(0))/b_{i+1})]/((f_{i+1}-g(0))/b_{i+1})`
185
+ // And so: g(0)+(f_{i+1}-f_i)/(b_{i+1}-b_i)m_t/2
186
+ // = (g(0)-1+sqrt[(1+g(0))**2+2M(f_{i+1}-g(0))/b_{i+1})])
187
+ midFee = Number(
188
+ (Math.sqrt((BASE_9 + currentFees) ** 2 + ac4) +
189
+ currentFees -
190
+ BASE_9) /
191
+ 2,
192
+ );
193
+ } else {
194
+ // In the burn case:
195
+ // `m_t = (1-g(0)+sqrt[(1-g(0))**2-2M(f_{i+1}-g(0))/b_{i+1})]/((f_{i+1}-g(0))/b_{i+1})`
196
+ // And so: g(0)+(f_{i+1}-f_i)/(b_{i+1}-b_i)m_t/2
197
+ // = (g(0)+1-sqrt[(1-g(0))**2-2M(f_{i+1}-g(0))/b_{i+1})])
198
+
199
+ const baseMinusCurrentSquared = (BASE_9 - currentFees) ** 2;
200
+ // Mathematically, this condition is always verified, but rounding errors may make this
201
+ // mathematical invariant break, in which case we consider that the square root is null
202
+ if (baseMinusCurrentSquared < ac4) {
203
+ midFee = (currentFees + BASE_9) / 2;
204
+ } else {
205
+ midFee =
206
+ (currentFees +
207
+ BASE_9 -
208
+ Math.sqrt(baseMinusCurrentSquared - ac4)) /
209
+ 2;
210
+ }
211
+ }
212
+ }
213
+ return amount + _computeFee(quoteType, amountStable, midFee);
214
+ }
215
+ amountStable -= amountToNextBreakPointNormalizer;
216
+ amount += !isExact
217
+ ? amountToNextBreakPoint
218
+ : isMint
219
+ ? _invertFeeMint(amountToNextBreakPoint, (upperFees + currentFees) / 2)
220
+ : _applyFeeBurn(amountToNextBreakPoint, (upperFees + currentFees) / 2);
221
+ currentExposure = upperExposure * BASE_9;
222
+ ++i;
223
+ // Update for the rest of the swaps the stablecoins issued from the asset
224
+ stablecoinsIssued = isMint
225
+ ? stablecoinsIssued + amountToNextBreakPoint
226
+ : stablecoinsIssued - amountToNextBreakPoint;
227
+ }
228
+ }
229
+
230
+ return (
231
+ amount +
232
+ _computeFee(
233
+ quoteType,
234
+ amountStable,
235
+ isMint ? fees.yFeeMint[n - 1] : fees.yFeeBurn[n - 1],
236
+ )
237
+ );
238
+ }
239
+
240
+ function findLowerBound(
241
+ increasingArray: boolean,
242
+ array: number[],
243
+ normalizerArray: number,
244
+ element: number,
245
+ ): number {
246
+ if (array.length === 0) {
247
+ return 0;
248
+ }
249
+ let low = 1;
250
+ let high = array.length;
251
+
252
+ if (
253
+ (increasingArray && array[high - 1] * normalizerArray <= element) ||
254
+ (!increasingArray && array[high - 1] * normalizerArray >= element)
255
+ ) {
256
+ return high - 1;
257
+ }
258
+
259
+ while (low < high) {
260
+ const mid = Math.floor((low + high) / 2);
261
+
262
+ if (
263
+ increasingArray
264
+ ? array[mid] * normalizerArray > element
265
+ : array[mid] * normalizerArray < element
266
+ ) {
267
+ high = mid;
268
+ } else {
269
+ low = mid + 1;
270
+ }
271
+ }
272
+
273
+ return low - 1;
274
+ }
275
+
276
+ function _isMint(quoteType: QuoteType): boolean {
277
+ return (
278
+ quoteType === QuoteType.MintExactInput ||
279
+ quoteType === QuoteType.MintExactOutput
280
+ );
281
+ }
282
+
283
+ function _isExact(quoteType: QuoteType): boolean {
284
+ return (
285
+ quoteType === QuoteType.MintExactOutput ||
286
+ quoteType === QuoteType.BurnExactInput
287
+ );
288
+ }
289
+
290
+ function _applyFeeMint(amountIn: number, fees: number): number {
291
+ if (fees >= 0) {
292
+ const castedFees = fees;
293
+ // Consider that if fees are above `BASE_12` this is equivalent to infinite fees
294
+ if (castedFees >= BASE_12) throw new Error('InvalidSwap');
295
+ return (amountIn * BASE_9) / (BASE_9 + castedFees);
296
+ }
297
+ return (amountIn * BASE_9) / (BASE_9 - Math.abs(-fees));
298
+ }
299
+
300
+ function _invertFeeMint(amountOut: number, fees: number): number {
301
+ if (fees >= 0) {
302
+ const castedFees = fees;
303
+ // Consider that if fees are above `BASE_12` this is equivalent to infinite fees
304
+ if (castedFees >= BASE_12) throw new Error('InvalidSwap');
305
+ return (amountOut * (BASE_9 + castedFees)) / BASE_9;
306
+ }
307
+ return (amountOut * (BASE_9 - Math.abs(-fees))) / BASE_9;
308
+ }
309
+
310
+ function _applyFeeBurn(amountIn: number, fees: number): number {
311
+ if (fees >= 0) {
312
+ const castedFees = fees;
313
+ if (castedFees >= MAX_BURN_FEE) throw new Error('InvalidSwap');
314
+ return ((BASE_9 - castedFees) * amountIn) / BASE_9;
315
+ }
316
+ return ((BASE_9 + Math.abs(-fees)) * amountIn) / BASE_9;
317
+ }
318
+
319
+ function _invertFeeBurn(amountOut: number, fees: number): number {
320
+ if (fees >= 0) {
321
+ const castedFees = fees;
322
+ if (castedFees >= MAX_BURN_FEE) throw new Error('InvalidSwap');
323
+ return (amountOut * BASE_9) / (BASE_9 - castedFees);
324
+ }
325
+ return (amountOut * BASE_9) / (BASE_9 + Math.abs(-fees));
326
+ }
327
+
328
+ function _computeFee(
329
+ quoteType: QuoteType,
330
+ amount: number,
331
+ fees: number,
332
+ ): number {
333
+ if (quoteType === QuoteType.MintExactInput) {
334
+ return _applyFeeMint(amount, fees);
335
+ }
336
+ if (quoteType === QuoteType.MintExactOutput) {
337
+ return _invertFeeMint(amount, fees);
338
+ }
339
+ if (quoteType === QuoteType.BurnExactInput) {
340
+ return _applyFeeBurn(amount, fees);
341
+ }
342
+ return _invertFeeBurn(amount, fees);
343
+ }
344
+
345
+ export function filterDictionaryOnly<T extends { [key: string]: any }>(
346
+ obj: T,
347
+ ): Partial<T> {
348
+ const result: Partial<T> = {};
349
+ Object.keys(obj).map(key => {
350
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
351
+ // Skip numeric keys to exclude array-like properties
352
+ if (Number.isNaN(Number(key))) {
353
+ result[key as keyof T] = obj[key];
354
+ }
355
+ }
356
+ });
357
+ return result;
358
+ }
package/src/dex/index.ts CHANGED
@@ -75,6 +75,7 @@ import { SwaapV2 } from './swaap-v2/swaap-v2';
75
75
  import { TraderJoeV21 } from './trader-joe-v2.1/trader-joe-v2.1';
76
76
  import { PancakeswapV3 } from './pancakeswap-v3/pancakeswap-v3';
77
77
  import { Algebra } from './algebra/algebra';
78
+ import { AngleTransmuter } from './angle-transmuter/angle-transmuter';
78
79
  import { AngleStakedStable } from './angle-staked-stable/angle-staked-stable';
79
80
  import { QuickPerps } from './quick-perps/quick-perps';
80
81
  import { NomiswapV2 } from './uniswap-v2/nomiswap-v2';
@@ -158,6 +159,7 @@ const Dexes = [
158
159
  MaverickV2,
159
160
  Camelot,
160
161
  SwaapV2,
162
+ AngleTransmuter,
161
163
  AngleStakedStable,
162
164
  QuickPerps,
163
165
  NomiswapV2,
@@ -49,6 +49,21 @@ export class ChainLinkSubscriber<State> extends PartialEventSubscriber<
49
49
  )[0];
50
50
  }
51
51
 
52
+ static getReadDecimal(proxy: Address): MultiCallInput {
53
+ return {
54
+ target: proxy,
55
+ callData:
56
+ ChainLinkSubscriber.proxyInterface.encodeFunctionData('decimals'),
57
+ };
58
+ }
59
+
60
+ static readDecimals(multicallOutput: MultiCallOutput): Address {
61
+ return ChainLinkSubscriber.proxyInterface.decodeFunctionResult(
62
+ 'decimals',
63
+ multicallOutput,
64
+ )[0];
65
+ }
66
+
52
67
  public processLog(
53
68
  state: DeepReadonly<ChainLinkState>,
54
69
  log: Readonly<Log>,