Skip to content

Commit

Permalink
Merge develop.
Browse files Browse the repository at this point in the history
  • Loading branch information
johngrantuk committed Jun 22, 2022
2 parents d33d587 + 32d8a8d commit b4a31bf
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 42 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.0-beta.8",
"version": "4.0.0-beta.9",
"license": "GPL-3.0-only",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand Down
75 changes: 59 additions & 16 deletions src/pools/metaStablePool/metaStablePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
_calcOutGivenIn,
_calcInGivenOut,
} from '../stablePool/stableMathBigInt';
import { StablePoolPairData } from 'pools/stablePool/stablePool';
import { StablePoolPairData } from '../stablePool/stablePool';

type MetaStablePoolToken = Pick<
SubgraphToken,
Expand Down Expand Up @@ -198,22 +198,31 @@ export class MetaStablePool implements PoolBase {
if (amount.isZero()) return ZERO;
// All values should use 1e18 fixed point
// i.e. 1USDC => 1e18 not 1e6
const amountConvertedEvm = parseFixed(amount.dp(18).toString(), 18)

const amtWithFee = this.subtractSwapFeeAmount(
parseFixed(
amount.dp(poolPairData.decimalsIn).toString(),
poolPairData.decimalsIn
),
poolPairData.swapFee
);

const amountConverted = amtWithFee
.mul(poolPairData.tokenInPriceRate)
.div(ONE);

const returnEvm = _calcOutGivenIn(
const returnAmt = _calcOutGivenIn(
this.amp.toBigInt(),
poolPairData.allBalancesScaled.map((balance) =>
balance.toBigInt()
),
poolPairData.tokenIndexIn,
poolPairData.tokenIndexOut,
amountConvertedEvm.toBigInt(),
poolPairData.swapFee.toBigInt()
amountConverted.toBigInt(),
BigInt(0)
);

const returnEvmWithRate = BigNumber.from(returnEvm)
const returnEvmWithRate = BigNumber.from(returnAmt)
.mul(ONE)
.div(poolPairData.tokenOutPriceRate);

Expand All @@ -230,28 +239,50 @@ export class MetaStablePool implements PoolBase {
): OldBigNumber {
try {
if (amount.isZero()) return ZERO;
const decimalsIn = poolPairData.decimalsIn;
const decimalsOut = poolPairData.decimalsOut;

// All values should use 1e18 fixed point
// i.e. 1USDC => 1e18 not 1e6
const amountConvertedEvm = parseFixed(amount.dp(18).toString(), 18)
.mul(poolPairData.tokenOutPriceRate)
.div(ONE);
const scalingFactorIn =
poolPairData.tokenInPriceRate.toBigInt() *
BigInt(10 ** (18 - decimalsIn));

const scalingFactorOut =
poolPairData.tokenOutPriceRate.toBigInt() *
BigInt(10 ** (18 - decimalsOut));

// eslint-disable-next-line prettier/prettier
const amountBigInt = BigInt(
amount
.times(10 ** decimalsOut)
.dp(0)
.toString()
);
const amountConverted =
(amountBigInt * scalingFactorOut) / BigInt(10 ** 18);

const returnEvm = _calcInGivenOut(
const returnAmount = _calcInGivenOut(
this.amp.toBigInt(),
poolPairData.allBalancesScaled.map((balance) =>
balance.toBigInt()
),
poolPairData.tokenIndexIn,
poolPairData.tokenIndexOut,
amountConvertedEvm.toBigInt(),
poolPairData.swapFee.toBigInt()
amountConverted,
BigInt(0)
);

const returnEvmWithRate = BigNumber.from(returnEvm)
.mul(ONE)
.div(poolPairData.tokenInPriceRate);
const returnAmountConverted =
(returnAmount * BigInt(10 ** 18)) / scalingFactorIn;

return bnum(formatFixed(returnEvmWithRate, 18));
const returnAmtWithFee = this.addSwapFeeAmount(
BigNumber.from(returnAmountConverted),
poolPairData.swapFee
);
return bnum(returnAmtWithFee.toString()).div(
10 ** poolPairData.decimalsIn
);
} catch (err) {
console.error(`_evminGivenOut: ${err.message}`);
return ZERO;
Expand Down Expand Up @@ -315,4 +346,16 @@ export class MetaStablePool implements PoolBase {
.times(priceRateOut)
.times(priceRateOut);
}

subtractSwapFeeAmount(amount: BigNumber, swapFee: BigNumber): BigNumber {
// https://github.com/balancer-labs/balancer-v2-monorepo/blob/c18ff2686c61a8cbad72cdcfc65e9b11476fdbc3/pkg/pool-utils/contracts/BasePool.sol#L466
const feeAmount = amount.mul(swapFee).add(ONE.sub(1)).div(ONE);
return amount.sub(feeAmount);
}

addSwapFeeAmount(amount: BigNumber, swapFee: BigNumber): BigNumber {
// https://github.com/balancer-labs/balancer-v2-monorepo/blob/c18ff2686c61a8cbad72cdcfc65e9b11476fdbc3/pkg/pool-utils/contracts/BasePool.sol#L458
const feeAmount = ONE.sub(swapFee);
return amount.mul(ONE).add(feeAmount.sub(1)).div(feeAmount);
}
}
10 changes: 7 additions & 3 deletions src/pools/phantomStablePool/phantomStablePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ export class PhantomStablePool implements PoolBase {
amount: OldBigNumber
): OldBigNumber {
try {
// This code assumes that decimalsIn and decimalsOut is 18

if (amount.isZero()) return ZERO;
// All values should use 1e18 fixed point
// i.e. 1USDC => 1e18 not 1e6
Expand Down Expand Up @@ -301,6 +303,8 @@ export class PhantomStablePool implements PoolBase {
amount: OldBigNumber
): OldBigNumber {
try {
// This code assumes that decimalsIn and decimalsOut is 18

if (amount.isZero()) return ZERO;
// All values should use 1e18 fixed point
// i.e. 1USDC => 1e18 not 1e6
Expand Down Expand Up @@ -331,7 +335,7 @@ export class PhantomStablePool implements PoolBase {
poolPairData.allBalancesScaled.map((b) => b.toBigInt()),
amountsOutBigInt,
poolPairData.virtualBptSupply.toBigInt(),
BigInt(0) // Fee is handled above
BigInt(0) // Fee is handled below
);
} else {
returnEvm = _calcInGivenOut(
Expand All @@ -340,7 +344,7 @@ export class PhantomStablePool implements PoolBase {
poolPairData.tokenIndexIn,
poolPairData.tokenIndexOut,
amountConvertedEvm.toBigInt(),
BigInt(0) // Fee is handled above
BigInt(0) // Fee is handled below
);
}
// In Phantom Pools every time there is a swap (token per token, bpt per token or token per bpt), we substract the fee from the amount in
Expand Down Expand Up @@ -488,7 +492,7 @@ export class PhantomStablePool implements PoolBase {

subtractSwapFeeAmount(amount: BigNumber, swapFee: BigNumber): BigNumber {
// https://github.com/balancer-labs/balancer-v2-monorepo/blob/c18ff2686c61a8cbad72cdcfc65e9b11476fdbc3/pkg/pool-utils/contracts/BasePool.sol#L466
const feeAmount = amount.mul(swapFee).div(ONE);
const feeAmount = amount.mul(swapFee).add(ONE.sub(1)).div(ONE);
return amount.sub(feeAmount);
}

Expand Down
50 changes: 39 additions & 11 deletions src/pools/stablePool/stablePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,20 @@ export class StablePool implements PoolBase {
): OldBigNumber {
try {
if (amount.isZero()) return ZERO;

const amtWithFeeEvm = this.subtractSwapFeeAmount(
parseFixed(
amount.dp(poolPairData.decimalsIn).toString(),
poolPairData.decimalsIn
),
poolPairData.swapFee
);

// All values should use 1e18 fixed point
// i.e. 1USDC => 1e18 not 1e6
const amtScaled = parseFixed(amount.dp(18).toString(), 18);
const amtScaled = amtWithFeeEvm.mul(
10 ** (18 - poolPairData.decimalsIn)
);

const amt = _calcOutGivenIn(
this.amp.toBigInt(),
Expand All @@ -188,8 +199,9 @@ export class StablePool implements PoolBase {
poolPairData.tokenIndexIn,
poolPairData.tokenIndexOut,
amtScaled.toBigInt(),
poolPairData.swapFee.toBigInt()
BigInt(0)
);

// return normalised amount
// Using BigNumber.js decimalPlaces (dp), allows us to consider token decimal accuracy correctly,
// i.e. when using token with 2decimals 0.002 should be returned as 0
Expand All @@ -214,23 +226,27 @@ export class StablePool implements PoolBase {
// i.e. 1USDC => 1e18 not 1e6
const amtScaled = parseFixed(amount.dp(18).toString(), 18);

const amt = _calcInGivenOut(
let amt = _calcInGivenOut(
this.amp.toBigInt(),
poolPairData.allBalancesScaled.map((balance) =>
balance.toBigInt()
),
poolPairData.tokenIndexIn,
poolPairData.tokenIndexOut,
amtScaled.toBigInt(),
poolPairData.swapFee.toBigInt()
BigInt(0)
);
// return normalised amount
// Using BigNumber.js decimalPlaces (dp), allows us to consider token decimal accuracy correctly,
// i.e. when using token with 2decimals 0.002 should be returned as 0
// Uses ROUND_UP mode (0)
return scale(bnum(amt.toString()), -18).dp(
poolPairData.decimalsIn,
0

// this is downscaleUp
const scaleFactor = BigInt(10 ** (18 - poolPairData.decimalsIn));
amt = (amt + scaleFactor - BigInt(1)) / scaleFactor;

const amtWithFee = this.addSwapFeeAmount(
BigNumber.from(amt),
poolPairData.swapFee
);
return bnum(amtWithFee.toString()).div(
10 ** poolPairData.decimalsIn
);
} catch (err) {
console.error(`_evminGivenOut: ${err.message}`);
Expand Down Expand Up @@ -271,4 +287,16 @@ export class StablePool implements PoolBase {
poolPairData
);
}

subtractSwapFeeAmount(amount: BigNumber, swapFee: BigNumber): BigNumber {
// https://github.com/balancer-labs/balancer-v2-monorepo/blob/c18ff2686c61a8cbad72cdcfc65e9b11476fdbc3/pkg/pool-utils/contracts/BasePool.sol#L466
const feeAmount = amount.mul(swapFee).add(ONE.sub(1)).div(ONE);
return amount.sub(feeAmount);
}

addSwapFeeAmount(amount: BigNumber, swapFee: BigNumber): BigNumber {
// https://github.com/balancer-labs/balancer-v2-monorepo/blob/c18ff2686c61a8cbad72cdcfc65e9b11476fdbc3/pkg/pool-utils/contracts/BasePool.sol#L458
const feeAmount = ONE.sub(swapFee);
return amount.mul(ONE).add(feeAmount.sub(1)).div(feeAmount);
}
}
30 changes: 21 additions & 9 deletions test/metaStablePools.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,15 +488,22 @@ describe(`Tests for MetaStable Pools.`, () => {
);
expect(swapInfoStable.tokenIn).to.deep.eq(swapInfo.tokenIn);
expect(swapInfoStable.tokenOut).to.deep.eq(swapInfo.tokenOut);
expect(swapInfoStable.returnAmount.toString()).eq(
swapInfo.returnAmount.mul(tokenInPriceRate).div(ONE).toString()
);
expect(swapInfoStable.returnAmountConsideringFees.toString()).eq(
swapInfo.returnAmountConsideringFees
.mul(tokenInPriceRate)
.div(ONE)
.toString()
);
expect(
almostEqual(
swapInfoStable.returnAmount,
swapInfo.returnAmount.mul(tokenInPriceRate).div(ONE)
),
'they are not almost equal'
).eq(true);
expect(
almostEqual(
swapInfoStable.returnAmountConsideringFees,
swapInfo.returnAmountConsideringFees
.mul(tokenInPriceRate)
.div(ONE)
),
'they are not almost equal'
).eq(true);
expect(swapInfoStable.swaps.length).eq(swapInfo.swaps.length);
swapInfoStable.swaps.forEach((swapStable, i) => {
expect(swapStable.poolId).eq(swapInfo.swaps[i].poolId);
Expand Down Expand Up @@ -750,3 +757,8 @@ describe(`Tests for MetaStable Pools.`, () => {
// });
});
});

function almostEqual(arg1: BigNumber, arg2: BigNumber): boolean {
const diff = arg1.sub(arg2).toBigInt();
return diff == BigInt(0) || diff == BigInt(1) || diff == BigInt(-1);
}
4 changes: 2 additions & 2 deletions test/stablePools.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ describe(`Tests for Stable Pools.`, () => {
console.log(`Return amt:`);
console.log(swapInfo.returnAmount.toString());
// This value is hard coded as sanity check if things unexpectedly change. Taken from V2 test run (with extra fee logic added).
expect(swapInfo.returnAmount.toString()).eq('1000401');
expect(swapInfo.returnAmount.toString()).eq('1000402');
expect(swapInfo.swaps.length).eq(1);
expect(swapInfo.swaps[0].amount.toString()).eq(swapAmt.toString());
expect(swapInfo.swaps[0].poolId).eq(poolsFromFile.pools[0].id);
Expand Down Expand Up @@ -336,7 +336,7 @@ describe(`Tests for Stable Pools.`, () => {
);

// This value is hard coded as sanity check if things unexpectedly change. Taken from V2 test run (with extra fee logic added).
expect(swapInfo.returnAmount.toString()).eq('18089532');
expect(swapInfo.returnAmount.toString()).eq('18089534');
expect(swapInfo.swaps.length).eq(2);
expect(swapInfo.swaps[0].amount.toString()).eq(swapAmt.toString());
expect(swapInfo.swaps[0].poolId).eq(
Expand Down
5 changes: 5 additions & 0 deletions test/testScripts/swapExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ export const ADDRESSES = {
decimals: 18,
symbol: 'bbausdc',
},
bbadai: {
address: '0x804cdb9116a10bb78768d3252355a1b18067bf8f',
decimals: 18,
symbol: 'bb-a-dai',
},
waDAI: {
address: '0x02d60b84491589974263d922d9cc7a3152618ef6',
decimals: 18,
Expand Down

0 comments on commit b4a31bf

Please sign in to comment.