Skip to content

Commit 7eaa6c8

Browse files
authored
Merge pull request #257 from bancorprotocol/fix-calculateLConstant
Fix function `calculateLConstant`
2 parents c83f52a + ce7d065 commit 7eaa6c8

File tree

2 files changed

+590
-269
lines changed

2 files changed

+590
-269
lines changed

src/adapters/uni-v3/adapter.ts

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Decimal, MAX_UINT256 } from '../../utils/numerics';
1+
import { BigNumber, Decimal, ONE } from '../../utils/numerics';
22
import { EncodedOrder, EncodedStrategy } from '../../common/types';
33
import { UniV3CastStrategy, UniV3Pool, UniV3Position } from './types';
44
import { decodeFloat, decodeOrder } from '../../utils/encoders';
@@ -28,65 +28,53 @@ function calculateImpliedTick(rate: Decimal, roundUp: boolean): number {
2828
*/
2929
function calculateLConstant(order: EncodedOrder): string {
3030
if (order.A.isZero()) {
31-
return MAX_UINT256.toString();
31+
return Infinity.toString();
3232
}
33-
return order.z.div(decodeFloat(order.A)).toString();
33+
return order.z.mul(ONE).div(decodeFloat(order.A)).toString();
3434
}
3535

36-
function calculateSqrtPriceX96(order: EncodedOrder): string {
37-
const decodedOrder = decodeOrder(order);
38-
const marginalRate = new Decimal(decodedOrder.marginalRate);
39-
const sqrtRate = marginalRate.sqrt();
36+
function calculateSqrtPriceX96(marginal: Decimal, roundUp: boolean): string {
37+
const sqrtRate = marginal.sqrt();
4038
const sqrtPriceX96 = sqrtRate.mul(new Decimal(2).pow(96));
41-
return sqrtPriceX96.floor().toString();
39+
return roundUp
40+
? sqrtPriceX96.ceil().toString()
41+
: sqrtPriceX96.floor().toString();
4242
}
4343

4444
/**
4545
* Calculates position information for a Carbon order
4646
* @param {EncodedOrder} order - The Carbon order
47-
* @param {boolean} isSellOrder - Whether this is a sell order
47+
* @param {boolean} invertRates - Whether to invert the rates
4848
* @returns {UniV3Position} The calculated Uniswap V3 position
4949
*/
5050
function calculatePositionInformation(
5151
order: EncodedOrder,
52-
isSellOrder: boolean
52+
invertRates: boolean
5353
): UniV3Position {
5454
const decodedOrder = decodeOrder(order);
5555
const priceLow = new Decimal(decodedOrder.lowestRate);
5656
const priceHigh = new Decimal(decodedOrder.highestRate);
57+
const priceMarginal = new Decimal(decodedOrder.marginalRate);
5758

58-
if (isSellOrder) {
59+
if (!invertRates) {
5960
return {
6061
tickUpper: calculateImpliedTick(priceHigh, true),
6162
tickLower: calculateImpliedTick(priceLow, false),
6263
liquidity: calculateLConstant(order),
63-
sqrtPriceX96: calculateSqrtPriceX96(order),
64+
sqrtPriceX96: calculateSqrtPriceX96(priceMarginal, false),
6465
};
6566
}
6667

6768
// For buy orders, invert the prices
68-
const invertedPriceLow = new Decimal(1).div(priceHigh);
69-
const invertedPriceHigh = new Decimal(1).div(priceLow);
69+
const invertedPriceHigh = new Decimal(1).div(priceHigh);
70+
const invertedPriceLow = new Decimal(1).div(priceLow);
71+
const invertedPriceMarginal = new Decimal(1).div(priceMarginal);
7072

7173
return {
72-
tickUpper: calculateImpliedTick(invertedPriceHigh, true),
73-
tickLower: calculateImpliedTick(invertedPriceLow, false),
74+
tickUpper: calculateImpliedTick(invertedPriceLow, true),
75+
tickLower: calculateImpliedTick(invertedPriceHigh, false),
7476
liquidity: calculateLConstant(order),
75-
sqrtPriceX96: calculateSqrtPriceX96(order),
76-
};
77-
}
78-
79-
/**
80-
* Defines the pool configuration for a token pair
81-
* @param {string} baseToken - The base token address
82-
* @param {string} quoteToken - The quote token address
83-
* @returns {UniV3Pool} The pool configuration
84-
*/
85-
function definePool(baseToken: string, quoteToken: string): UniV3Pool {
86-
return {
87-
xAxisToken: quoteToken,
88-
yAxisToken: baseToken,
89-
tickSpacing: DEFAULT_TICK_SPACING,
77+
sqrtPriceX96: calculateSqrtPriceX96(invertedPriceMarginal, true),
9078
};
9179
}
9280

@@ -96,12 +84,23 @@ function definePool(baseToken: string, quoteToken: string): UniV3Pool {
9684
* @returns {UniV3CastStrategy} The strategy in Uniswap V3 format
9785
*/
9886
export function castToUniV3(strategy: EncodedStrategy): UniV3CastStrategy {
99-
const pool = definePool(strategy.token0, strategy.token1);
87+
// use the token addresses to define which is the base token and which is the quote token. Base token is the token with the lowest address.
88+
89+
const addr0 = BigNumber.from(strategy.token0);
90+
const addr1 = BigNumber.from(strategy.token1);
91+
92+
const isToken0XAxis = addr0.lt(addr1);
93+
94+
const pool: UniV3Pool = {
95+
xAxisToken: isToken0XAxis ? strategy.token0 : strategy.token1,
96+
yAxisToken: isToken0XAxis ? strategy.token1 : strategy.token0,
97+
tickSpacing: DEFAULT_TICK_SPACING,
98+
};
10099

101100
return {
102101
pool,
103-
sellOrder: calculatePositionInformation(strategy.order0, true),
104-
buyOrder: calculatePositionInformation(strategy.order1, false),
102+
sellOrder: calculatePositionInformation(strategy.order0, isToken0XAxis),
103+
buyOrder: calculatePositionInformation(strategy.order1, !isToken0XAxis),
105104
};
106105
}
107106

0 commit comments

Comments
 (0)