Skip to content

Commit

Permalink
Merge pull request #335 from balancer-labs/develop
Browse files Browse the repository at this point in the history
Release 4.0.1-beta.16
  • Loading branch information
John Grant authored Dec 13, 2022
2 parents 9b68ea4 + 292cfe3 commit f2442fd
Show file tree
Hide file tree
Showing 30 changed files with 248 additions and 155 deletions.
2 changes: 1 addition & 1 deletion hardhat.config.js → hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require('@nomiclabs/hardhat-ethers');
import '@nomiclabs/hardhat-ethers';

/**
* @type import('hardhat/config').HardhatUserConfig
Expand Down
6 changes: 3 additions & 3 deletions 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.15",
"version": "4.0.1-beta.16",
"license": "GPL-3.0-only",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand All @@ -11,11 +11,11 @@
"test": "TS_NODE_PROJECT='tsconfig.testing.json' nyc mocha -r ts-node/register test/*.spec.ts",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"lint": "eslint ./src ./test --ext .ts --max-warnings 0",
"node": "npx hardhat node --fork $(grep ALCHEMY_URL .env | cut -d '=' -f2) --fork-block-number 14828550"
"node": "npx hardhat node --tsconfig tsconfig.testing.json --fork $(grep ALCHEMY_URL .env | cut -d '=' -f2) --fork-block-number 14828550"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
"pre-commit": "pretty-quick --staged && yarn run lint"
}
},
"publishConfig": {
Expand Down
9 changes: 1 addition & 8 deletions src/frontendHelpers/queryBatchSwapHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import { BigNumberish } from '@ethersproject/bignumber';
import { Contract } from '@ethersproject/contracts';
import { AddressZero } from '@ethersproject/constants';
import { SwapTypes, SwapInfo, SwapV2 } from '../types';
import { SwapTypes, SwapInfo, SwapV2, FundManagement } from '../types';
import { SOR } from '../index';

type FundManagement = {
sender: string;
recipient: string;
fromInternalBalance: boolean;
toInternalBalance: boolean;
};

/*
* queryBatchSwap simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be
* simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result.
Expand Down
2 changes: 2 additions & 0 deletions src/pools/elementPool/elementPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,13 @@ export class ElementPool implements PoolBase {
return _tokenInForExactTokenOut(amount, poolPairData);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcTokensOutGivenExactBptIn(bptAmountIn: BigNumber): BigNumber[] {
// Missing maths for this
return new Array(this.tokens.length).fill(Zero);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcBptOutGivenExactTokensIn(amountsIn: BigNumber[]): BigNumber {
// Missing maths for this
return Zero;
Expand Down
2 changes: 2 additions & 0 deletions src/pools/gyro2Pool/gyro2Pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,13 @@ export class Gyro2Pool implements PoolBase {
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcTokensOutGivenExactBptIn(bptAmountIn: BigNumber): BigNumber[] {
// Missing maths for this
return new Array(this.tokens.length).fill(Zero);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcBptOutGivenExactTokensIn(amountsIn: BigNumber[]): BigNumber {
// Missing maths for this
return Zero;
Expand Down
2 changes: 2 additions & 0 deletions src/pools/gyro3Pool/gyro3Pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,13 @@ export class Gyro3Pool implements PoolBase {
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcTokensOutGivenExactBptIn(bptAmountIn: BigNumber): BigNumber[] {
// Missing maths for this
return new Array(this.tokens.length).fill(Zero);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcBptOutGivenExactTokensIn(amountsIn: BigNumber[]): BigNumber {
// Missing maths for this
return Zero;
Expand Down
4 changes: 3 additions & 1 deletion src/pools/gyroEPool/gyroEMath/gyroEMath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ export function calculateInvariantWithError(
if (x.add(y).gt(MAX_BALANCES)) throw new Error('MAX ASSETS EXCEEDED');
const AtAChi = calcAtAChi(x, y, params, derived);

let [square_root, err] = calcInvariantSqrt(x, y, params, derived);
const invariantResult = calcInvariantSqrt(x, y, params, derived);
const square_root = invariantResult[0];
let err = invariantResult[1];

if (square_root.gt(0)) {
err = divUpMagU(err.add(1), square_root.mul(2));
Expand Down
2 changes: 2 additions & 0 deletions src/pools/gyroEPool/gyroEPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,13 @@ export class GyroEPool implements PoolBase {
return bnum(formatFixed(inAmount, 18));
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcTokensOutGivenExactBptIn(bptAmountIn: BigNumber): BigNumber[] {
// Missing maths for this
return new Array(this.tokens.length).fill(Zero);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcBptOutGivenExactTokensIn(amountsIn: BigNumber[]): BigNumber {
// Missing maths for this
return Zero;
Expand Down
1 change: 1 addition & 0 deletions src/pools/lido/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,7 @@ function calculateMarketSp(
if (!newPool) return bnum(0);

// Parses relevant balances, etc
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const poolPairData: any = newPool.parsePoolPairData(
assets[swap.assetInIndex],
assets[swap.assetOutIndex]
Expand Down
3 changes: 3 additions & 0 deletions src/pools/linearPool/linearPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ export class LinearPool implements PoolBase {
return poolPairData;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getNormalizedLiquidity(poolPairData: LinearPoolPairData): OldBigNumber {
return bnum(0);
}
Expand Down Expand Up @@ -755,11 +756,13 @@ export class LinearPool implements PoolBase {
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcTokensOutGivenExactBptIn(bptAmountIn: BigNumber): BigNumber[] {
// Linear Pool doesn't have Exit Pool implementation
return new Array(this.tokens.length).fill(Zero);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
_calcBptOutGivenExactTokensIn(amountsIn: BigNumber[]): BigNumber {
// Linear Pool doesn't have Join Pool implementation
return Zero;
Expand Down
76 changes: 35 additions & 41 deletions src/pools/stablePool/stableMathBigInt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ import { MathSol, BZERO } from '../../utils/basicOperations';

const AMP_PRECISION = BigInt(1e3);

function _calculateInvariant(
amp: bigint,
balances: bigint[],
roundUp: boolean
): bigint {
function _calculateInvariant(amp: bigint, balances: bigint[]): bigint {
/**********************************************************************************************
// invariant //
// D = invariant D^(n+1) //
Expand All @@ -26,7 +22,7 @@ function _calculateInvariant(
// n = number of tokens //
*********x************************************************************************************/

// We support rounding up or down.
// Always round down, to match Vyper's arithmetic (which always truncates).

let sum = BZERO;
const numTokens = balances.length;
Expand All @@ -42,30 +38,30 @@ function _calculateInvariant(
const ampTimesTotal = amp * BigInt(numTokens);

for (let i = 0; i < 255; i++) {
let P_D = balances[0] * BigInt(numTokens);
for (let j = 1; j < numTokens; j++) {
P_D = MathSol.div(
MathSol.mul(MathSol.mul(P_D, balances[j]), BigInt(numTokens)),
invariant,
roundUp
let D_P = invariant;
for (let j = 0; j < numTokens; j++) {
// (D_P * invariant) / (balances[j] * numTokens)
D_P = MathSol.divDown(
MathSol.mul(D_P, invariant),
MathSol.mul(balances[j], BigInt(numTokens))
);
}

prevInvariant = invariant;
invariant = MathSol.div(
MathSol.mul(MathSol.mul(BigInt(numTokens), invariant), invariant) +
MathSol.div(
MathSol.mul(MathSol.mul(ampTimesTotal, sum), P_D),
AMP_PRECISION,
roundUp
),
MathSol.mul(BigInt(numTokens + 1), invariant) +
// No need to use checked arithmetic for the amp precision, the amp is guaranteed to be at least 1
MathSol.div(
MathSol.mul(ampTimesTotal - AMP_PRECISION, P_D),
AMP_PRECISION,
!roundUp
),
roundUp
invariant = MathSol.divDown(
MathSol.mul(
// (ampTimesTotal * sum) / AMP_PRECISION + D_P * numTokens
MathSol.divDown(
MathSol.mul(ampTimesTotal, sum),
AMP_PRECISION
) + MathSol.mul(D_P, BigInt(numTokens)),
invariant
),
// ((ampTimesTotal - _AMP_PRECISION) * invariant) / _AMP_PRECISION + (numTokens + 1) * D_P
MathSol.divDown(
MathSol.mul(ampTimesTotal - AMP_PRECISION, invariant),
AMP_PRECISION
) + MathSol.mul(BigInt(numTokens + 1), D_P)
);

if (invariant > prevInvariant) {
Expand All @@ -76,7 +72,6 @@ function _calculateInvariant(
return invariant;
}
}

throw new Error('Errors.STABLE_INVARIANT_DIDNT_CONVERGE');
}

Expand All @@ -91,8 +86,7 @@ export function _calcOutGivenIn(
fee: bigint
): bigint {
amountIn = subtractFee(amountIn, fee);
// Given that we need to have a greater final balance out, the invariant needs to be rounded up
const invariant = _calculateInvariant(amp, balances, true);
const invariant = _calculateInvariant(amp, balances);

const initBalance = balances[tokenIndexIn];
balances[tokenIndexIn] = initBalance + amountIn;
Expand All @@ -113,7 +107,7 @@ export function _calcInGivenOut(
amountOut: bigint,
fee: bigint
): bigint {
const invariant = _calculateInvariant(amp, balances, true);
const invariant = _calculateInvariant(amp, balances);
balances[tokenIndexOut] = MathSol.sub(balances[tokenIndexOut], amountOut);

const finalBalanceIn = _getTokenBalanceGivenInvariantAndAllOtherBalances(
Expand Down Expand Up @@ -188,8 +182,9 @@ export function _calcBptOutGivenExactTokensIn(
}

// Get current and new invariants, taking swap fees into account
const currentInvariant = _calculateInvariant(amp, balances, true);
const newInvariant = _calculateInvariant(amp, newBalances, false);
const currentInvariant = _calculateInvariant(amp, balances);
const newInvariant = _calculateInvariant(amp, newBalances);

const invariantRatio = MathSol.divDownFixed(newInvariant, currentInvariant);

// If the invariant didn't increase for any reason, we simply don't mint BPT
Expand All @@ -212,7 +207,7 @@ export function _calcTokenInGivenExactBptOut(
fee: bigint
): bigint {
// Token in, so we round up overall.
const currentInvariant = _calculateInvariant(amp, balances, true);
const currentInvariant = _calculateInvariant(amp, balances);
const newInvariant = MathSol.mulUpFixed(
MathSol.divUpFixed(
MathSol.add(bptTotalSupply, bptAmountOut),
Expand Down Expand Up @@ -322,8 +317,8 @@ export function _calcBptInGivenExactTokensOut(
}

// Get current and new invariants, taking into account swap fees
const currentInvariant = _calculateInvariant(amp, balances, true);
const newInvariant = _calculateInvariant(amp, newBalances, false);
const currentInvariant = _calculateInvariant(amp, balances);
const newInvariant = _calculateInvariant(amp, newBalances);
const invariantRatio = MathSol.divDownFixed(newInvariant, currentInvariant);

// return amountBPTIn
Expand All @@ -343,8 +338,7 @@ export function _calcTokenOutGivenExactBptIn(
): bigint {
// Token out, so we round down overall.

// Get the current and new invariants. Since we need a bigger new invariant, we round the current one up.
const currentInvariant = _calculateInvariant(amp, balances, true);
const currentInvariant = _calculateInvariant(amp, balances);
const newInvariant = MathSol.mulUpFixed(
MathSol.divUpFixed(bptTotalSupply - bptAmountIn, bptTotalSupply),
currentInvariant
Expand Down Expand Up @@ -540,7 +534,7 @@ export function _spotPriceAfterSwapTokenInForExactTokenOut(
tokenIndexOut: number,
amountOut: bigint,
fee: bigint
): BigInt {
): bigint {
const balancesCopy = [...balances];
const _in = _calcInGivenOut(
amp,
Expand Down Expand Up @@ -714,7 +708,7 @@ export function _poolDerivatives(
wrt_out: boolean
): bigint {
const totalCoins = balances.length;
const D = _calculateInvariant(amp, balances, true);
const D = _calculateInvariant(amp, balances);
let S = BigInt(0);
for (let i = 0; i < totalCoins; i++) {
if (i != tokenIndexIn && i != tokenIndexOut) {
Expand Down Expand Up @@ -765,7 +759,7 @@ export function _poolDerivativesBPT(
wrt_out: boolean
): bigint {
const totalCoins = balances.length;
const D = _calculateInvariant(amp, balances, true);
const D = _calculateInvariant(amp, balances);
let S = BigInt(0);
let D_P = D / BigInt(totalCoins);
for (let i = 0; i < totalCoins; i++) {
Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,10 @@ export interface TokenPriceService {
export interface PoolDataService {
getPools(): Promise<SubgraphPoolBase[]>;
}

export type FundManagement = {
sender: string;
recipient: string;
fromInternalBalance: boolean;
toInternalBalance: boolean;
};
Loading

0 comments on commit f2442fd

Please sign in to comment.