Skip to content

Commit

Permalink
Merge pull request #341 from balancer-labs/develop
Browse files Browse the repository at this point in the history
Release 4.0.1-beta.17
  • Loading branch information
John Grant authored Jan 5, 2023
2 parents f2442fd + c2efa07 commit fb6b8c0
Show file tree
Hide file tree
Showing 29 changed files with 523 additions and 368 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@balancer-labs/sor",
"version": "4.0.1-beta.16",
"version": "4.0.1-beta.17",
"license": "GPL-3.0-only",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand Down
2 changes: 1 addition & 1 deletion src/frontendHelpers/stableHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function BPTForTokensZeroPriceImpact(
const amountBPTOut = amounts.reduce((totalBptOut, amountIn, i) => {
// Calculate amount of BPT gained per token in
const poolPairData: StablePoolPairData = {
amp: amp,
amp: BigNumber.from(amp),
allBalances: allBalancesDownScaled,
tokenIndexIn: i,
balanceOut: bptTotalSupply,
Expand Down
19 changes: 8 additions & 11 deletions src/pools/elementPool/elementPool.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BigNumber, formatFixed, parseFixed } from '@ethersproject/bignumber';
import { WeiPerEther as ONE, Zero } from '@ethersproject/constants';
import { isSameAddress } from '../../utils';
import { BigNumber as OldBigNumber, bnum } from '../../utils/bignumber';
import { BigNumber as OldBigNumber, bnum, ZERO } from '../../utils/bignumber';
import {
PoolBase,
PoolTypes,
Expand All @@ -20,6 +20,7 @@ import {
_derivativeSpotPriceAfterSwapTokenInForExactTokenOut,
getTimeTillExpiry,
} from './elementMath';
import { universalNormalizedLiquidity } from '../liquidity';

type ElementPoolToken = Pick<SubgraphToken, 'address' | 'balance' | 'decimals'>;

Expand All @@ -32,7 +33,7 @@ export type ElementPoolPairData = PoolPairBase & {
currentBlockTimestamp: number;
};

export class ElementPool implements PoolBase {
export class ElementPool implements PoolBase<ElementPoolPairData> {
poolType: PoolTypes = PoolTypes.Element;
id: string;
address: string;
Expand Down Expand Up @@ -147,16 +148,12 @@ export class ElementPool implements PoolBase {
return poolPairData;
}

// Normalized liquidity is an abstract term that can be thought of the
// inverse of the slippage. It is proportional to the token balances in the
// pool but also depends on the shape of the invariant curve.
// As a standard, we define normalized liquidity in tokenOut
getNormalizedLiquidity(poolPairData: ElementPoolPairData): OldBigNumber {
// This could be refined by using the inverse of the slippage, but
// in practice this won't have a big impact in path selection for
// multi-hops so not a big priority
return bnum(
formatFixed(poolPairData.balanceOut, poolPairData.decimalsOut)
return universalNormalizedLiquidity(
this._derivativeSpotPriceAfterSwapExactTokenInForTokenOut(
poolPairData,
ZERO
)
);
}

Expand Down
31 changes: 8 additions & 23 deletions src/pools/gyro2Pool/gyro2Pool.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getAddress } from '@ethersproject/address';
import { WeiPerEther as ONE, Zero } from '@ethersproject/constants';
import { formatFixed, BigNumber } from '@ethersproject/bignumber';
import { BigNumber as OldBigNumber, bnum } from '../../utils/bignumber';
import { BigNumber as OldBigNumber, bnum, ZERO } from '../../utils/bignumber';

import {
PoolBase,
Expand All @@ -20,7 +20,6 @@ import {
_calculateNewSpotPrice,
_derivativeSpotPriceAfterSwapExactTokenInForTokenOut,
_derivativeSpotPriceAfterSwapTokenInForExactTokenOut,
_getNormalizedLiquidity,
} from './gyro2Math';
import {
_normalizeBalances,
Expand All @@ -29,6 +28,7 @@ import {
} from '../gyroHelpers/helpers';
import { mulDown, divDown } from '../gyroHelpers/gyroSignedFixedPoint';
import { SWAP_LIMIT_FACTOR } from '../gyroHelpers/constants';
import { universalNormalizedLiquidity } from '../liquidity';

export type Gyro2PoolPairData = PoolPairBase & {
sqrtAlpha: BigNumber;
Expand All @@ -40,7 +40,7 @@ export type Gyro2PoolToken = Pick<
'address' | 'balance' | 'decimals'
>;

export class Gyro2Pool implements PoolBase {
export class Gyro2Pool implements PoolBase<Gyro2PoolPairData> {
poolType: PoolTypes = PoolTypes.Gyro2;
id: string;
address: string;
Expand Down Expand Up @@ -131,27 +131,12 @@ export class Gyro2Pool implements PoolBase {
}

getNormalizedLiquidity(poolPairData: Gyro2PoolPairData): OldBigNumber {
const balances = [poolPairData.balanceIn, poolPairData.balanceOut];
const normalizedBalances = _normalizeBalances(balances, [
poolPairData.decimalsIn,
poolPairData.decimalsOut,
]);
const invariant = _calculateInvariant(
normalizedBalances,
poolPairData.sqrtAlpha,
poolPairData.sqrtBeta
return universalNormalizedLiquidity(
this._derivativeSpotPriceAfterSwapExactTokenInForTokenOut(
poolPairData,
ZERO
)
);
const [, virtualParamOut] = _findVirtualParams(
invariant,
poolPairData.sqrtAlpha,
poolPairData.sqrtBeta
);
const normalisedLiquidity = _getNormalizedLiquidity(
normalizedBalances,
virtualParamOut
);

return bnum(formatFixed(normalisedLiquidity, 18));
}

getLimitAmountSwap(
Expand Down
35 changes: 8 additions & 27 deletions src/pools/gyro3Pool/gyro3Pool.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getAddress } from '@ethersproject/address';
import { WeiPerEther as ONE, Zero } from '@ethersproject/constants';
import { formatFixed, BigNumber } from '@ethersproject/bignumber';
import { BigNumber as OldBigNumber, bnum } from '../../utils/bignumber';
import { BigNumber as OldBigNumber, bnum, ZERO } from '../../utils/bignumber';

import {
PoolBase,
Expand All @@ -19,7 +19,6 @@ import {
_calculateNewSpotPrice,
_derivativeSpotPriceAfterSwapExactTokenInForTokenOut,
_derivativeSpotPriceAfterSwapTokenInForExactTokenOut,
_getNormalizedLiquidity,
} from './gyro3Math';

import {
Expand All @@ -29,6 +28,7 @@ import {
} from '../gyroHelpers/helpers';
import { mulDown, divDown } from '../gyroHelpers/gyroSignedFixedPoint';
import { SWAP_LIMIT_FACTOR } from '../gyroHelpers/constants';
import { universalNormalizedLiquidity } from '../liquidity';

export type Gyro3PoolPairData = PoolPairBase & {
balanceTertiary: BigNumber; // Balance of the unchanged asset
Expand All @@ -40,7 +40,7 @@ export type Gyro3PoolToken = Pick<
'address' | 'balance' | 'decimals'
>;

export class Gyro3Pool implements PoolBase {
export class Gyro3Pool implements PoolBase<Gyro3PoolPairData> {
poolType: PoolTypes = PoolTypes.Gyro3;
id: string;
address: string;
Expand Down Expand Up @@ -147,31 +147,12 @@ export class Gyro3Pool implements PoolBase {
}

getNormalizedLiquidity(poolPairData: Gyro3PoolPairData): OldBigNumber {
const balances = [
poolPairData.balanceIn,
poolPairData.balanceOut,
poolPairData.balanceTertiary,
];
const decimals = [
poolPairData.decimalsIn,
poolPairData.decimalsOut,
poolPairData.decimalsTertiary,
];
const normalizedBalances = _normalizeBalances(balances, decimals);

const invariant = _calculateInvariant(
normalizedBalances,
this.root3Alpha
return universalNormalizedLiquidity(
this._derivativeSpotPriceAfterSwapExactTokenInForTokenOut(
poolPairData,
ZERO
)
);

const virtualOffsetInOut = mulDown(invariant, this.root3Alpha);

const normalisedLiquidity = _getNormalizedLiquidity(
normalizedBalances,
virtualOffsetInOut
);

return bnum(formatFixed(normalisedLiquidity, 18));
}

getLimitAmountSwap(
Expand Down
42 changes: 8 additions & 34 deletions src/pools/gyroEPool/gyroEPool.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getAddress } from '@ethersproject/address';
import { WeiPerEther as ONE, Zero } from '@ethersproject/constants';
import { formatFixed, BigNumber } from '@ethersproject/bignumber';
import { BigNumber as OldBigNumber, bnum } from '../../utils/bignumber';
import { BigNumber as OldBigNumber, bnum, ZERO } from '../../utils/bignumber';

import {
PoolBase,
Expand Down Expand Up @@ -32,9 +32,9 @@ import {
calcSpotPriceAfterSwapInGivenOut,
calcDerivativePriceAfterSwapOutGivenIn,
calcDerivativeSpotPriceAfterSwapInGivenOut,
calculateNormalizedLiquidity,
} from './gyroEMath/gyroEMath';
import { SWAP_LIMIT_FACTOR } from '../gyroHelpers/constants';
import { universalNormalizedLiquidity } from '../liquidity';

export type GyroEPoolPairData = PoolPairBase & {
tokenInIsToken0: boolean;
Expand Down Expand Up @@ -64,7 +64,7 @@ type DerivedGyroEParamsFromSubgraph = {
dSq: string;
};

export class GyroEPool implements PoolBase {
export class GyroEPool implements PoolBase<GyroEPoolPairData> {
poolType: PoolTypes = PoolTypes.GyroE;
id: string;
address: string;
Expand Down Expand Up @@ -212,38 +212,12 @@ export class GyroEPool implements PoolBase {
}

getNormalizedLiquidity(poolPairData: GyroEPoolPairData): OldBigNumber {
const normalizedBalances = normalizeBalances(
[poolPairData.balanceIn, poolPairData.balanceOut],
[poolPairData.decimalsIn, poolPairData.decimalsOut]
);

const orderedNormalizedBalances = balancesFromTokenInOut(
normalizedBalances[0],
normalizedBalances[1],
poolPairData.tokenInIsToken0
);

const [currentInvariant, invErr] = calculateInvariantWithError(
orderedNormalizedBalances,
this.gyroEParams,
this.derivedGyroEParams
);

const invariant: Vector2 = {
x: currentInvariant.add(invErr.mul(2)),
y: currentInvariant,
};

const normalizedLiquidity = calculateNormalizedLiquidity(
orderedNormalizedBalances,
this.gyroEParams,
this.derivedGyroEParams,
invariant,
this.swapFee,
poolPairData.tokenInIsToken0
return universalNormalizedLiquidity(
this._derivativeSpotPriceAfterSwapExactTokenInForTokenOut(
poolPairData,
ZERO
)
);

return bnum(formatFixed(normalizedLiquidity, 18));
}

getLimitAmountSwap(
Expand Down
8 changes: 5 additions & 3 deletions src/pools/linearPool/linearPool.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BigNumber, parseFixed, formatFixed } from '@ethersproject/bignumber';
import { bnum, scale, ZERO } from '../../utils/bignumber';
import { bnum, INFINITY, scale, ZERO } from '../../utils/bignumber';
import { BigNumber as OldBigNumber } from '../../utils/bignumber';
import { WeiPerEther as ONE, Zero } from '@ethersproject/constants';
import { isSameAddress } from '../../utils';
Expand Down Expand Up @@ -65,7 +65,7 @@ export type LinearPoolPairData = PoolPairBase & {
virtualBptSupply: BigNumber;
};

export class LinearPool implements PoolBase {
export class LinearPool implements PoolBase<LinearPoolPairData> {
poolType: PoolTypes = PoolTypes.Linear;
id: string;
address: string;
Expand Down Expand Up @@ -203,7 +203,9 @@ export class LinearPool implements PoolBase {

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getNormalizedLiquidity(poolPairData: LinearPoolPairData): OldBigNumber {
return bnum(0);
return INFINITY; // It is the inverse of zero
// This is correct since linear pools have no price impact,
// except for the swap fee that is expected to be small.
}

getLimitAmountSwap(
Expand Down
13 changes: 13 additions & 0 deletions src/pools/liquidity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { BigNumber as OldBigNumber, ZERO, bnum } from '../utils/bignumber';

/*
It is possible to compute the normalized liquidity using another function already existing at every pool type, which is the derivative of spot price after swap.
https://quark-ceres-740.notion.site/SOR-Normalized-liquidity-and-highest-liquidity-pool-d81bd3db48e5482ab2275a8eecac33b4
*/
export function universalNormalizedLiquidity(
derivativeSpotPriceAtZero: OldBigNumber
): OldBigNumber {
const ans = bnum(1).div(derivativeSpotPriceAtZero);
if (ans.isNaN() || ans.lt(ZERO) || !ans.isFinite()) return ZERO;
return ans;
}
Loading

0 comments on commit fb6b8c0

Please sign in to comment.