From 832a3502567cc2edfb338672d8fe064042b554fb Mon Sep 17 00:00:00 2001 From: sergioyuhjtman Date: Mon, 15 Aug 2022 15:50:13 -0300 Subject: [PATCH 01/11] patch _calcTokenOutGivenExactBptIn; fix weightedMath tests --- src/pools/weightedPool/weightedMath.ts | 10 ++--- test/weightedMath.spec.ts | 51 +++++++++++--------------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/pools/weightedPool/weightedMath.ts b/src/pools/weightedPool/weightedMath.ts index 42e5820b..b6c4faaa 100644 --- a/src/pools/weightedPool/weightedMath.ts +++ b/src/pools/weightedPool/weightedMath.ts @@ -260,12 +260,12 @@ export function _calcTokenOutGivenExactBptIn( MathSol.complementFixed(normalizedWeight) ); const nonTaxableAmount = MathSol.sub(amountOutWithoutFee, taxableAmount); - const taxableAmountMinusFees = MathSol.mulUpFixed( - taxableAmount, - MathSol.complementFixed(swapFeePercentage) + const swapFee = MathSol.mulUpFixed(taxableAmount, swapFeePercentage); + const amountOut = MathSol.add( + nonTaxableAmount, + MathSol.sub(taxableAmount, swapFee) ); - - return MathSol.add(nonTaxableAmount, taxableAmountMinusFees); + return amountOut; } export function _calcBptInGivenExactTokensOut( diff --git a/test/weightedMath.spec.ts b/test/weightedMath.spec.ts index 41f7f83a..1a33be24 100644 --- a/test/weightedMath.spec.ts +++ b/test/weightedMath.spec.ts @@ -25,8 +25,6 @@ import singleWeightedPool from './testData/weightedPools/singlePoolWithSwapEnabl import { WeightedPool } from '../src/pools/weightedPool/weightedPool'; import { _calcBptOutGivenExactTokensIn, - _calculateInvariant, - _calcDueProtocolSwapFeeBptAmount, _calcTokensOutGivenExactBptIn, _calcTokenOutGivenExactBptIn, _calcBptInGivenExactTokensOut, @@ -111,18 +109,18 @@ describe('weightedMath tests', () => { totalSupply: bigint, swapFee: bigint ) { - const sdkResult = SDK.WeightedMath._calcBptOutGivenExactTokensIn( - balances.map((a) => bnum(a.toString())), - normalizedWeights.map((a) => bnum(a.toString())), - amountsIn.map((a) => bnum(a.toString())), - bnum(totalSupply.toString()), - bnum(swapFee.toString()) - ); const amountsInScaled = _upscaleArray( amountsIn.map((a) => BigInt(a)), scalingFactors ); const balancesScaled = _upscaleArray(balances, scalingFactors); + const sdkResult = SDK.WeightedMath._calcBptOutGivenExactTokensIn( + balancesScaled.map((a) => bnum(a.toString())), + normalizedWeights.map((a) => bnum(a.toString())), + amountsInScaled.map((a) => bnum(a.toString())), + bnum(totalSupply.toString()), + bnum(swapFee.toString()) + ); const calculatedBptOut = _calcBptOutGivenExactTokensIn( balancesScaled, normalizedWeights, @@ -311,26 +309,20 @@ describe('weightedMath tests', () => { amountBptIn: bigint, totalSupply: bigint ) { + const balancesScaled = _upscaleArray(balances, scalingFactors); const sdkResult = SDK.WeightedMath._calcTokensOutGivenExactBptIn( - balances.map((a) => bnum(a.toString())), + balancesScaled.map((a) => bnum(a.toString())), bnum(amountBptIn.toString()), bnum(totalSupply.toString()) ); - const balancesScaled = _upscaleArray(balances, scalingFactors); const calculatedTokensOut = _calcTokensOutGivenExactBptIn( balancesScaled, amountBptIn, totalSupply ); - const calculatedTokensOutScaled = _downscaleDownArray( - calculatedTokensOut, - scalingFactors - ); expect(sdkResult[0].gt(0)).to.be.true; - expect(sdkResult.toString()).to.eq( - calculatedTokensOutScaled.toString() - ); + expect(sdkResult.toString()).to.eq(calculatedTokensOut.toString()); } context('testing against original maths', () => { @@ -394,15 +386,15 @@ describe('weightedMath tests', () => { totalSupply: bigint, swapFee: bigint ) { + const balanceScaled = _upscale(balance, scalingFactor); const sdkResult = SDK.WeightedMath._calcTokenOutGivenExactBptIn( - bnum(balance.toString()), + bnum(balanceScaled.toString()), bnum(normalizedWeight.toString()), bnum(bptAmountIn.toString()), bnum(totalSupply.toString()), bnum(swapFee.toString()) ); - const balanceScaled = _upscale(balance, scalingFactor); const tokenOut = _calcTokenOutGivenExactBptIn( balanceScaled, normalizedWeight, @@ -410,9 +402,8 @@ describe('weightedMath tests', () => { totalSupply, swapFee ); - const tokenOutScaled = _downscaleDown(tokenOut, scalingFactor); expect(sdkResult.gt(0)).to.be.true; - expect(sdkResult.toString()).to.eq(tokenOutScaled.toString()); + expect(sdkResult.toString()).to.eq(tokenOut.toString()); } context('testing against original maths', () => { @@ -482,22 +473,22 @@ describe('weightedMath tests', () => { totalSupply: bigint, swapFee: bigint ) { + const balancesScaled = _upscaleArray(balances, scalingFactors); + const amountsOutScaled = _upscaleArray( + amountsOut.map((a) => BigInt(a)), + scalingFactors + ); const sdkResult = SDK.WeightedMath._calcBptInGivenExactTokensOut( - balances.map((a) => bnum(a.toString())), + balancesScaled.map((a) => bnum(a.toString())), normalizedWeights.map((a) => bnum(a.toString())), - amountsOut.map((a) => bnum(a.toString())), + amountsOutScaled.map((a) => bnum(a.toString())), bnum(totalSupply.toString()), bnum(swapFee.toString()) ); - const amountsInScaled = _upscaleArray( - amountsOut.map((a) => BigInt(a)), - scalingFactors - ); - const balancesScaled = _upscaleArray(balances, scalingFactors); const calculatedBptIn = _calcBptInGivenExactTokensOut( balancesScaled, normalizedWeights, - amountsInScaled, + amountsOutScaled, totalSupply, swapFee ); From 1d682f77799792bbe959e7faffa76743476f2045 Mon Sep 17 00:00:00 2001 From: sergioyuhjtman Date: Tue, 16 Aug 2022 15:37:51 -0300 Subject: [PATCH 02/11] fix scalingFactors and _upscaleArray --- src/utils/basicOperations.ts | 5 +- test/weightedMath.spec.ts | 249 ++++++++++++++++------------------- 2 files changed, 112 insertions(+), 142 deletions(-) diff --git a/src/utils/basicOperations.ts b/src/utils/basicOperations.ts index f345c4f4..900e3946 100644 --- a/src/utils/basicOperations.ts +++ b/src/utils/basicOperations.ts @@ -27,10 +27,7 @@ export function _upscaleArray( ): bigint[] { const upscaledAmounts = new Array(amounts.length); for (let i = 0; i < amounts.length; ++i) { - upscaledAmounts[i] = MathSol.mulDownFixed( - amounts[i], - scalingFactors[i] - ); + upscaledAmounts[i] = MathSol.mul(amounts[i], scalingFactors[i]); } return upscaledAmounts; } diff --git a/test/weightedMath.spec.ts b/test/weightedMath.spec.ts index 1a33be24..532aa779 100644 --- a/test/weightedMath.spec.ts +++ b/test/weightedMath.spec.ts @@ -28,6 +28,8 @@ import { _calcTokensOutGivenExactBptIn, _calcTokenOutGivenExactBptIn, _calcBptInGivenExactTokensOut, + _calcDueProtocolSwapFeeBptAmount, + _calculateInvariant, } from '../src/pools/weightedPool/weightedMath'; import { Contract } from '@ethersproject/contracts'; @@ -113,7 +115,10 @@ describe('weightedMath tests', () => { amountsIn.map((a) => BigInt(a)), scalingFactors ); + console.log('balances: ', balances); + console.log('scalingFactors: ', scalingFactors); const balancesScaled = _upscaleArray(balances, scalingFactors); + console.log('balancesScaled: ', balancesScaled); const sdkResult = SDK.WeightedMath._calcBptOutGivenExactTokensIn( balancesScaled.map((a) => bnum(a.toString())), normalizedWeights.map((a) => bnum(a.toString())), @@ -134,18 +139,16 @@ describe('weightedMath tests', () => { // UI was previously using GeorgesSDK so we should at least match this context('testing against original SDK maths', () => { - it('Pool with 18 decimal tokens', async () => { + it('debug Pool with 18 decimal tokens', async () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1'), BigInt('1')]; const amountsIn = [ BigInt('7000000000000000000'), BigInt('1000000000000000000'), ]; + console.log('poolInfo.balances: ', poolInfo.balances); compareToSdk( scalingFactors, poolInfo.balances, @@ -161,10 +164,7 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; const amountsIn = [ BigInt('1234000000'), BigInt('1000000000000000000'), @@ -184,110 +184,103 @@ describe('weightedMath tests', () => { Testing maths against a queryJoin is failing. Needs further investigation but possible related to protocol fees which this has some initial code. */ - // context('testing with protocol fee', () => { - // it('Pool with 6 decimal tokens', async () => { - // // USDC/WETH - // const poolId = - // '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; - // const poolInfo = await getPoolOnChain(poolId, vault, provider); - // const assets = poolInfo.tokens; - // const scalingFactors = [ - // '1000000000000000000000000000000', - // '1000000000000000000', - // ]; - // const amountsIn = ['1234000000', '1000000000000000000']; - // const amountsInScaled: bigint[] = amountsIn.map( - // (a, i) => - // (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) - // ); - // const scaledBalances = poolInfo.balances.map( - // (a, i) => - // (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) - // ); - // // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract - // // getSwapFeePercentage - // const protocolSwapFeePercentage = BigInt('500000000000000000'); - - // // _beforeJoinExit - // // Same as getInvariant - // const preJoinExitInvariant = _calculateInvariant( - // poolInfo.normalizedWeights, - // scaledBalances - // ); - // const toMint = _calcDueProtocolSwapFeeBptAmount( - // poolInfo.totalSupply, - // poolInfo.lastInvariant, - // preJoinExitInvariant, - // protocolSwapFeePercentage - // ); - // const calculatedBptOut = _calcBptOutGivenExactTokensIn( - // scaledBalances, - // poolInfo.normalizedWeights, - // amountsInScaled, - // poolInfo.totalSupply + toMint, - // poolInfo.swapFee - // ); - // // queryJoin against local fork - // const query = await queryJoin( - // poolId, - // amountsIn, - // assets, - // balancerHelpers - // ); - // expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); - // expect(query.bptOut.toString()).to.eq( - // calculatedBptOut.toString() - // ); - // }).timeout(10000); - - // it('Pool with 18 decimal tokens', async () => { - // const poolId = - // '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; - // const poolInfo = await getPoolOnChain(poolId, vault, provider); - // const assets = poolInfo.tokens; - // const amountsIn = [ - // '7000000000000000000', - // '1000000000000000000', - // ]; - // // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract - // // getSwapFeePercentage - // const protocolSwapFeePercentage = BigInt('500000000000000000'); - - // // _beforeJoinExit - // // Same as getInvariant - // const preJoinExitInvariant = _calculateInvariant( - // poolInfo.normalizedWeights, - // poolInfo.balances - // ); - // const toMint = _calcDueProtocolSwapFeeBptAmount( - // poolInfo.totalSupply, - // poolInfo.lastInvariant, - // preJoinExitInvariant, - // protocolSwapFeePercentage - // ); - // const calculatedBptOut = _calcBptOutGivenExactTokensIn( - // poolInfo.balances, - // poolInfo.normalizedWeights, - // amountsIn.map((a) => BigInt(a)), - // poolInfo.totalSupply + toMint, - // poolInfo.swapFee - // ); - // // queryJoin against local fork - // const query = await queryJoin( - // poolId, - // amountsIn, - // assets, - // balancerHelpers - // ); - // expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); - // expect(query.bptOut.gt(0)).to.be.true; - // expect(query.bptOut.toString()).to.eq( - // calculatedBptOut.toString() - // ); - // }).timeout(10000); - // }); + /* context('testing with protocol fee', () => { + it('Pool with 6 decimal tokens', async () => { + // USDC/WETH + const poolId = + '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; + const poolInfo = await getPoolOnChain(poolId, vault, provider); + const assets = poolInfo.tokens; + const scalingFactors = ['1000000000000', '1']; + const amountsIn = ['1234000000', '1000000000000000000']; + const amountsInScaled: bigint[] = amountsIn.map( + (a, i) => + (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) + ); + const scaledBalances = poolInfo.balances.map( + (a, i) => + (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) + ); + // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract + // getSwapFeePercentage + const protocolSwapFeePercentage = BigInt('500000000000000000'); + // _beforeJoinExit + // Same as getInvariant + const preJoinExitInvariant = _calculateInvariant( + poolInfo.normalizedWeights, + scaledBalances + ); + const toMint = _calcDueProtocolSwapFeeBptAmount( + poolInfo.totalSupply, + poolInfo.lastInvariant, + preJoinExitInvariant, + protocolSwapFeePercentage + ); + const calculatedBptOut = _calcBptOutGivenExactTokensIn( + scaledBalances, + poolInfo.normalizedWeights, + amountsInScaled, + poolInfo.totalSupply + toMint, + poolInfo.swapFee + ); + // queryJoin against local fork + const query = await queryJoin( + poolId, + amountsIn, + assets, + balancerHelpers + ); + expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); + expect(query.bptOut.toString()).to.eq( + calculatedBptOut.toString() + ); + }).timeout(10000); + it('Pool with 18 decimal tokens', async () => { + const poolId = + '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; + const poolInfo = await getPoolOnChain(poolId, vault, provider); + const assets = poolInfo.tokens; + const amountsIn = [ + '7000000000000000000', + '1000000000000000000', + ]; + // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract + // getSwapFeePercentage + const protocolSwapFeePercentage = BigInt('500000000000000000'); + // _beforeJoinExit + // Same as getInvariant + const preJoinExitInvariant = _calculateInvariant( + poolInfo.normalizedWeights, + poolInfo.balances + ); + const toMint = _calcDueProtocolSwapFeeBptAmount( + poolInfo.totalSupply, + poolInfo.lastInvariant, + preJoinExitInvariant, + protocolSwapFeePercentage + ); + const calculatedBptOut = _calcBptOutGivenExactTokensIn( + poolInfo.balances, + poolInfo.normalizedWeights, + amountsIn.map((a) => BigInt(a)), + poolInfo.totalSupply + toMint, + poolInfo.swapFee + ); + // queryJoin against local fork + const query = await queryJoin( + poolId, + amountsIn, + assets, + balancerHelpers + ); + expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); + expect(query.bptOut.gt(0)).to.be.true; + expect(query.bptOut.toString()).to.eq( + calculatedBptOut.toString() + ); + }).timeout(10000); + });*/ }); - context('_calcTokensOutGivenExactBptIn', () => { // Setup chain before(async function () { @@ -330,10 +323,7 @@ describe('weightedMath tests', () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1'), BigInt('1')]; const amountBptIn = BigInt('7000000000000000000'); compareToSdk( scalingFactors, @@ -348,10 +338,7 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; const amountBptIn = BigInt('1234000000000000000000'); compareToSdk( scalingFactors, @@ -411,12 +398,8 @@ describe('weightedMath tests', () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1'), BigInt('1')]; const bptIn = BigInt('7000000000000000000'); - // This is failing - looks like a rounding error compareToSdk( scalingFactors[0], poolInfo.balances[0], @@ -432,12 +415,8 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; const bptIn = BigInt('123000000000000000000'); - // This is failing - looks like a rounding error compareToSdk( scalingFactors[0], poolInfo.balances[0], @@ -501,10 +480,7 @@ describe('weightedMath tests', () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1'), BigInt('1')]; const amountsOut = [ BigInt('7000000000000000000'), BigInt('1000000000000000000'), @@ -524,10 +500,7 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [ - BigInt('1000000000000000000000000000000'), - BigInt('1000000000000000000'), - ]; + const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; const amountsOut = [ BigInt('1234000000'), BigInt('1000000000000000000'), From fe6dfefefadb943dca31dfafc6bf1e6745a4cbdd Mon Sep 17 00:00:00 2001 From: sergioyuhjtman Date: Wed, 17 Aug 2022 12:20:19 -0300 Subject: [PATCH 03/11] revert previous commit --- src/utils/basicOperations.ts | 5 +- test/weightedMath.spec.ts | 247 +++++++++++++++++++---------------- 2 files changed, 140 insertions(+), 112 deletions(-) diff --git a/src/utils/basicOperations.ts b/src/utils/basicOperations.ts index 900e3946..f345c4f4 100644 --- a/src/utils/basicOperations.ts +++ b/src/utils/basicOperations.ts @@ -27,7 +27,10 @@ export function _upscaleArray( ): bigint[] { const upscaledAmounts = new Array(amounts.length); for (let i = 0; i < amounts.length; ++i) { - upscaledAmounts[i] = MathSol.mul(amounts[i], scalingFactors[i]); + upscaledAmounts[i] = MathSol.mulDownFixed( + amounts[i], + scalingFactors[i] + ); } return upscaledAmounts; } diff --git a/test/weightedMath.spec.ts b/test/weightedMath.spec.ts index 532aa779..faa2716a 100644 --- a/test/weightedMath.spec.ts +++ b/test/weightedMath.spec.ts @@ -28,8 +28,6 @@ import { _calcTokensOutGivenExactBptIn, _calcTokenOutGivenExactBptIn, _calcBptInGivenExactTokensOut, - _calcDueProtocolSwapFeeBptAmount, - _calculateInvariant, } from '../src/pools/weightedPool/weightedMath'; import { Contract } from '@ethersproject/contracts'; @@ -115,10 +113,7 @@ describe('weightedMath tests', () => { amountsIn.map((a) => BigInt(a)), scalingFactors ); - console.log('balances: ', balances); - console.log('scalingFactors: ', scalingFactors); const balancesScaled = _upscaleArray(balances, scalingFactors); - console.log('balancesScaled: ', balancesScaled); const sdkResult = SDK.WeightedMath._calcBptOutGivenExactTokensIn( balancesScaled.map((a) => bnum(a.toString())), normalizedWeights.map((a) => bnum(a.toString())), @@ -139,16 +134,18 @@ describe('weightedMath tests', () => { // UI was previously using GeorgesSDK so we should at least match this context('testing against original SDK maths', () => { - it('debug Pool with 18 decimal tokens', async () => { + it('Pool with 18 decimal tokens', async () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000'), + BigInt('1000000000000000000'), + ]; const amountsIn = [ BigInt('7000000000000000000'), BigInt('1000000000000000000'), ]; - console.log('poolInfo.balances: ', poolInfo.balances); compareToSdk( scalingFactors, poolInfo.balances, @@ -164,7 +161,10 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000000000000000'), + BigInt('1000000000000000000'), + ]; const amountsIn = [ BigInt('1234000000'), BigInt('1000000000000000000'), @@ -184,103 +184,110 @@ describe('weightedMath tests', () => { Testing maths against a queryJoin is failing. Needs further investigation but possible related to protocol fees which this has some initial code. */ - /* context('testing with protocol fee', () => { - it('Pool with 6 decimal tokens', async () => { - // USDC/WETH - const poolId = - '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; - const poolInfo = await getPoolOnChain(poolId, vault, provider); - const assets = poolInfo.tokens; - const scalingFactors = ['1000000000000', '1']; - const amountsIn = ['1234000000', '1000000000000000000']; - const amountsInScaled: bigint[] = amountsIn.map( - (a, i) => - (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) - ); - const scaledBalances = poolInfo.balances.map( - (a, i) => - (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) - ); - // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract - // getSwapFeePercentage - const protocolSwapFeePercentage = BigInt('500000000000000000'); - // _beforeJoinExit - // Same as getInvariant - const preJoinExitInvariant = _calculateInvariant( - poolInfo.normalizedWeights, - scaledBalances - ); - const toMint = _calcDueProtocolSwapFeeBptAmount( - poolInfo.totalSupply, - poolInfo.lastInvariant, - preJoinExitInvariant, - protocolSwapFeePercentage - ); - const calculatedBptOut = _calcBptOutGivenExactTokensIn( - scaledBalances, - poolInfo.normalizedWeights, - amountsInScaled, - poolInfo.totalSupply + toMint, - poolInfo.swapFee - ); - // queryJoin against local fork - const query = await queryJoin( - poolId, - amountsIn, - assets, - balancerHelpers - ); - expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); - expect(query.bptOut.toString()).to.eq( - calculatedBptOut.toString() - ); - }).timeout(10000); - it('Pool with 18 decimal tokens', async () => { - const poolId = - '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; - const poolInfo = await getPoolOnChain(poolId, vault, provider); - const assets = poolInfo.tokens; - const amountsIn = [ - '7000000000000000000', - '1000000000000000000', - ]; - // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract - // getSwapFeePercentage - const protocolSwapFeePercentage = BigInt('500000000000000000'); - // _beforeJoinExit - // Same as getInvariant - const preJoinExitInvariant = _calculateInvariant( - poolInfo.normalizedWeights, - poolInfo.balances - ); - const toMint = _calcDueProtocolSwapFeeBptAmount( - poolInfo.totalSupply, - poolInfo.lastInvariant, - preJoinExitInvariant, - protocolSwapFeePercentage - ); - const calculatedBptOut = _calcBptOutGivenExactTokensIn( - poolInfo.balances, - poolInfo.normalizedWeights, - amountsIn.map((a) => BigInt(a)), - poolInfo.totalSupply + toMint, - poolInfo.swapFee - ); - // queryJoin against local fork - const query = await queryJoin( - poolId, - amountsIn, - assets, - balancerHelpers - ); - expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); - expect(query.bptOut.gt(0)).to.be.true; - expect(query.bptOut.toString()).to.eq( - calculatedBptOut.toString() - ); - }).timeout(10000); - });*/ + // context('testing with protocol fee', () => { + // it('Pool with 6 decimal tokens', async () => { + // // USDC/WETH + // const poolId = + // '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; + // const poolInfo = await getPoolOnChain(poolId, vault, provider); + // const assets = poolInfo.tokens; + // const scalingFactors = [ + // '1000000000000000000000000000000', + // '1000000000000000000', + // ]; + // const amountsIn = ['1234000000', '1000000000000000000']; + // const amountsInScaled: bigint[] = amountsIn.map( + // (a, i) => + // (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) + // ); + // const scaledBalances = poolInfo.balances.map( + // (a, i) => + // (BigInt(a) * BigInt(scalingFactors[i])) / BigInt(1e18) + // ); + // // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract + // // getSwapFeePercentage + // const protocolSwapFeePercentage = BigInt('500000000000000000'); + + // // _beforeJoinExit + // // Same as getInvariant + // const preJoinExitInvariant = _calculateInvariant( + // poolInfo.normalizedWeights, + // scaledBalances + // ); + // const toMint = _calcDueProtocolSwapFeeBptAmount( + // poolInfo.totalSupply, + // poolInfo.lastInvariant, + // preJoinExitInvariant, + // protocolSwapFeePercentage + // ); + // const calculatedBptOut = _calcBptOutGivenExactTokensIn( + // scaledBalances, + // poolInfo.normalizedWeights, + // amountsInScaled, + // poolInfo.totalSupply + toMint, + // poolInfo.swapFee + // ); + // // queryJoin against local fork + // const query = await queryJoin( + // poolId, + // amountsIn, + // assets, + // balancerHelpers + // ); + // expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); + // expect(query.bptOut.toString()).to.eq( + // calculatedBptOut.toString() + // ); + // }).timeout(10000); + + // it('Pool with 18 decimal tokens', async () => { + // const poolId = + // '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; + // const poolInfo = await getPoolOnChain(poolId, vault, provider); + // const assets = poolInfo.tokens; + // const amountsIn = [ + // '7000000000000000000', + // '1000000000000000000', + // ]; + // // https://etherscan.io/address/0xce88686553686DA562CE7Cea497CE749DA109f9F#readContract + // // getSwapFeePercentage + // const protocolSwapFeePercentage = BigInt('500000000000000000'); + + // // _beforeJoinExit + // // Same as getInvariant + // const preJoinExitInvariant = _calculateInvariant( + // poolInfo.normalizedWeights, + // poolInfo.balances + // ); + // const toMint = _calcDueProtocolSwapFeeBptAmount( + // poolInfo.totalSupply, + // poolInfo.lastInvariant, + // preJoinExitInvariant, + // protocolSwapFeePercentage + // ); + // const calculatedBptOut = _calcBptOutGivenExactTokensIn( + // poolInfo.balances, + // poolInfo.normalizedWeights, + // amountsIn.map((a) => BigInt(a)), + // poolInfo.totalSupply + toMint, + // poolInfo.swapFee + // ); + // // queryJoin against local fork + // const query = await queryJoin( + // poolId, + // amountsIn, + // assets, + // balancerHelpers + // ); + // expect(query.amountsIn.toString()).to.eq(amountsIn.toString()); + // expect(query.bptOut.gt(0)).to.be.true; + // expect(query.bptOut.toString()).to.eq( + // calculatedBptOut.toString() + // ); + // }).timeout(10000); + // }); }); + context('_calcTokensOutGivenExactBptIn', () => { // Setup chain before(async function () { @@ -323,7 +330,10 @@ describe('weightedMath tests', () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000'), + BigInt('1000000000000000000'), + ]; const amountBptIn = BigInt('7000000000000000000'); compareToSdk( scalingFactors, @@ -338,7 +348,10 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000000000000000'), + BigInt('1000000000000000000'), + ]; const amountBptIn = BigInt('1234000000000000000000'); compareToSdk( scalingFactors, @@ -398,7 +411,10 @@ describe('weightedMath tests', () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000'), + BigInt('1000000000000000000'), + ]; const bptIn = BigInt('7000000000000000000'); compareToSdk( scalingFactors[0], @@ -415,7 +431,10 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000000000000000'), + BigInt('1000000000000000000'), + ]; const bptIn = BigInt('123000000000000000000'); compareToSdk( scalingFactors[0], @@ -480,7 +499,10 @@ describe('weightedMath tests', () => { const poolId = '0x90291319f1d4ea3ad4db0dd8fe9e12baf749e84500020000000000000000013c'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000'), + BigInt('1000000000000000000'), + ]; const amountsOut = [ BigInt('7000000000000000000'), BigInt('1000000000000000000'), @@ -500,7 +522,10 @@ describe('weightedMath tests', () => { const poolId = '0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019'; const poolInfo = await getPoolOnChain(poolId, vault, provider); - const scalingFactors = [BigInt('1000000000000'), BigInt('1')]; + const scalingFactors = [ + BigInt('1000000000000000000000000000000'), + BigInt('1000000000000000000'), + ]; const amountsOut = [ BigInt('1234000000'), BigInt('1000000000000000000'), From 1003d11a203d92548b2d404ac2e1f6372ba87880 Mon Sep 17 00:00:00 2001 From: sergioyuhjtman Date: Wed, 17 Aug 2022 12:33:32 -0300 Subject: [PATCH 04/11] comment out gyro integration tests --- test/gyro2.integration.spec.ts | 4 ++++ test/gyro3.integration.spec.ts | 2 ++ 2 files changed, 6 insertions(+) diff --git a/test/gyro2.integration.spec.ts b/test/gyro2.integration.spec.ts index 228ee6b9..36ed4a70 100644 --- a/test/gyro2.integration.spec.ts +++ b/test/gyro2.integration.spec.ts @@ -1,4 +1,5 @@ // TS_NODE_PROJECT='tsconfig.testing.json' npx mocha -r ts-node/register test/gyro2.integration.spec.ts + import dotenv from 'dotenv'; import { parseFixed } from '@ethersproject/bignumber'; import { AddressZero } from '@ethersproject/constants'; @@ -24,6 +25,8 @@ dotenv.config(); * - Run kovan node on terminal: yarn run node * TO DO - Change this test to mainnet once deployed. */ + +/* const { ALCHEMY_URL: jsonRpcUrl } = process.env; const rpcUrl = 'http://127.0.0.1:8545'; const provider = new JsonRpcProvider(rpcUrl, 42); @@ -175,3 +178,4 @@ describe('gyro2 integration tests', () => { }).timeout(10000); }); }); +*/ diff --git a/test/gyro3.integration.spec.ts b/test/gyro3.integration.spec.ts index 735cd9fe..4a79773e 100644 --- a/test/gyro3.integration.spec.ts +++ b/test/gyro3.integration.spec.ts @@ -24,6 +24,7 @@ dotenv.config(); * - Run kovan node on terminal: yarn run node * TO DO - Change this test to mainnet once deployed. */ +/* const { ALCHEMY_URL: jsonRpcUrl } = process.env; const rpcUrl = 'http://127.0.0.1:8545'; const provider = new JsonRpcProvider(rpcUrl, 42); @@ -182,3 +183,4 @@ describe('gyro3 integration tests', () => { }).timeout(10000); }); }); +*/ From 65b83962e9427150eeadf0a804ae355a717b26be Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Thu, 18 Aug 2022 09:56:57 +0100 Subject: [PATCH 05/11] Add guards to handle maths out of range for Gyro pools. --- src/pools/gyro2Pool/gyro2Pool.ts | 256 ++++++++++++++++--------------- src/pools/gyro3Pool/gyro3Pool.ts | 254 ++++++++++++++++-------------- test/testScripts/swapExample.ts | 18 ++- 3 files changed, 286 insertions(+), 242 deletions(-) diff --git a/src/pools/gyro2Pool/gyro2Pool.ts b/src/pools/gyro2Pool/gyro2Pool.ts index ad7ba5c6..2b162e2b 100644 --- a/src/pools/gyro2Pool/gyro2Pool.ts +++ b/src/pools/gyro2Pool/gyro2Pool.ts @@ -198,148 +198,164 @@ export class Gyro2Pool implements PoolBase { poolPairData: Gyro2PoolPairData, amount: OldBigNumber ): OldBigNumber { - const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; - const normalizedBalances = _normalizeBalances( - balances, - poolPairData.decimalsIn, - poolPairData.decimalsOut - ); - const invariant = _calculateInvariant( - normalizedBalances, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const [virtualParamIn, virtualParamOut] = _findVirtualParams( - invariant, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const inAmount = parseFixed(amount.toString(), 18); - const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); + try { + const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; + const normalizedBalances = _normalizeBalances( + balances, + poolPairData.decimalsIn, + poolPairData.decimalsOut + ); + const invariant = _calculateInvariant( + normalizedBalances, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const [virtualParamIn, virtualParamOut] = _findVirtualParams( + invariant, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const inAmount = parseFixed(amount.toString(), 18); + const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); - const outAmount = _calcOutGivenIn( - normalizedBalances[0], - normalizedBalances[1], - inAmountLessFee, - virtualParamIn, - virtualParamOut - ); + const outAmount = _calcOutGivenIn( + normalizedBalances[0], + normalizedBalances[1], + inAmountLessFee, + virtualParamIn, + virtualParamOut + ); - return bnum(formatFixed(outAmount, 18)); + return bnum(formatFixed(outAmount, 18)); + } catch (error) { + return bnum(0); + } } _tokenInForExactTokenOut( poolPairData: Gyro2PoolPairData, amount: OldBigNumber ): OldBigNumber { - const outAmount = parseFixed(amount.toString(), 18); - const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; - const normalizedBalances = _normalizeBalances( - balances, - poolPairData.decimalsIn, - poolPairData.decimalsOut - ); - const invariant = _calculateInvariant( - normalizedBalances, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const [virtualParamIn, virtualParamOut] = _findVirtualParams( - invariant, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const inAmountLessFee = _calcInGivenOut( - normalizedBalances[0], - normalizedBalances[1], - outAmount, - virtualParamIn, - virtualParamOut - ); - const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); + try { + const outAmount = parseFixed(amount.toString(), 18); + const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; + const normalizedBalances = _normalizeBalances( + balances, + poolPairData.decimalsIn, + poolPairData.decimalsOut + ); + const invariant = _calculateInvariant( + normalizedBalances, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const [virtualParamIn, virtualParamOut] = _findVirtualParams( + invariant, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const inAmountLessFee = _calcInGivenOut( + normalizedBalances[0], + normalizedBalances[1], + outAmount, + virtualParamIn, + virtualParamOut + ); + const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); - return bnum(formatFixed(inAmount, 18)); + return bnum(formatFixed(inAmount, 18)); + } catch (error) { + return bnum(0); + } } _spotPriceAfterSwapExactTokenInForTokenOut( poolPairData: Gyro2PoolPairData, amount: OldBigNumber ): OldBigNumber { - const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; - const normalizedBalances = _normalizeBalances( - balances, - poolPairData.decimalsIn, - poolPairData.decimalsOut - ); - const invariant = _calculateInvariant( - normalizedBalances, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const [virtualParamIn, virtualParamOut] = _findVirtualParams( - invariant, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const inAmount = parseFixed(amount.toString(), 18); - const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); - const outAmount = _calcOutGivenIn( - normalizedBalances[0], - normalizedBalances[1], - inAmountLessFee, - virtualParamIn, - virtualParamOut - ); - const newSpotPrice = _calculateNewSpotPrice( - normalizedBalances, - inAmount, - outAmount, - virtualParamIn, - virtualParamOut, - poolPairData.swapFee - ); - return bnum(formatFixed(newSpotPrice, 18)); + try { + const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; + const normalizedBalances = _normalizeBalances( + balances, + poolPairData.decimalsIn, + poolPairData.decimalsOut + ); + const invariant = _calculateInvariant( + normalizedBalances, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const [virtualParamIn, virtualParamOut] = _findVirtualParams( + invariant, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const inAmount = parseFixed(amount.toString(), 18); + const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); + const outAmount = _calcOutGivenIn( + normalizedBalances[0], + normalizedBalances[1], + inAmountLessFee, + virtualParamIn, + virtualParamOut + ); + const newSpotPrice = _calculateNewSpotPrice( + normalizedBalances, + inAmount, + outAmount, + virtualParamIn, + virtualParamOut, + poolPairData.swapFee + ); + return bnum(formatFixed(newSpotPrice, 18)); + } catch (error) { + return bnum(0); + } } _spotPriceAfterSwapTokenInForExactTokenOut( poolPairData: Gyro2PoolPairData, amount: OldBigNumber ): OldBigNumber { - const outAmount = parseFixed(amount.toString(), 18); - const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; - const normalizedBalances = _normalizeBalances( - balances, - poolPairData.decimalsIn, - poolPairData.decimalsOut - ); - const invariant = _calculateInvariant( - normalizedBalances, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const [virtualParamIn, virtualParamOut] = _findVirtualParams( - invariant, - poolPairData.sqrtAlpha, - poolPairData.sqrtBeta - ); - const inAmountLessFee = _calcInGivenOut( - normalizedBalances[0], - normalizedBalances[1], - outAmount, - virtualParamIn, - virtualParamOut - ); - const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); - const newSpotPrice = _calculateNewSpotPrice( - normalizedBalances, - inAmount, - outAmount, - virtualParamIn, - virtualParamOut, - poolPairData.swapFee - ); + try { + const outAmount = parseFixed(amount.toString(), 18); + const balances = [poolPairData.balanceIn, poolPairData.balanceOut]; + const normalizedBalances = _normalizeBalances( + balances, + poolPairData.decimalsIn, + poolPairData.decimalsOut + ); + const invariant = _calculateInvariant( + normalizedBalances, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const [virtualParamIn, virtualParamOut] = _findVirtualParams( + invariant, + poolPairData.sqrtAlpha, + poolPairData.sqrtBeta + ); + const inAmountLessFee = _calcInGivenOut( + normalizedBalances[0], + normalizedBalances[1], + outAmount, + virtualParamIn, + virtualParamOut + ); + const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); + const newSpotPrice = _calculateNewSpotPrice( + normalizedBalances, + inAmount, + outAmount, + virtualParamIn, + virtualParamOut, + poolPairData.swapFee + ); - return bnum(formatFixed(newSpotPrice, 18)); + return bnum(formatFixed(newSpotPrice, 18)); + } catch (error) { + return bnum(0); + } } _derivativeSpotPriceAfterSwapExactTokenInForTokenOut( diff --git a/src/pools/gyro3Pool/gyro3Pool.ts b/src/pools/gyro3Pool/gyro3Pool.ts index af28828f..a26db9e5 100644 --- a/src/pools/gyro3Pool/gyro3Pool.ts +++ b/src/pools/gyro3Pool/gyro3Pool.ts @@ -217,155 +217,171 @@ export class Gyro3Pool implements PoolBase { poolPairData: Gyro3PoolPairData, amount: OldBigNumber ): 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 - ); + try { + 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 + ); - const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); - const inAmount = parseFixed(amount.toString(), 18); - const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); + const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); + const inAmount = parseFixed(amount.toString(), 18); + const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); - const outAmount = _calcOutGivenIn( - normalizedBalances[0], - normalizedBalances[1], - inAmountLessFee, - virtualOffsetInOut - ); - return bnum(formatFixed(outAmount, 18)); + const outAmount = _calcOutGivenIn( + normalizedBalances[0], + normalizedBalances[1], + inAmountLessFee, + virtualOffsetInOut + ); + return bnum(formatFixed(outAmount, 18)); + } catch (error) { + return bnum(0); + } } _tokenInForExactTokenOut( poolPairData: Gyro3PoolPairData, amount: OldBigNumber ): OldBigNumber { - const outAmount = parseFixed(amount.toString(), 18); - 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 - ); + try { + const outAmount = parseFixed(amount.toString(), 18); + 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 + ); - const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); + const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); - const inAmountLessFee = _calcInGivenOut( - normalizedBalances[0], - normalizedBalances[1], - outAmount, - virtualOffsetInOut - ); - const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); + const inAmountLessFee = _calcInGivenOut( + normalizedBalances[0], + normalizedBalances[1], + outAmount, + virtualOffsetInOut + ); + const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); - return bnum(formatFixed(inAmount, 18)); + return bnum(formatFixed(inAmount, 18)); + } catch (error) { + return bnum(0); + } } _spotPriceAfterSwapExactTokenInForTokenOut( poolPairData: Gyro3PoolPairData, amount: OldBigNumber ): 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 - ); + try { + 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 + ); - const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); + const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); - const inAmount = parseFixed(amount.toString(), 18); - const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); + const inAmount = parseFixed(amount.toString(), 18); + const inAmountLessFee = _reduceFee(inAmount, poolPairData.swapFee); - const outAmount = _calcOutGivenIn( - normalizedBalances[0], - normalizedBalances[1], - inAmountLessFee, - virtualOffsetInOut - ); + const outAmount = _calcOutGivenIn( + normalizedBalances[0], + normalizedBalances[1], + inAmountLessFee, + virtualOffsetInOut + ); - const newSpotPrice = _calculateNewSpotPrice( - normalizedBalances, - inAmount, - outAmount, - virtualOffsetInOut, - poolPairData.swapFee - ); - return bnum(formatFixed(newSpotPrice, 18)); + const newSpotPrice = _calculateNewSpotPrice( + normalizedBalances, + inAmount, + outAmount, + virtualOffsetInOut, + poolPairData.swapFee + ); + return bnum(formatFixed(newSpotPrice, 18)); + } catch (error) { + return bnum(0); + } } _spotPriceAfterSwapTokenInForExactTokenOut( poolPairData: Gyro3PoolPairData, amount: OldBigNumber ): OldBigNumber { - const outAmount = parseFixed(amount.toString(), 18); - 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 - ); + try { + const outAmount = parseFixed(amount.toString(), 18); + 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 + ); - const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); + const virtualOffsetInOut = mulDown(invariant, this.root3Alpha); - const inAmountLessFee = _calcInGivenOut( - normalizedBalances[0], - normalizedBalances[1], - outAmount, - virtualOffsetInOut - ); - const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); - - const newSpotPrice = _calculateNewSpotPrice( - normalizedBalances, - inAmount, - outAmount, - virtualOffsetInOut, - poolPairData.swapFee - ); + const inAmountLessFee = _calcInGivenOut( + normalizedBalances[0], + normalizedBalances[1], + outAmount, + virtualOffsetInOut + ); + const inAmount = _addFee(inAmountLessFee, poolPairData.swapFee); + + const newSpotPrice = _calculateNewSpotPrice( + normalizedBalances, + inAmount, + outAmount, + virtualOffsetInOut, + poolPairData.swapFee + ); - return bnum(formatFixed(newSpotPrice, 18)); + return bnum(formatFixed(newSpotPrice, 18)); + } catch (error) { + return bnum(0); + } } _derivativeSpotPriceAfterSwapExactTokenInForTokenOut( diff --git a/test/testScripts/swapExample.ts b/test/testScripts/swapExample.ts index f43fd1a7..debb0023 100644 --- a/test/testScripts/swapExample.ts +++ b/test/testScripts/swapExample.ts @@ -58,17 +58,17 @@ function setUp(networkId: Network, provider: JsonRpcProvider): SOR { } export async function swap(): Promise { - const networkId = Network.MAINNET; + const networkId = Network.POLYGON; const provider = new JsonRpcProvider(PROVIDER_URLS[networkId]); // gasPrice is used by SOR as a factor to determine how many pools to swap against. // i.e. higher cost means more costly to trade against lots of different pools. const gasPrice = BigNumber.from('40000000000'); // This determines the max no of pools the SOR will use to swap. const maxPools = 4; - const tokenIn = ADDRESSES[networkId].BAL; + const tokenIn = ADDRESSES[networkId].DAI; const tokenOut = ADDRESSES[networkId].USDC; const swapType: SwapTypes = SwapTypes.SwapExactIn; - const swapAmount = parseFixed('3000', 18); + const swapAmount = parseFixed('0.001', 18); const sor = setUp(networkId, provider); @@ -137,6 +137,18 @@ export async function swap(): Promise { } else { console.log('RELAYER SWAP - Execute via batchRelayer.'); } + } else { + console.log('No Valid Swap'); + await printOutput( + swapInfo, + sor, + tokenIn, + tokenOut, + swapType, + swapAmount, + gasPrice, + [] + ); } } From ea1caac01b4d067f7f57abff2ba8665fa4299b3e Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Thu, 18 Aug 2022 11:35:03 +0100 Subject: [PATCH 06/11] Remove unnecessary logging. --- src/poolCacher.ts | 2 +- src/pools/metaStablePool/metaStablePool.ts | 2 +- src/pools/phantomStablePool/phantomStablePool.ts | 2 +- src/pools/stablePool/stablePool.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/poolCacher.ts b/src/poolCacher.ts index ac59b35c..b6fac414 100644 --- a/src/poolCacher.ts +++ b/src/poolCacher.ts @@ -28,7 +28,7 @@ export class PoolCacher { // On error clear all caches and return false so user knows to try again. this._finishedFetching = false; this.pools = []; - console.error(`Error: fetchPools(): ${err.message}`); + console.error(`Error: fetchPools(): ${err}`); return false; } } diff --git a/src/pools/metaStablePool/metaStablePool.ts b/src/pools/metaStablePool/metaStablePool.ts index f0ae920a..18b35a71 100644 --- a/src/pools/metaStablePool/metaStablePool.ts +++ b/src/pools/metaStablePool/metaStablePool.ts @@ -228,7 +228,7 @@ export class MetaStablePool implements PoolBase { return bnum(formatFixed(returnEvmWithRate, 18)); } catch (err) { - console.error(`_evmoutGivenIn: ${err.message}`); + // console.error(`_evmoutGivenIn: ${err.message}`); return ZERO; } } diff --git a/src/pools/phantomStablePool/phantomStablePool.ts b/src/pools/phantomStablePool/phantomStablePool.ts index 0d2d2ded..7b17c332 100644 --- a/src/pools/phantomStablePool/phantomStablePool.ts +++ b/src/pools/phantomStablePool/phantomStablePool.ts @@ -293,7 +293,7 @@ export class PhantomStablePool implements PoolBase { // Return human scaled return bnum(formatFixed(returnEvmWithRate, 18)); } catch (err) { - console.error(`PhantomStable _evmoutGivenIn: ${err.message}`); + // console.error(`PhantomStable _evmoutGivenIn: ${err.message}`); return ZERO; } } diff --git a/src/pools/stablePool/stablePool.ts b/src/pools/stablePool/stablePool.ts index e4b1d43d..981df362 100644 --- a/src/pools/stablePool/stablePool.ts +++ b/src/pools/stablePool/stablePool.ts @@ -211,7 +211,7 @@ export class StablePool implements PoolBase { 1 ); } catch (err) { - console.error(`_evmoutGivenIn: ${err.message}`); + // console.error(`_evmoutGivenIn: ${err.message}`); return ZERO; } } From d97a71057c0f851a598f4bfe8f29028e98fedfcd Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Thu, 18 Aug 2022 11:42:16 +0100 Subject: [PATCH 07/11] Activate ComposableStable type. --- src/pools/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pools/index.ts b/src/pools/index.ts index f6fc832f..37c0dcda 100644 --- a/src/pools/index.ts +++ b/src/pools/index.ts @@ -60,7 +60,10 @@ export function parseNewPool( newPool.setCurrentBlockTimestamp(currentBlockTimestamp); } else if (pool.poolType.toString().includes('Linear')) newPool = LinearPool.fromPool(pool); - else if (pool.poolType === 'StablePhantom') + else if ( + pool.poolType === 'StablePhantom' || + pool.poolType === 'ComposableStable' + ) newPool = PhantomStablePool.fromPool(pool); else if (pool.poolType === 'Gyro2') newPool = Gyro2Pool.fromPool(pool); else if (pool.poolType === 'Gyro3') newPool = Gyro3Pool.fromPool(pool); From e7a4ad45ae4468127cd104ead0680c2045d7787b Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Thu, 18 Aug 2022 11:42:37 +0100 Subject: [PATCH 08/11] Update package to 4.0.1-beta.3. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 47ce6f7c..bdc9cfb8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@balancer-labs/sor", - "version": "4.0.1-beta.2", + "version": "4.0.1-beta.3", "license": "GPL-3.0-only", "main": "dist/index.js", "module": "dist/index.esm.js", From 075474db8c481865804237365cea6891b31d1a59 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Thu, 18 Aug 2022 11:53:23 +0100 Subject: [PATCH 09/11] Fetch ComposableStable onchain data. --- test/lib/onchainData.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/lib/onchainData.ts b/test/lib/onchainData.ts index a3c4d5b0..849c0760 100644 --- a/test/lib/onchainData.ts +++ b/test/lib/onchainData.ts @@ -71,7 +71,8 @@ export async function getOnChainBalances( } else if ( pool.poolType === 'Stable' || pool.poolType === 'MetaStable' || - pool.poolType === 'StablePhantom' + pool.poolType === 'StablePhantom' || + pool.poolType === 'ComposableStable' ) { // MetaStable & StablePhantom is the same as Stable for multicall purposes multiPool.call( @@ -150,7 +151,8 @@ export async function getOnChainBalances( if ( subgraphPools[index].poolType === 'Stable' || subgraphPools[index].poolType === 'MetaStable' || - subgraphPools[index].poolType === 'StablePhantom' + subgraphPools[index].poolType === 'StablePhantom' || + subgraphPools[index].poolType === 'ComposableStable' ) { if (!onchainData.amp) { console.error(`Stable Pool Missing Amp: ${poolId}`); From c42652d67a69b8ffdbedab2bdfe1d04e1924f322 Mon Sep 17 00:00:00 2001 From: sergioyuhjtman Date: Mon, 22 Aug 2022 17:20:00 -0300 Subject: [PATCH 10/11] add export line to src/index.ts --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index d83d959c..23fa2730 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,3 +19,4 @@ export { LinearPool } from './pools/linearPool/linearPool'; export { getSpotPriceAfterSwapForPath } from './router/helpersClass'; export * as WeightedMaths from './pools/weightedPool/weightedMath'; export * as StableMaths from './pools/stablePool/stableMath'; +export * as StableMathBigInt from './pools/stablePool/stableMathBigInt'; From 9ec3c635e337ec00b8419b838c80076d83a9714e Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Tue, 23 Aug 2022 13:28:48 +0100 Subject: [PATCH 11/11] Use SG totalSupply for virtualBpt. --- src/pools/phantomStablePool/phantomStableMath.ts | 13 ++----------- src/pools/phantomStablePool/phantomStablePool.ts | 7 +------ src/types.ts | 1 + test/phantomStableMath.spec.ts | 2 +- .../boostedPools/boostedPoolsWithWstETH.json | 4 ++-- test/testData/boostedPools/genericBoosted.json | 4 ++-- test/testData/boostedPools/multipleBoosted.json | 2 +- test/testData/linearPools/fullKovan.json | 2 +- test/testData/linearPools/kovan.json | 2 +- test/testData/linearPools/smallLinear.json | 2 +- .../phantomStablePools/phantomStablePool.json | 2 +- .../phantomStableStabal3WithPriceRates.json | 2 +- test/testScripts/constants.ts | 12 +++++++++++- 13 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/pools/phantomStablePool/phantomStableMath.ts b/src/pools/phantomStablePool/phantomStableMath.ts index 1e857147..b5b03ee0 100644 --- a/src/pools/phantomStablePool/phantomStableMath.ts +++ b/src/pools/phantomStablePool/phantomStableMath.ts @@ -8,11 +8,6 @@ import { } from '../../utils/bignumber'; import { PhantomStablePoolPairData } from './phantomStablePool'; -const MAX_TOKEN_BALANCE = bnum(2) - .pow(112) - .minus(1) - .div(10 ** 18); - // All functions are adapted from the solidity ones to be found on: // https://github.com/balancer-labs/balancer-core-v2/blob/master/contracts/pools/stable/StableMath.sol @@ -474,8 +469,7 @@ export function _exactBPTInForTokenOut( // we input zero the output should be zero if (amount.isZero()) return amount; - const { amp, allBalances, balanceIn, tokenIndexOut, decimalsIn, swapFee } = - poolPairData; + const { amp, allBalances, tokenIndexOut, swapFee } = poolPairData; const balances = [...allBalances]; const bptAmountIn = amount; @@ -486,10 +480,7 @@ export function _exactBPTInForTokenOut( // Get current invariant const currentInvariant = _invariant(amp, balances); // Calculate new invariant - - const bnumBalanceIn = MAX_TOKEN_BALANCE.minus( - bnum(formatFixed(balanceIn, decimalsIn)) - ); + const bnumBalanceIn = bnum(formatFixed(poolPairData.virtualBptSupply, 18)); const newInvariant = bnumBalanceIn .minus(bptAmountIn) .div(bnumBalanceIn) diff --git a/src/pools/phantomStablePool/phantomStablePool.ts b/src/pools/phantomStablePool/phantomStablePool.ts index 7b17c332..8b18ac8b 100644 --- a/src/pools/phantomStablePool/phantomStablePool.ts +++ b/src/pools/phantomStablePool/phantomStablePool.ts @@ -49,8 +49,6 @@ export class PhantomStablePool implements PoolBase { tokens: PhantomStablePoolToken[]; tokensList: string[]; ALMOST_ONE = parseFixed('0.99', 18); - // Used for VirutalBpt and can be removed if SG is updated with VirtualBpt value - MAX_TOKEN_BALANCE = BigNumber.from('2').pow('112').sub('1'); static AMP_DECIMALS = 3; @@ -151,10 +149,7 @@ export class PhantomStablePool implements PoolBase { const bptIndex = this.tokensList.indexOf(this.address); // VirtualBPTSupply must be used for the maths - // TO DO - SG should be updated to so that totalShares should return VirtualSupply - const virtualBptSupply = this.MAX_TOKEN_BALANCE.sub( - allBalancesScaled[bptIndex] - ); + const virtualBptSupply = this.totalShares; const poolPairData: PhantomStablePoolPairData = { id: this.id, diff --git a/src/types.ts b/src/types.ts index 3d6e5fc1..007ec5ab 100644 --- a/src/types.ts +++ b/src/types.ts @@ -165,6 +165,7 @@ export enum PoolFilter { ERC4626Linear = 'ERC4626Linear', Gyro2 = 'Gyro2', Gyro3 = 'Gyro3', + ComposableStable = 'ComposableStable', } export interface PoolBase { diff --git a/test/phantomStableMath.spec.ts b/test/phantomStableMath.spec.ts index c1afdc1b..26d603f1 100644 --- a/test/phantomStableMath.spec.ts +++ b/test/phantomStableMath.spec.ts @@ -1,4 +1,4 @@ -// TS_NODE_PROJECT='tsconfig.testing.json' npx mocha -r ts-node/register test/math.spec.ts +// TS_NODE_PROJECT='tsconfig.testing.json' npx mocha -r ts-node/register test/phantomStableMath.spec.ts import { assert } from 'chai'; import { formatFixed } from '@ethersproject/bignumber'; import { BigNumber as OldBigNumber } from '../src/utils/bignumber'; diff --git a/test/testData/boostedPools/boostedPoolsWithWstETH.json b/test/testData/boostedPools/boostedPoolsWithWstETH.json index bd7e58a2..887d3e6b 100644 --- a/test/testData/boostedPools/boostedPoolsWithWstETH.json +++ b/test/testData/boostedPools/boostedPoolsWithWstETH.json @@ -48,7 +48,7 @@ "0x6a8c3239695613c0710dc971310b36f9b81e115e", "0xcd32a460b6fecd053582e43b07ed6e2c04e15369" ], - "totalShares": "0", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "wrappedIndex": 0 }, @@ -364,7 +364,7 @@ "0x0000000000000000000000000000000000211111", "0x0000000000000000000000000000000000000000" ], - "totalShares": "0", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "wrappedIndex": 0 }, diff --git a/test/testData/boostedPools/genericBoosted.json b/test/testData/boostedPools/genericBoosted.json index 370cca77..fa3c39cb 100644 --- a/test/testData/boostedPools/genericBoosted.json +++ b/test/testData/boostedPools/genericBoosted.json @@ -48,7 +48,7 @@ "0x6a8c3239695613c0710dc971310b36f9b81e115e", "0xcd32a460b6fecd053582e43b07ed6e2c04e15369" ], - "totalShares": "0", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "wrappedIndex": 0 }, @@ -364,7 +364,7 @@ "0x0000000000000000000000000000000000211111", "0x0000000000000000000000000000000000000000" ], - "totalShares": "0", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "wrappedIndex": 0 }, diff --git a/test/testData/boostedPools/multipleBoosted.json b/test/testData/boostedPools/multipleBoosted.json index 8003fd87..552b4e36 100644 --- a/test/testData/boostedPools/multipleBoosted.json +++ b/test/testData/boostedPools/multipleBoosted.json @@ -48,7 +48,7 @@ "0x6a8c3239695613c0710dc971310b36f9b81e115e", "0xcd32a460b6fecd053582e43b07ed6e2c04e15369" ], - "totalShares": "0", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "wrappedIndex": 0 }, diff --git a/test/testData/linearPools/fullKovan.json b/test/testData/linearPools/fullKovan.json index b533d99c..fd42620d 100644 --- a/test/testData/linearPools/fullKovan.json +++ b/test/testData/linearPools/fullKovan.json @@ -14518,7 +14518,7 @@ "0x6a8c3239695613c0710dc971310b36f9b81e115e", "0xcd32a460b6fecd053582e43b07ed6e2c04e15369" ], - "totalShares": "4500", + "totalShares": "18973.09292830139671902", "totalWeight": "0", "unitSeconds": 0, "upperTarget": "null", diff --git a/test/testData/linearPools/kovan.json b/test/testData/linearPools/kovan.json index 5aac91e1..6d947e48 100644 --- a/test/testData/linearPools/kovan.json +++ b/test/testData/linearPools/kovan.json @@ -48,7 +48,7 @@ "0x6a8c3239695613c0710dc971310b36f9b81e115e", "0xcd32a460b6fecd053582e43b07ed6e2c04e15369" ], - "totalShares": "0", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "wrappedIndex": 0 }, diff --git a/test/testData/linearPools/smallLinear.json b/test/testData/linearPools/smallLinear.json index dab451a7..f1265265 100644 --- a/test/testData/linearPools/smallLinear.json +++ b/test/testData/linearPools/smallLinear.json @@ -323,7 +323,7 @@ "0x0000000000000000000000000000000000000003", "0x8fd162f338b770f7e879030830cde9173367f301" ], - "totalShares": "10000000", + "totalShares": "3692296858534827.628530496329220095", "poolType": "StablePhantom" }, { diff --git a/test/testData/phantomStablePools/phantomStablePool.json b/test/testData/phantomStablePools/phantomStablePool.json index 7f4bed75..cb1f2006 100644 --- a/test/testData/phantomStablePools/phantomStablePool.json +++ b/test/testData/phantomStablePools/phantomStablePool.json @@ -109,7 +109,7 @@ "0x6a8c3239695613c0710dc971310b36f9b81e115e", "0xcd32a460b6fecd053582e43b07ed6e2c04e15369" ], - "totalShares": "5192296858534827.628530496329220095", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "unitSeconds": 0, "upperTarget": "0", diff --git a/test/testData/phantomStablePools/phantomStableStabal3WithPriceRates.json b/test/testData/phantomStablePools/phantomStableStabal3WithPriceRates.json index 2c4ff8c8..e0695887 100644 --- a/test/testData/phantomStablePools/phantomStableStabal3WithPriceRates.json +++ b/test/testData/phantomStablePools/phantomStableStabal3WithPriceRates.json @@ -48,7 +48,7 @@ "0x6a8c3239695613c0710dc971310b36f9b81e115e", "0xcd32a460b6fecd053582e43b07ed6e2c04e15369" ], - "totalShares": "5192296858534827.628530496329220095", + "totalShares": "14473.09292830139671902", "totalWeight": "0", "unitSeconds": 0, "upperTarget": "0", diff --git a/test/testScripts/constants.ts b/test/testScripts/constants.ts index a7fef816..35974fa4 100644 --- a/test/testScripts/constants.ts +++ b/test/testScripts/constants.ts @@ -66,7 +66,7 @@ export const MULTIADDR: { [chainId: number]: string } = { export const SUBGRAPH_URLS = { [Network.MAINNET]: - 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2', + 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2-beta', [Network.GOERLI]: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-goerli-v2', [Network.KOVAN]: @@ -149,6 +149,16 @@ export const ADDRESSES = { decimals: 6, symbol: 'waUSDC', }, + bbausd2: { + address: '0x9b532ab955417afd0d012eb9f7389457cd0ea712', + decimals: 18, + symbol: 'bbausd2', + }, + bbadai2: { + address: '0xae37d54ae477268b9997d4161b96b8200755935c', + decimals: 18, + symbol: 'bb-a-dai2', + }, }, [Network.KOVAN]: { // Visit https://balancer-faucet.on.fleek.co/#/faucet for test tokens