From d1e6a6da74557b5e9ffbd447cac0fcce1ee23618 Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Thu, 9 Jul 2020 02:50:51 -0700 Subject: [PATCH] more tests --- src/balancer/balancerlib.ts | 135 ++++++++++++++++++++++++++-- test/unit/balancer/Balancer.test.ts | 77 ++++++++++++++++ 2 files changed, 206 insertions(+), 6 deletions(-) diff --git a/src/balancer/balancerlib.ts b/src/balancer/balancerlib.ts index c8aca9e1..41d6c5a6 100644 --- a/src/balancer/balancerlib.ts +++ b/src/balancer/balancerlib.ts @@ -179,6 +179,48 @@ export class Balancer { return result } + async sharesBalance(address: string): Promise { + if (this.pool == null) { + console.error('BPool not initialiez. Maybe you missed newPool or loadPool ?') + return null + } + const tokenAddress = this.poolAddress + const minABI = [ + { + constant: true, + inputs: [ + { + name: '_owner', + type: 'address' + } + ], + name: 'balanceOf', + outputs: [ + { + name: 'balance', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + } + ] + const token = new this.web3.eth.Contract(minABI, tokenAddress, { + from: this.account + }) + let result = null + try { + result = this.web3.utils.fromWei(await token.methods + .balanceOf(address) + .call({ from: this.account, gas: this.GASLIMIT_DEFAULT }) + ) + } catch (e) { + console.error(e) + } + return result + } + /** * Adds tokens to pool * @param {Array} tokens Array of token object { address,amount,weight} @@ -697,6 +739,37 @@ export class Balancer { return result } + /** + * Specify tokenAmountOut of token tokenOut that you want to get out of the pool. This costs poolAmountIn pool shares (these went into the pool). + * @param {String} tokenOut + * @param {String} tokenAmountOut will be converted to wei + * @param {String} maxPoolAmountIn will be converted to wei + * @return {any} + */ + async exitswapExternAmountOut( + tokenOut: string, + tokenAmountOut: string, + maxPoolAmountIn: string + ): Promise { + if (this.pool == null) { + console.error('BPool not initialiez. Maybe you missed newPool or loadPool ?') + return null + } + let result = null + try { + result = await this.pool.methods + .exitswapExternAmountOut( + tokenOut, + this.web3.utils.toWei(tokenAmountOut), + this.web3.utils.toWei(maxPoolAmountIn) + ) + .send({ from: this.account, gas: this.GASLIMIT_DEFAULT }) + } catch (e) { + console.error(e) + } + return result + } + /** * Get Spot Price of swaping tokenIn to tokenOut * @param {String} tokenIn @@ -904,12 +977,22 @@ export class Balancer { /** * Add Data Token amount to pool liquidity * @param {String} amount Data Token Amount - * @param {String} maxOceanAmount Maximum Ocean Token Amount required * @return {any} */ - public addDTLiquidity(amount: string, maxOceanAmount: string): Promise { - const amounts = [amount, maxOceanAmount] - return this.joinPool('0', amounts) + public async addDTLiquidity(amount: string): Promise { + if (this.dtAddress == null) { + console.error( + 'dtAddress is not defined. Did you do loadDTPool or createDTPool ?' + ) + return null + } + await this.approve( + this.dtAddress, + this.poolAddress, + this.web3.utils.toWei(amount) + ) + const result = await this.joinswapExternAmountIn(this.dtAddress, amount, '0') + return result } /** @@ -917,8 +1000,48 @@ export class Balancer { * @param {String} amount pool Liquidity Amount * @return {any} */ - public removeDTLiquidity(amount: string): Promise { - return this.exitPool(amount, '0') + public removeDTLiquidity(amount: string, maximumPoolShares: string): Promise { + if (this.dtAddress == null) { + console.error( + 'dtAddress is not defined. Did you do loadDTPool or createDTPool ?' + ) + return null + } + // TODO Check balance of PoolShares before doing exit + return this.exitswapExternAmountOut(this.dtAddress, amount, maximumPoolShares) + } + + /** + * Add Ocean Token amount to pool liquidity + * @param {String} amount Data Token Amount + * @return {any} + */ + public async addOceanLiquidity(amount: string): Promise { + if (this.oceanAddress == null) { + console.error('oceanAddress is not defined') + return null + } + await this.approve( + this.oceanAddress, + this.poolAddress, + this.web3.utils.toWei(amount) + ) + const result = await this.joinswapExternAmountIn(this.oceanAddress, amount, '0') + return result + } + + /** + * Remove Ocean Token amount from pool liquidity + * @param {String} amount pool Liquidity Amount + * @return {any} + */ + public removeOceanLiquidity(amount: string, maximumPoolShares: string): Promise { + if (this.oceanAddress == null) { + console.error('oceanAddress is not defined') + return null + } + // TODO Check balance of PoolShares before doing exit + return this.exitswapExternAmountOut(this.oceanAddress, amount, maximumPoolShares) } /** diff --git a/test/unit/balancer/Balancer.test.ts b/test/unit/balancer/Balancer.test.ts index ee63ac6d..a9db0486 100644 --- a/test/unit/balancer/Balancer.test.ts +++ b/test/unit/balancer/Balancer.test.ts @@ -5,6 +5,7 @@ import { DataTokens } from '../../../src/datatokens/Datatokens' import { Balancer } from '../../../src/balancer/balancerlib' import { Ocean } from '../../../src/ocean/Ocean' import { Config } from '../../../src/models/Config' +import { POINT_CONVERSION_COMPRESSED } from 'constants' const Web3 = require('web3') const web3 = new Web3('http://127.0.0.1:8545') @@ -25,6 +26,7 @@ describe('Balancer flow', () => { let alicePoolAddress let bobPool let currentDtPrice + let bobPoolShares let owner let bob let alice @@ -160,5 +162,80 @@ describe('Balancer flow', () => { assert(bobDtBalance > 0) assert(bobOceanBalance > 0) }) + it('Bob should add DT liquidity to pool ', async () => { + const currentDtReserve = await alicePool.getBalance(tokenAddress) + const bobDtBalance = web3.utils.fromWei( + await datatoken.balance(tokenAddress, bob) + ) + + await bobPool.addDTLiquidity(bobDtBalance) + + const newbobDtBalance = web3.utils.fromWei( + await datatoken.balance(tokenAddress, bob) + ) + + const newDtReserve = await alicePool.getBalance(tokenAddress) + + const sharesBalance = await bobPool.sharesBalance(bob) + assert(parseFloat(newbobDtBalance) < parseFloat(bobDtBalance)) + assert(parseFloat(newDtReserve) > parseFloat(currentDtReserve)) + assert(parseFloat(sharesBalance) > 0) + }) + + it('Bob should remove DT liquidity from pool ', async () => { + const currentDtReserve = await alicePool.getBalance(tokenAddress) + const bobDtBalance = web3.utils.fromWei( + await datatoken.balance(tokenAddress, bob) + ) + const poolShares = await bobPool.sharesBalance(bob) + await bobPool.removeDTLiquidity('0.75', poolShares) + + const newDtReserve = await alicePool.getBalance(tokenAddress) + const newbobDtBalance = web3.utils.fromWei( + await datatoken.balance(tokenAddress, bob) + ) + const newpoolShares = await bobPool.sharesBalance(bob) + assert(parseFloat(newDtReserve) < parseFloat(currentDtReserve)) + assert(parseFloat(bobDtBalance) < parseFloat(newbobDtBalance)) + assert(parseFloat(poolShares) > parseFloat(newpoolShares)) + }) + + it('Bob should add Ocean liquidity to pool ', async () => { + const currentDtReserve = await alicePool.getBalance(oceanTokenAddress) + const bobDtBalance = web3.utils.fromWei( + await datatoken.balance(oceanTokenAddress, bob) + ) + + await bobPool.addOceanLiquidity('1') + + const newbobDtBalance = web3.utils.fromWei( + await datatoken.balance(oceanTokenAddress, bob) + ) + + const newDtReserve = await alicePool.getBalance(oceanTokenAddress) + + const sharesBalance = await bobPool.sharesBalance(bob) + assert(parseFloat(newbobDtBalance) < parseFloat(bobDtBalance)) + assert(parseFloat(newDtReserve) > parseFloat(currentDtReserve)) + assert(parseFloat(sharesBalance) > 0) + }) + + it('Bob should remove DT liquidity from pool ', async () => { + const currentDtReserve = await alicePool.getBalance(oceanTokenAddress) + const bobDtBalance = web3.utils.fromWei( + await datatoken.balance(oceanTokenAddress, bob) + ) + const poolShares = await bobPool.sharesBalance(bob) + await bobPool.removeOceanLiquidity('0.75', poolShares) + + const newDtReserve = await alicePool.getBalance(oceanTokenAddress) + const newbobDtBalance = web3.utils.fromWei( + await datatoken.balance(oceanTokenAddress, bob) + ) + const newpoolShares = await bobPool.sharesBalance(bob) + assert(parseFloat(newDtReserve) < parseFloat(currentDtReserve)) + assert(parseFloat(bobDtBalance) < parseFloat(newbobDtBalance)) + assert(parseFloat(poolShares) > parseFloat(newpoolShares)) + }) }) })