From 475855d8991ff0dfba1a9e9234b3abeb281e73b4 Mon Sep 17 00:00:00 2001 From: lacoop6tu Date: Mon, 8 Nov 2021 17:03:20 -0500 Subject: [PATCH] add test for liquidity view functions, fix decimals issue --- src/pools/balancer/Pool.ts | 104 +++++++++++--------------- test/unit/pools/balancer/Pool.test.ts | 40 ++++++++++ 2 files changed, 84 insertions(+), 60 deletions(-) diff --git a/src/pools/balancer/Pool.ts b/src/pools/balancer/Pool.ts index 4a695a22..8aceedb4 100644 --- a/src/pools/balancer/Pool.ts +++ b/src/pools/balancer/Pool.ts @@ -756,14 +756,18 @@ export class Pool { defaultERC20ABI.abi as AbiItem[], token ) + try { decimals = await tokenContract.methods.decimals().call() + if (decimals == 0){ + decimals = 18 + } } catch (e) { this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18') } - + const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals) - + return amountFormatted.toString() } @@ -775,10 +779,13 @@ export class Pool { ) try { decimals = await tokenContract.methods.decimals().call() + if (decimals == 0){ + decimals = 18 + } } catch (e) { this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18') } - + const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals) return amountFormatted.toString() @@ -1513,7 +1520,9 @@ export class Pool { const result = await pool.methods .getAmountOutExactIn(tokenIn, tokenOut, amountInFormatted) .call() + amount = await this.unitsToAmount(tokenOut, result) + } catch (e) { this.logger.error('ERROR: Failed to calcOutGivenIn') } @@ -1522,56 +1531,46 @@ export class Pool { public async calcPoolOutGivenSingleIn( poolAddress: string, - tokenBalanceIn: string, - tokenWeightIn: string, - poolSupply: string, - totalWeight: string, - tokenAmountIn: string, - swapFee: string + tokenIn: string, + tokenAmountIn: string ): Promise { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) let amount = null try { const result = await pool.methods - .calcPoolOutGivenSingleIn( - this.web3.utils.toWei(tokenBalanceIn), - this.web3.utils.toWei(tokenWeightIn), - this.web3.utils.toWei(poolSupply), - this.web3.utils.toWei(totalWeight), - this.web3.utils.toWei(tokenAmountIn), - this.web3.utils.toWei(swapFee) + .calcPoolOutSingleIn( + tokenIn, + await this.amountToUnits(tokenIn,tokenAmountIn) ) .call() - amount = this.web3.utils.fromWei(result) + amount = await this.unitsToAmount(poolAddress,result) } catch (e) { this.logger.error(`ERROR: Failed to calculate PoolOutGivenSingleIn : ${e.message}`) } return amount } - + public async calcSingleInGivenPoolOut( poolAddress: string, - tokenBalanceIn: string, - tokenWeightIn: string, - poolSupply: string, - totalWeight: string, + tokenIn:string, poolAmountOut: string, - swapFee: string ): Promise { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) let amount = null + + const amountFormatted = await this.amountToUnits(poolAddress,poolAmountOut) + try { const result = await pool.methods - .calcSingleInGivenPoolOut( - this.web3.utils.toWei(tokenBalanceIn), - this.web3.utils.toWei(tokenWeightIn), - this.web3.utils.toWei(poolSupply), - this.web3.utils.toWei(totalWeight), - this.web3.utils.toWei(poolAmountOut), - this.web3.utils.toWei(swapFee) + .calcSingleInPoolOut( + tokenIn, + amountFormatted ) + .call() - amount = this.web3.utils.fromWei(result) + + amount = await this.unitsToAmount(tokenIn,result) + } catch (e) { this.logger.error(`ERROR: Failed to calculate SingleInGivenPoolOut : ${e.message}`) } @@ -1580,27 +1579,19 @@ export class Pool { public async calcSingleOutGivenPoolIn( poolAddress: string, - tokenBalanceOut: string, - tokenWeightOut: string, - poolSupply: string, - totalWeight: string, - poolAmountIn: string, - swapFee: string + tokenOut:string, + poolAmountIn: string ): Promise { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) let amount = null try { const result = await pool.methods - .calcSingleOutGivenPoolIn( - this.web3.utils.toWei(tokenBalanceOut), - this.web3.utils.toWei(tokenWeightOut), - this.web3.utils.toWei(poolSupply), - this.web3.utils.toWei(totalWeight), - this.web3.utils.toWei(poolAmountIn), - this.web3.utils.toWei(swapFee) + .calcSingleOutPoolIn( + tokenOut, + await this.amountToUnits(poolAddress,poolAmountIn) ) .call() - amount = this.web3.utils.fromWei(result) + amount = await this.unitsToAmount(tokenOut,result) } catch (e) { this.logger.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e.message}`) } @@ -1608,28 +1599,21 @@ export class Pool { } public async calcPoolInGivenSingleOut( - poolAddress: string, - tokenBalanceOut: string, - tokenWeightOut: string, - poolSupply: string, - totalWeight: string, - tokenAmountOut: string, - swapFee: string + poolAddress:string, + tokenOut:string, + tokenAmountOut: string ): Promise { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) let amount = null try { const result = await pool.methods - .calcPoolInGivenSingleOut( - this.web3.utils.toWei(tokenBalanceOut), - this.web3.utils.toWei(tokenWeightOut), - this.web3.utils.toWei(poolSupply), - this.web3.utils.toWei(totalWeight), - this.web3.utils.toWei(tokenAmountOut), - this.web3.utils.toWei(swapFee) + .calcPoolInSingleOut( + tokenOut, + await this.amountToUnits(tokenOut,tokenAmountOut) ) .call() - amount = this.web3.utils.fromWei(result) + + amount = await this.unitsToAmount(poolAddress,result) } catch (e) { this.logger.error(`ERROR: Failed to calculate PoolInGivenSingleOut : ${e.message}`) } diff --git a/test/unit/pools/balancer/Pool.test.ts b/test/unit/pools/balancer/Pool.test.ts index c63f88dc..0962fd09 100644 --- a/test/unit/pools/balancer/Pool.test.ts +++ b/test/unit/pools/balancer/Pool.test.ts @@ -637,6 +637,46 @@ describe('Pool unit test', () => { expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0') }) + it('#calcPoolOutGivenSingleIn - should get the amount of pool OUT for exact token IN', async () => { + // since rate is 1 and the pool is just created + // amount of pool out received for same amount of different token In is equal + const tokenInAmount = '10' // 10 USDC or 10 DTs + expect(await pool.calcPoolOutGivenSingleIn(poolAddress, erc20Token, tokenInAmount)).to.equal( + await pool.calcPoolOutGivenSingleIn(poolAddress, contracts.usdcAddress, tokenInAmount) + ) + //console.log(await pool.calcPoolOutGivenSingleIn(poolAddress, erc20Token, tokenInAmount)) + }) + + + it('#calcSingleInGivenPoolOut - should get the amount of token IN for exact pool token OUT', async () => { + // since rate is 1 and the pool is just created + // amount of different token In for getting same pool amount out is equal + const poolAmountOut = '1' + expect(parseInt(await pool.calcSingleInGivenPoolOut(poolAddress, erc20Token, poolAmountOut))).to.be.closeTo( + parseInt(await pool.calcSingleInGivenPoolOut(poolAddress, contracts.usdcAddress, poolAmountOut)),1e9 + ) + + }) + + it('#calcSingleOutGivenPoolIn - should get the amount of token OUT for exact pool token IN', async () => { + // since rate is 1 and the pool is just created + //amount amount of different token Out for rediming the same pool In is equal + const poolAmountIn = '10' + expect(await pool.calcSingleOutGivenPoolIn(poolAddress, erc20Token, poolAmountIn)).to.equal( + await pool.calcSingleOutGivenPoolIn(poolAddress, contracts.usdcAddress, poolAmountIn) + ) + + }) + + it('#calcPoolInGivenSingleOut - should get the amount of pool IN for exact token OUT', async () => { + // since rate is 1 and the pool is just created + //amount of pool In for getting the same amount of different token Out is equal + const tokenAmountOut = '10' + expect(parseInt(await pool.calcPoolInGivenSingleOut(poolAddress, erc20Token,tokenAmountOut))).to.be.closeTo( + parseInt(await pool.calcPoolInGivenSingleOut(poolAddress, contracts.usdcAddress, tokenAmountOut)),1e9 + ) + }) + it('#sharesBalance - should return user shares balance (datatoken balance, LPT balance, etc) ', async () => { expect(await usdcContract.methods.balanceOf(user2).call()).to.equal( await pool.sharesBalance(user2, contracts.usdcAddress)