@paraswap/dex-lib 2.16.8-pancakeswapv3.0 → 2.17.0

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 (198) hide show
  1. package/.idea/aws.xml +17 -0
  2. package/.idea/codeStyles/Project.xml +19 -0
  3. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/paraswap-dex-lib.iml +9 -0
  7. package/.idea/vcs.xml +6 -0
  8. package/build/abi/woo-fi/WooFeeManager.abi.json +318 -0
  9. package/build/abi/woo-fi/WooPP.abi.json +548 -0
  10. package/build/abi/woo-fi/Wooracle.abi.json +260 -0
  11. package/build/config.js +4 -4
  12. package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
  13. package/build/dex/aave-v3/tokens/avalanche.json +74 -0
  14. package/build/dex/aave-v3/tokens/fantom.json +62 -0
  15. package/build/dex/aave-v3/tokens/optimism.json +50 -0
  16. package/build/dex/aave-v3/tokens/polygon.json +116 -0
  17. package/build/dex/balancer-v2/balancer-v2.d.ts +14 -19
  18. package/build/dex/balancer-v2/balancer-v2.js +27 -22
  19. package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
  20. package/build/dex/balancer-v2/config.d.ts +2 -7
  21. package/build/dex/balancer-v2/config.js +20 -30
  22. package/build/dex/balancer-v2/config.js.map +1 -1
  23. package/build/dex/balancer-v2/pools/balancer-v2-pool.d.ts +25 -0
  24. package/build/dex/balancer-v2/pools/balancer-v2-pool.js +107 -0
  25. package/build/dex/balancer-v2/pools/balancer-v2-pool.js.map +1 -0
  26. package/build/dex/balancer-v2/pools/linear/LinearMath.d.ts +20 -0
  27. package/build/dex/balancer-v2/pools/linear/LinearMath.js +179 -0
  28. package/build/dex/balancer-v2/pools/linear/LinearMath.js.map +1 -0
  29. package/build/dex/balancer-v2/pools/linear/LinearPool.d.ts +50 -0
  30. package/build/dex/balancer-v2/pools/linear/LinearPool.js +458 -0
  31. package/build/dex/balancer-v2/pools/linear/LinearPool.js.map +1 -0
  32. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.d.ts +10 -0
  33. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.js +314 -0
  34. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.js.map +1 -0
  35. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.d.ts +50 -0
  36. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.js +367 -0
  37. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.js.map +1 -0
  38. package/build/dex/balancer-v2/pools/stable/StableMath.d.ts +7 -0
  39. package/build/dex/balancer-v2/pools/stable/StableMath.js +111 -0
  40. package/build/dex/balancer-v2/pools/stable/StableMath.js.map +1 -0
  41. package/build/dex/balancer-v2/pools/stable/StablePool.d.ts +30 -0
  42. package/build/dex/balancer-v2/pools/stable/StablePool.js +129 -0
  43. package/build/dex/balancer-v2/pools/stable/StablePool.js.map +1 -0
  44. package/build/dex/balancer-v2/pools/weighted/WeightedMath.d.ts +6 -0
  45. package/build/dex/balancer-v2/pools/weighted/WeightedMath.js +61 -0
  46. package/build/dex/balancer-v2/pools/weighted/WeightedMath.js.map +1 -0
  47. package/build/dex/balancer-v2/pools/weighted/WeightedPool.d.ts +30 -0
  48. package/build/dex/balancer-v2/pools/weighted/WeightedPool.js +112 -0
  49. package/build/dex/balancer-v2/pools/weighted/WeightedPool.js.map +1 -0
  50. package/build/dex/balancer-v2/types.d.ts +1 -0
  51. package/build/dex/balancer-v2/types.js.map +1 -1
  52. package/build/dex/balancer-v2/utils.d.ts +3 -2
  53. package/build/dex/balancer-v2/utils.js +6 -4
  54. package/build/dex/balancer-v2/utils.js.map +1 -1
  55. package/build/dex/index.js +1 -1
  56. package/build/dex/index.js.map +1 -1
  57. package/build/dex/quickswap-v3.d.ts +21 -0
  58. package/build/dex/quickswap-v3.js +40 -0
  59. package/build/dex/quickswap-v3.js.map +1 -0
  60. package/build/dex/uniswap-v3/config.js +28 -0
  61. package/build/dex/uniswap-v3/config.js.map +1 -1
  62. package/build/dex/uniswap-v3/uniswap-v3-pool.d.ts +2 -1
  63. package/build/dex/uniswap-v3/uniswap-v3-pool.js +3 -2
  64. package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
  65. package/build/dex/uniswap-v3/uniswap-v3.js +1 -1
  66. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  67. package/build/dex/{pancakeswap-v3 → woo-fi}/config.d.ts +2 -2
  68. package/build/dex/woo-fi/config.js +141 -0
  69. package/build/dex/woo-fi/config.js.map +1 -0
  70. package/build/dex/woo-fi/constants.d.ts +5 -0
  71. package/build/dex/woo-fi/constants.js +20 -0
  72. package/build/dex/woo-fi/constants.js.map +1 -0
  73. package/build/dex/woo-fi/types.d.ts +48 -0
  74. package/build/dex/woo-fi/types.js +3 -0
  75. package/build/dex/woo-fi/types.js.map +1 -0
  76. package/build/dex/woo-fi/woo-fi-decimal-math.d.ts +14 -0
  77. package/build/dex/woo-fi/woo-fi-decimal-math.js +42 -0
  78. package/build/dex/woo-fi/woo-fi-decimal-math.js.map +1 -0
  79. package/build/dex/woo-fi/woo-fi-math.d.ts +31 -0
  80. package/build/dex/woo-fi/woo-fi-math.js +300 -0
  81. package/build/dex/woo-fi/woo-fi-math.js.map +1 -0
  82. package/build/dex/woo-fi/woo-fi.d.ts +65 -0
  83. package/build/dex/woo-fi/woo-fi.js +480 -0
  84. package/build/dex/woo-fi/woo-fi.js.map +1 -0
  85. package/package.json +1 -1
  86. package/src/config.ts +4 -4
  87. package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +538 -225
  88. package/src/dex/balancer-v2/balancer-v2-integration.test.ts +305 -122
  89. package/src/dex/balancer-v2/balancer-v2.ts +60 -56
  90. package/src/dex/balancer-v2/config.ts +23 -35
  91. package/src/dex/balancer-v2/pools/balancer-v2-pool.ts +274 -0
  92. package/src/dex/balancer-v2/{LinearMath.ts → pools/linear/LinearMath.ts} +11 -10
  93. package/src/dex/balancer-v2/{LinearPool.ts → pools/linear/LinearPool.ts} +210 -6
  94. package/src/dex/balancer-v2/{StableMath.ts → pools/phantom-stable/PhantomStableMath.ts} +101 -21
  95. package/src/dex/balancer-v2/{PhantomStablePool.ts → pools/phantom-stable/PhantomStablePool.ts} +167 -12
  96. package/src/dex/balancer-v2/pools/stable/StableMath.ts +204 -0
  97. package/src/dex/balancer-v2/pools/stable/StablePool.ts +221 -0
  98. package/src/dex/balancer-v2/pools/weighted/WeightedMath.ts +84 -0
  99. package/src/dex/balancer-v2/pools/weighted/WeightedPool.ts +189 -0
  100. package/src/dex/balancer-v2/types.ts +1 -0
  101. package/src/dex/balancer-v2/utils.ts +7 -1
  102. package/src/dex/index.ts +1 -1
  103. package/src/dex/uniswap-v3/config.ts +32 -0
  104. package/src/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.ts +28 -0
  105. package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +156 -0
  106. package/src/dex/uniswap-v3/uniswap-v3-events.test.ts +0 -4
  107. package/src/dex/uniswap-v3/uniswap-v3-pool.ts +2 -1
  108. package/src/dex/uniswap-v3/uniswap-v3.ts +1 -0
  109. package/tests/constants-e2e.ts +33 -8
  110. package/build/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +0 -781
  111. package/build/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +0 -1039
  112. package/build/abi/pancakeswap-v3/PancakeswapV3Quoter.abi.json +0 -285
  113. package/build/abi/pancakeswap-v3/PancakeswapV3Router.abi.json +0 -583
  114. package/build/dex/pancakeswap-v3/config.js +0 -62
  115. package/build/dex/pancakeswap-v3/config.js.map +0 -1
  116. package/build/dex/pancakeswap-v3/constants.d.ts +0 -23
  117. package/build/dex/pancakeswap-v3/constants.js +0 -29
  118. package/build/dex/pancakeswap-v3/constants.js.map +0 -1
  119. package/build/dex/pancakeswap-v3/contract-math/BitMath.d.ts +0 -4
  120. package/build/dex/pancakeswap-v3/contract-math/BitMath.js +0 -93
  121. package/build/dex/pancakeswap-v3/contract-math/BitMath.js.map +0 -1
  122. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.d.ts +0 -3
  123. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js +0 -8
  124. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js.map +0 -1
  125. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.d.ts +0 -4
  126. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js +0 -9
  127. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js.map +0 -1
  128. package/build/dex/pancakeswap-v3/contract-math/FullMath.d.ts +0 -4
  129. package/build/dex/pancakeswap-v3/contract-math/FullMath.js +0 -19
  130. package/build/dex/pancakeswap-v3/contract-math/FullMath.js.map +0 -1
  131. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.d.ts +0 -3
  132. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js +0 -22
  133. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js.map +0 -1
  134. package/build/dex/pancakeswap-v3/contract-math/Oracle.d.ts +0 -10
  135. package/build/dex/pancakeswap-v3/contract-math/Oracle.js +0 -133
  136. package/build/dex/pancakeswap-v3/contract-math/Oracle.js.map +0 -1
  137. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.d.ts +0 -10
  138. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js +0 -91
  139. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js.map +0 -1
  140. package/build/dex/pancakeswap-v3/contract-math/SwapMath.d.ts +0 -8
  141. package/build/dex/pancakeswap-v3/contract-math/SwapMath.js +0 -70
  142. package/build/dex/pancakeswap-v3/contract-math/SwapMath.js.map +0 -1
  143. package/build/dex/pancakeswap-v3/contract-math/Tick.d.ts +0 -7
  144. package/build/dex/pancakeswap-v3/contract-math/Tick.js +0 -45
  145. package/build/dex/pancakeswap-v3/contract-math/Tick.js.map +0 -1
  146. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.d.ts +0 -8
  147. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js +0 -87
  148. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js.map +0 -1
  149. package/build/dex/pancakeswap-v3/contract-math/TickMath.d.ts +0 -8
  150. package/build/dex/pancakeswap-v3/contract-math/TickMath.js +0 -162
  151. package/build/dex/pancakeswap-v3/contract-math/TickMath.js.map +0 -1
  152. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.d.ts +0 -3
  153. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js +0 -10
  154. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js.map +0 -1
  155. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.d.ts +0 -18
  156. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js +0 -407
  157. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js.map +0 -1
  158. package/build/dex/pancakeswap-v3/contract-math/utils.d.ts +0 -3
  159. package/build/dex/pancakeswap-v3/contract-math/utils.js +0 -16
  160. package/build/dex/pancakeswap-v3/contract-math/utils.js.map +0 -1
  161. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.d.ts +0 -45
  162. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js +0 -340
  163. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js.map +0 -1
  164. package/build/dex/pancakeswap-v3/pancakeswap-v3.d.ts +0 -55
  165. package/build/dex/pancakeswap-v3/pancakeswap-v3.js +0 -605
  166. package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +0 -1
  167. package/build/dex/pancakeswap-v3/types.d.ts +0 -137
  168. package/build/dex/pancakeswap-v3/types.js +0 -9
  169. package/build/dex/pancakeswap-v3/types.js.map +0 -1
  170. package/build/dex/pancakeswap-v3/utils.d.ts +0 -6
  171. package/build/dex/pancakeswap-v3/utils.js +0 -65
  172. package/build/dex/pancakeswap-v3/utils.js.map +0 -1
  173. package/src/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +0 -781
  174. package/src/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +0 -1039
  175. package/src/dex/balancer-v2/balancer-v2-pool.ts +0 -744
  176. package/src/dex/pancakeswap-v3/config.ts +0 -68
  177. package/src/dex/pancakeswap-v3/constants.ts +0 -35
  178. package/src/dex/pancakeswap-v3/contract-math/BitMath.ts +0 -90
  179. package/src/dex/pancakeswap-v3/contract-math/FixedPoint128.ts +0 -3
  180. package/src/dex/pancakeswap-v3/contract-math/FixedPoint96.ts +0 -4
  181. package/src/dex/pancakeswap-v3/contract-math/FullMath.ts +0 -30
  182. package/src/dex/pancakeswap-v3/contract-math/LiquidityMath.ts +0 -17
  183. package/src/dex/pancakeswap-v3/contract-math/Oracle.ts +0 -226
  184. package/src/dex/pancakeswap-v3/contract-math/SqrtPriceMath.ts +0 -226
  185. package/src/dex/pancakeswap-v3/contract-math/SwapMath.ts +0 -139
  186. package/src/dex/pancakeswap-v3/contract-math/Tick.ts +0 -82
  187. package/src/dex/pancakeswap-v3/contract-math/TickBitMap.ts +0 -128
  188. package/src/dex/pancakeswap-v3/contract-math/TickMath.ts +0 -211
  189. package/src/dex/pancakeswap-v3/contract-math/UnsafeMath.ts +0 -5
  190. package/src/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.ts +0 -691
  191. package/src/dex/pancakeswap-v3/contract-math/utils.ts +0 -11
  192. package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +0 -168
  193. package/src/dex/pancakeswap-v3/pancakeswap-v3-events.test.ts +0 -124
  194. package/src/dex/pancakeswap-v3/pancakeswap-v3-integration.test.ts +0 -338
  195. package/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts +0 -554
  196. package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +0 -1000
  197. /package/src/abi/{pancakeswap-v3/PancakeswapV3Quoter.abi.json → uniswap-v3/pancakeswap-v3/PancakeswapV3QuoterV2.abi.json} +0 -0
  198. /package/src/abi/{pancakeswap-v3 → uniswap-v3/pancakeswap-v3}/PancakeswapV3Router.abi.json +0 -0
@@ -1,11 +1,11 @@
1
1
  import { Interface } from '@ethersproject/abi';
2
2
  import { BigNumber } from '@ethersproject/bignumber';
3
- import { isSameAddress, decodeThrowError } from './utils';
3
+ import { isSameAddress, decodeThrowError } from '../../utils';
4
4
  import * as LinearMath from './LinearMath';
5
- import { BasePool } from './balancer-v2-pool';
6
- import { callData, SubgraphPoolBase, PoolState, TokenState } from './types';
7
- import LinearPoolABI from '../../abi/balancer-v2/linearPoolAbi.json';
8
- import { SwapSide } from '../../constants';
5
+ import { BasePool } from '../balancer-v2-pool';
6
+ import { callData, SubgraphPoolBase, PoolState } from '../../types';
7
+ import LinearPoolABI from '../../../../abi/balancer-v2/linearPoolAbi.json';
8
+ import { SwapSide } from '../../../../constants';
9
9
  import { keyBy } from 'lodash';
10
10
 
11
11
  export enum PairTypes {
@@ -82,6 +82,210 @@ export class LinearPool extends BasePool {
82
82
  );
83
83
  }
84
84
 
85
+ onBuy(amounts: bigint[], poolPairData: LinearPoolPairData): bigint[] {
86
+ return this._swapGivenOut(
87
+ amounts,
88
+ poolPairData.tokens,
89
+ poolPairData.balances,
90
+ poolPairData.indexIn,
91
+ poolPairData.indexOut,
92
+ poolPairData.bptIndex,
93
+ poolPairData.wrappedIndex,
94
+ poolPairData.mainIndex,
95
+ poolPairData.scalingFactors,
96
+ poolPairData.swapFee,
97
+ poolPairData.lowerTarget,
98
+ poolPairData.upperTarget,
99
+ );
100
+ }
101
+
102
+ _swapGivenOut(
103
+ tokenAmountsOut: bigint[],
104
+ tokens: string[],
105
+ balances: bigint[],
106
+ indexIn: number,
107
+ indexOut: number,
108
+ bptIndex: number,
109
+ wrappedIndex: number,
110
+ mainIndex: number,
111
+ scalingFactors: bigint[],
112
+ swapFeePercentage: bigint,
113
+ lowerTarget: bigint,
114
+ upperTarget: bigint,
115
+ ): bigint[] {
116
+ let pairType: PairTypes;
117
+ if (isSameAddress(tokens[indexIn], tokens[bptIndex])) {
118
+ if (isSameAddress(tokens[indexOut], tokens[wrappedIndex]))
119
+ pairType = PairTypes.BptToWrappedToken;
120
+ else pairType = PairTypes.BptToMainToken;
121
+ } else if (isSameAddress(tokens[indexOut], tokens[bptIndex])) {
122
+ if (isSameAddress(tokens[indexIn], tokens[wrappedIndex]))
123
+ pairType = PairTypes.WrappedTokenToBpt;
124
+ else pairType = PairTypes.MainTokenToBpt;
125
+ } else {
126
+ if (isSameAddress(tokens[indexIn], tokens[wrappedIndex]))
127
+ pairType = PairTypes.WrappedTokenToMainToken;
128
+ else pairType = PairTypes.MainTokenToWrappedToken;
129
+ }
130
+
131
+ const balancesUpscaled = this._upscaleArray(balances, scalingFactors);
132
+ const tokenAmountsOutScaled = tokenAmountsOut.map(a =>
133
+ this._upscale(a, scalingFactors[indexOut]),
134
+ );
135
+
136
+ // VirtualBPTSupply must be used for the maths
137
+ const virtualBptSupply = this.MAX_TOKEN_BALANCE.sub(
138
+ balances[bptIndex],
139
+ ).toBigInt();
140
+
141
+ const amountsIn = this._onSwapGivenOut(
142
+ tokenAmountsOutScaled,
143
+ balancesUpscaled[mainIndex],
144
+ balancesUpscaled[wrappedIndex],
145
+ swapFeePercentage,
146
+ lowerTarget,
147
+ upperTarget,
148
+ virtualBptSupply,
149
+ pairType,
150
+ );
151
+
152
+ return amountsIn.map(a => this._downscaleUp(a, scalingFactors[indexIn]));
153
+ }
154
+
155
+ _onSwapGivenOut(
156
+ tokenAmountsIn: bigint[],
157
+ mainBalance: bigint,
158
+ wrappedBalance: bigint,
159
+ fee: bigint,
160
+ lowerTarget: bigint,
161
+ upperTarget: bigint,
162
+ virtualBptSupply: bigint,
163
+ pairType: PairTypes,
164
+ ): bigint[] {
165
+ const amountsIn: bigint[] = [];
166
+
167
+ switch (pairType) {
168
+ case PairTypes.BptToMainToken:
169
+ tokenAmountsIn.forEach(amountIn => {
170
+ let amt: bigint;
171
+ try {
172
+ amt = LinearMath._calcBptInPerMainOut(
173
+ amountIn,
174
+ mainBalance,
175
+ wrappedBalance,
176
+ virtualBptSupply,
177
+ {
178
+ fee: fee,
179
+ lowerTarget: lowerTarget,
180
+ upperTarget: upperTarget,
181
+ },
182
+ );
183
+ } catch (err) {
184
+ amt = 0n;
185
+ }
186
+ amountsIn.push(amt);
187
+ });
188
+
189
+ break;
190
+ case PairTypes.MainTokenToBpt:
191
+ tokenAmountsIn.forEach(amountIn => {
192
+ let amt: bigint;
193
+ try {
194
+ amt = LinearMath._calcMainInPerBptOut(
195
+ amountIn,
196
+ mainBalance,
197
+ wrappedBalance,
198
+ virtualBptSupply,
199
+ {
200
+ fee: fee,
201
+ lowerTarget: lowerTarget,
202
+ upperTarget: upperTarget,
203
+ },
204
+ );
205
+ } catch (err) {
206
+ amt = 0n;
207
+ }
208
+ amountsIn.push(amt);
209
+ });
210
+ break;
211
+ case PairTypes.MainTokenToWrappedToken:
212
+ tokenAmountsIn.forEach(amountIn => {
213
+ let amt: bigint;
214
+ try {
215
+ amt = LinearMath._calcMainInPerWrappedOut(amountIn, mainBalance, {
216
+ fee: fee,
217
+ lowerTarget: lowerTarget,
218
+ upperTarget: upperTarget,
219
+ });
220
+ } catch (err) {
221
+ amt = 0n;
222
+ }
223
+ amountsIn.push(amt);
224
+ });
225
+ break;
226
+ case PairTypes.WrappedTokenToMainToken:
227
+ tokenAmountsIn.forEach(amountIn => {
228
+ let amt: bigint;
229
+ try {
230
+ amt = LinearMath._calcWrappedInPerMainOut(amountIn, mainBalance, {
231
+ fee: fee,
232
+ lowerTarget: lowerTarget,
233
+ upperTarget: upperTarget,
234
+ });
235
+ } catch (err) {
236
+ amt = 0n;
237
+ }
238
+ amountsIn.push(amt);
239
+ });
240
+ break;
241
+ case PairTypes.BptToWrappedToken:
242
+ tokenAmountsIn.forEach(amountIn => {
243
+ let amt: bigint;
244
+ try {
245
+ amt = LinearMath._calcBptInPerWrappedOut(
246
+ amountIn,
247
+ mainBalance,
248
+ wrappedBalance,
249
+ virtualBptSupply,
250
+ {
251
+ fee: fee,
252
+ lowerTarget: lowerTarget,
253
+ upperTarget: upperTarget,
254
+ },
255
+ );
256
+ } catch (err) {
257
+ amt = 0n;
258
+ }
259
+ amountsIn.push(amt);
260
+ });
261
+ break;
262
+ case PairTypes.WrappedTokenToBpt:
263
+ tokenAmountsIn.forEach(amountIn => {
264
+ let amt: bigint;
265
+ try {
266
+ amt = LinearMath._calcWrappedInPerBptOut(
267
+ amountIn,
268
+ mainBalance,
269
+ wrappedBalance,
270
+ virtualBptSupply,
271
+ {
272
+ fee: fee,
273
+ lowerTarget: lowerTarget,
274
+ upperTarget: upperTarget,
275
+ },
276
+ );
277
+ } catch (err) {
278
+ amt = 0n;
279
+ }
280
+ amountsIn.push(amt);
281
+ });
282
+ break;
283
+ default:
284
+ amountsIn.push(0n);
285
+ }
286
+ return amountsIn;
287
+ }
288
+
85
289
  _swapGivenIn(
86
290
  tokenAmountsIn: bigint[],
87
291
  tokens: string[],
@@ -427,7 +631,7 @@ export class LinearPool extends BasePool {
427
631
  (this._upscale(
428
632
  poolPairData.balances[poolPairData.indexOut],
429
633
  poolPairData.scalingFactors[poolPairData.indexOut],
430
- ) *
634
+ ) *
431
635
  99n) /
432
636
  100n
433
637
  );
@@ -1,5 +1,5 @@
1
- import { BI_POWS } from '../../bigint-constants';
2
- import { MathSol } from './balancer-v2-math';
1
+ import { BI_POWS } from '../../../../bigint-constants';
2
+ import { MathSol } from '../../balancer-v2-math';
3
3
 
4
4
  const AMP_PRECISION = BI_POWS[3];
5
5
 
@@ -9,15 +9,15 @@ export function _calculateInvariant(
9
9
  roundUp: boolean,
10
10
  ): bigint {
11
11
  /**********************************************************************************************
12
- // invariant //
13
- // D = invariant D^(n+1) //
14
- // A = amplification coefficient A n^n S + D = A D n^n + ----------- //
15
- // S = sum of balances n^n P //
16
- // P = product of balances //
17
- // n = number of tokens //
18
- *********x************************************************************************************/
12
+ // invariant //
13
+ // D = invariant D^(n+1) //
14
+ // A = amplification coefficient A n^n S + D = A D n^n + ----------- //
15
+ // S = sum of balances n^n P //
16
+ // P = product of balances //
17
+ // n = number of tokens //
18
+ *********x************************************************************************************/
19
19
 
20
- // We support rounding up or down.
20
+ // We support rounding up or down.
21
21
 
22
22
  let sum = 0n;
23
23
  const numTokens = balances.length;
@@ -44,18 +44,18 @@ export function _calculateInvariant(
44
44
  prevInvariant = invariant;
45
45
  invariant = MathSol.div(
46
46
  MathSol.mul(MathSol.mul(BigInt(numTokens), invariant), invariant) +
47
- MathSol.div(
48
- MathSol.mul(MathSol.mul(ampTimesTotal, sum), P_D),
49
- AMP_PRECISION,
50
- roundUp,
51
- ),
47
+ MathSol.div(
48
+ MathSol.mul(MathSol.mul(ampTimesTotal, sum), P_D),
49
+ AMP_PRECISION,
50
+ roundUp,
51
+ ),
52
52
  MathSol.mul(BigInt(numTokens + 1), invariant) +
53
- // No need to use checked arithmetic for the amp precision, the amp is guaranteed to be at least 1
54
- MathSol.div(
55
- MathSol.mul(ampTimesTotal - AMP_PRECISION, P_D),
56
- AMP_PRECISION,
57
- !roundUp,
58
- ),
53
+ // No need to use checked arithmetic for the amp precision, the amp is guaranteed to be at least 1
54
+ MathSol.div(
55
+ MathSol.mul(ampTimesTotal - AMP_PRECISION, P_D),
56
+ AMP_PRECISION,
57
+ !roundUp,
58
+ ),
59
59
  roundUp,
60
60
  );
61
61
 
@@ -81,6 +81,17 @@ export function _calcOutGivenIn(
81
81
  amountIn: bigint,
82
82
  invariant?: bigint,
83
83
  ): bigint {
84
+ /**************************************************************************************************************
85
+ // outGivenIn token x for y - polynomial equation to solve //
86
+ // ay = amount out to calculate //
87
+ // by = balance token out //
88
+ // y = by - ay (finalBalanceOut) //
89
+ // D = invariant D D^(n+1) //
90
+ // A = amplification coefficient y^2 + ( S - ---------- - D) * y - ------------- = 0 //
91
+ // n = number of tokens (A * n^n) A * n^2n * P //
92
+ // S = sum of final balances but y //
93
+ // P = product of final balances but y //
94
+ **************************************************************************************************************/
84
95
  balances = [...balances];
85
96
  // Given that we need to have a greater final balance out, the invariant needs to be rounded up
86
97
  if (!invariant) invariant = _calculateInvariant(amp, balances, true);
@@ -105,6 +116,19 @@ export function _calcInGivenOut(
105
116
  fee: bigint,
106
117
  invariant?: bigint,
107
118
  ): bigint {
119
+ /**************************************************************************************************************
120
+ // inGivenOut token x for y - polynomial equation to solve //
121
+ // ax = amount in to calculate //
122
+ // bx = balance token in //
123
+ // x = bx + ax (finalBalanceIn) //
124
+ // D = invariant D D^(n+1) //
125
+ // A = amplification coefficient x^2 + ( S - ---------- - D) * x - ------------- = 0 //
126
+ // n = number of tokens (A * n^n) A * n^2n * P //
127
+ // S = sum of final balances but x //
128
+ // P = product of final balances but x //
129
+ **************************************************************************************************************/
130
+
131
+ // Given that we need to have a greater final balance in, the invariant needs to be rounded up
108
132
  balances = [...balances];
109
133
  if (!invariant) invariant = _calculateInvariant(amp, balances, true);
110
134
  balances[tokenIndexOut] = MathSol.sub(balances[tokenIndexOut], amountOut);
@@ -120,6 +144,7 @@ export function _calcInGivenOut(
120
144
  MathSol.sub(finalBalanceIn, balances[tokenIndexIn]),
121
145
  1n,
122
146
  );
147
+
123
148
  amountIn = addFee(amountIn, fee);
124
149
  return amountIn;
125
150
  }
@@ -195,6 +220,61 @@ export function _calcBptOutGivenExactTokensIn(
195
220
  }
196
221
  }
197
222
 
223
+ export function _calcTokenInGivenExactBptOut(
224
+ amp: bigint,
225
+ balances: bigint[],
226
+ tokenIndexIn: number,
227
+ bptAmountOut: bigint,
228
+ bptTotalSupply: bigint,
229
+ fee: bigint,
230
+ invariant?: bigint,
231
+ ): bigint {
232
+ if (!invariant) invariant = _calculateInvariant(amp, balances, true);
233
+
234
+ const newInvariant = MathSol.mulUpFixed(
235
+ MathSol.divUpFixed(
236
+ MathSol.add(bptTotalSupply, bptAmountOut),
237
+ bptTotalSupply
238
+ ),
239
+ invariant
240
+ );
241
+
242
+ const newBalanceTokenIndex =
243
+ _getTokenBalanceGivenInvariantAndAllOtherBalances(
244
+ amp,
245
+ balances,
246
+ newInvariant,
247
+ tokenIndexIn
248
+ );
249
+ const amountInWithoutFee = MathSol.sub(
250
+ newBalanceTokenIndex,
251
+ balances[tokenIndexIn]
252
+ );
253
+
254
+ let sumBalances = BigInt(0);
255
+ for (let i = 0; i < balances.length; i++) {
256
+ sumBalances = MathSol.add(sumBalances, balances[i]);
257
+ }
258
+
259
+ // We can now compute how much extra balance is being deposited
260
+ // and used in virtual swaps, and charge swap fees accordingly.
261
+ const currentWeight = MathSol.divDownFixed(
262
+ balances[tokenIndexIn],
263
+ sumBalances
264
+ );
265
+ const taxablePercentage = MathSol.complementFixed(currentWeight);
266
+ const taxableAmount = MathSol.mulUpFixed(
267
+ amountInWithoutFee,
268
+ taxablePercentage
269
+ );
270
+ const nonTaxableAmount = MathSol.sub(amountInWithoutFee, taxableAmount);
271
+
272
+ return MathSol.add(
273
+ nonTaxableAmount,
274
+ MathSol.divUpFixed(taxableAmount, MathSol.sub(MathSol.ONE, fee))
275
+ );
276
+ }
277
+
198
278
  /*
199
279
  Flow of calculations:
200
280
  amountsTokenOut -> amountsOutProportional ->
@@ -1,12 +1,12 @@
1
1
  import { Interface } from '@ethersproject/abi';
2
2
  import { BigNumber } from '@ethersproject/bignumber';
3
- import { BasePool } from './balancer-v2-pool';
4
- import { isSameAddress, decodeThrowError } from './utils';
5
- import * as StableMath from './StableMath';
6
- import { SubgraphPoolBase, PoolState, callData, TokenState } from './types';
7
- import { SwapSide } from '../../constants';
8
- import MetaStablePoolABI from '../../abi/balancer-v2/meta-stable-pool.json';
9
- import ComposableStablePoolABI from '../../abi/balancer-v2/ComposableStable.json';
3
+ import { BasePool } from '../balancer-v2-pool';
4
+ import { isSameAddress, decodeThrowError } from '../../utils';
5
+ import * as PhantomStableMath from './PhantomStableMath';
6
+ import { SubgraphPoolBase, PoolState, callData } from '../../types';
7
+ import { SwapSide } from '../../../../constants';
8
+ import MetaStablePoolABI from '../../../../abi/balancer-v2/meta-stable-pool.json';
9
+ import ComposableStablePoolABI from '../../../../abi/balancer-v2/ComposableStable.json';
10
10
  import { keyBy } from 'lodash';
11
11
 
12
12
  enum PairTypes {
@@ -84,6 +84,21 @@ export class PhantomStablePool extends BasePool {
84
84
  );
85
85
  }
86
86
 
87
+ onBuy(amounts: bigint[], poolPairData: PhantomStablePoolPairData): bigint[] {
88
+ return this._swapGivenOut(
89
+ amounts,
90
+ poolPairData.tokens,
91
+ poolPairData.balances,
92
+ poolPairData.indexIn,
93
+ poolPairData.indexOut,
94
+ poolPairData.bptIndex,
95
+ poolPairData.scalingFactors,
96
+ poolPairData.swapFee,
97
+ poolPairData.amp,
98
+ poolPairData.actualSupply,
99
+ );
100
+ }
101
+
87
102
  // StablePool's `_onSwapGivenIn` and `_onSwapGivenOut` handlers are meant to process swaps between Pool tokens.
88
103
  // Since one of the Pool's tokens is the preminted BPT, we need to a) handle swaps where that tokens is involved
89
104
  // separately (as they are effectively single-token joins or exits), and b) remove BPT from the balances array when
@@ -98,7 +113,7 @@ export class PhantomStablePool extends BasePool {
98
113
  indexIn: number;
99
114
  indexOut: number;
100
115
  } {
101
- if (bptIndex != -1) {
116
+ if (bptIndex !== -1) {
102
117
  balances.splice(bptIndex, 1);
103
118
  if (bptIndex < tokenIndexIn) tokenIndexIn -= 1;
104
119
  if (bptIndex < tokenIndexOut) tokenIndexOut -= 1;
@@ -110,6 +125,64 @@ export class PhantomStablePool extends BasePool {
110
125
  };
111
126
  }
112
127
 
128
+ _swapGivenOut(
129
+ tokenAmountsOut: bigint[],
130
+ tokens: string[],
131
+ balances: bigint[],
132
+ indexIn: number,
133
+ indexOut: number,
134
+ bptIndex: number,
135
+ scalingFactors: bigint[],
136
+ swapFeePercentage: bigint,
137
+ amplificationParameter: bigint,
138
+ actualSupply: bigint | undefined,
139
+ ) {
140
+ // Phantom pools allow trading between token and pool BPT
141
+ let pairType: PairTypes;
142
+ if (isSameAddress(tokens[indexIn], tokens[bptIndex])) {
143
+ pairType = PairTypes.BptToToken;
144
+ } else if (isSameAddress(tokens[indexOut], tokens[bptIndex])) {
145
+ pairType = PairTypes.TokenToBpt;
146
+ } else {
147
+ pairType = PairTypes.TokenToToken;
148
+ }
149
+
150
+ const balancesUpscaled = this._upscaleArray(balances, scalingFactors);
151
+ const tokenAmountsOutScaled = tokenAmountsOut.map(a =>
152
+ this._upscale(a, scalingFactors[indexOut]),
153
+ );
154
+
155
+ let bptSupply: bigint;
156
+ if (actualSupply) bptSupply = actualSupply;
157
+ // VirtualBPTSupply must be used for the maths
158
+ else bptSupply = this.MAX_TOKEN_BALANCE.sub(balances[bptIndex]).toBigInt();
159
+
160
+ const droppedBpt = this.removeBPT(
161
+ balancesUpscaled,
162
+ indexIn,
163
+ indexOut,
164
+ bptIndex,
165
+ );
166
+
167
+ const amountsIn = this._onSwapGivenOut(
168
+ tokenAmountsOutScaled,
169
+ droppedBpt.balances,
170
+ droppedBpt.indexIn,
171
+ droppedBpt.indexOut,
172
+ amplificationParameter,
173
+ bptSupply,
174
+ pairType,
175
+ );
176
+
177
+ const amountsInDownscaled = amountsIn.map(a =>
178
+ this._downscaleUp(a, scalingFactors[indexIn]),
179
+ );
180
+
181
+ return amountsInDownscaled.map(a =>
182
+ this._addFeeAmount(a, swapFeePercentage),
183
+ );
184
+ }
185
+
113
186
  _swapGivenIn(
114
187
  tokenAmountsIn: bigint[],
115
188
  tokens: string[],
@@ -136,6 +209,7 @@ export class PhantomStablePool extends BasePool {
136
209
  const tokenAmountsInWithFee = tokenAmountsIn.map(a =>
137
210
  this._subtractSwapFeeAmount(a, swapFeePercentage),
138
211
  );
212
+
139
213
  const balancesUpscaled = this._upscaleArray(balances, scalingFactors);
140
214
  const tokenAmountsInScaled = tokenAmountsInWithFee.map(a =>
141
215
  this._upscale(a, scalingFactors[indexIn]),
@@ -169,6 +243,87 @@ export class PhantomStablePool extends BasePool {
169
243
  );
170
244
  }
171
245
 
246
+ _onSwapGivenOut(
247
+ tokenAmountsOut: bigint[],
248
+ balances: bigint[],
249
+ indexIn: number,
250
+ indexOut: number,
251
+ _amplificationParameter: bigint,
252
+ virtualBptSupply: bigint,
253
+ pairType: PairTypes,
254
+ ) {
255
+ const invariant = PhantomStableMath._calculateInvariant(
256
+ _amplificationParameter,
257
+ balances,
258
+ true,
259
+ );
260
+
261
+ const amountsIn: bigint[] = [];
262
+
263
+ if (pairType === PairTypes.TokenToBpt) {
264
+ tokenAmountsOut.forEach(amountOut => {
265
+ let amt: bigint;
266
+ try {
267
+ const amountsInBigInt = Array(balances.length).fill(0n);
268
+ amountsInBigInt[indexIn] = amountOut;
269
+
270
+ amt = PhantomStableMath._calcTokenInGivenExactBptOut(
271
+ _amplificationParameter,
272
+ balances,
273
+ indexIn,
274
+ amountOut,
275
+ virtualBptSupply,
276
+ 0n,
277
+ invariant,
278
+ );
279
+ } catch (err) {
280
+ amt = 0n;
281
+ }
282
+ amountsIn.push(amt);
283
+ });
284
+ } else if (pairType === PairTypes.BptToToken) {
285
+
286
+ tokenAmountsOut.forEach(amountOut => {
287
+ let amt: bigint;
288
+ try {
289
+ const amountsOutBigInt = Array(balances.length).fill(0n);
290
+ amountsOutBigInt[indexOut] = amountOut;
291
+
292
+ amt = PhantomStableMath._calcBptInGivenExactTokensOut(
293
+ _amplificationParameter,
294
+ balances,
295
+ amountsOutBigInt,
296
+ virtualBptSupply,
297
+ 0n,
298
+ invariant,
299
+ );
300
+ } catch (err) {
301
+ amt = 0n;
302
+ }
303
+ amountsIn.push(amt);
304
+ });
305
+ } else {
306
+ tokenAmountsOut.forEach(amountOut => {
307
+ let amt: bigint;
308
+ try {
309
+ amt = PhantomStableMath._calcInGivenOut(
310
+ _amplificationParameter,
311
+ balances,
312
+ indexIn,
313
+ indexOut,
314
+ amountOut,
315
+ 0n,
316
+ invariant,
317
+ );
318
+ } catch (err) {
319
+ amt = 0n;
320
+ }
321
+ amountsIn.push(amt);
322
+ });
323
+ }
324
+ return amountsIn;
325
+ }
326
+
172
327
  /*
173
328
  Called when a swap with the Pool occurs, where the amount of tokens entering the Pool is known.
174
329
  All amounts are upscaled.
@@ -184,7 +339,7 @@ export class PhantomStablePool extends BasePool {
184
339
  virtualBptSupply: bigint,
185
340
  pairType: PairTypes,
186
341
  ): bigint[] {
187
- const invariant = StableMath._calculateInvariant(
342
+ const invariant = PhantomStableMath._calculateInvariant(
188
343
  _amplificationParameter,
189
344
  balances,
190
345
  true,
@@ -199,7 +354,7 @@ export class PhantomStablePool extends BasePool {
199
354
  const amountsInBigInt = Array(balances.length).fill(0n);
200
355
  amountsInBigInt[indexIn] = amountIn;
201
356
 
202
- amt = StableMath._calcBptOutGivenExactTokensIn(
357
+ amt = PhantomStableMath._calcBptOutGivenExactTokensIn(
203
358
  _amplificationParameter,
204
359
  balances,
205
360
  amountsInBigInt,
@@ -215,7 +370,7 @@ export class PhantomStablePool extends BasePool {
215
370
  tokenAmountsIn.forEach(amountIn => {
216
371
  let amt: bigint;
217
372
  try {
218
- amt = StableMath._calcTokenOutGivenExactBptIn(
373
+ amt = PhantomStableMath._calcTokenOutGivenExactBptIn(
219
374
  _amplificationParameter,
220
375
  balances,
221
376
  indexOut,
@@ -232,7 +387,7 @@ export class PhantomStablePool extends BasePool {
232
387
  tokenAmountsIn.forEach(amountIn => {
233
388
  let amt: bigint;
234
389
  try {
235
- amt = StableMath._calcOutGivenIn(
390
+ amt = PhantomStableMath._calcOutGivenIn(
236
391
  _amplificationParameter,
237
392
  balances,
238
393
  indexIn,