From 002a38d487ffacb54f04b74679da528d282b873c Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Mon, 12 Oct 2020 14:29:44 -0700 Subject: [PATCH] add more pool tests --- src/balancer/OceanPool.ts | 29 +++++++------ src/balancer/Pool.ts | 12 ++++-- test/unit/balancer/Balancer.test.ts | 65 +++++++++++++++++++++++------ 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/balancer/OceanPool.ts b/src/balancer/OceanPool.ts index 57ede37e..8acde680 100644 --- a/src/balancer/OceanPool.ts +++ b/src/balancer/OceanPool.ts @@ -3,6 +3,8 @@ import { AbiItem } from 'web3-utils/types' import { TransactionReceipt } from 'web3-core' import { Pool } from './Pool' import { EventData, Filter } from 'web3-eth-contract' +import BigNumber from 'bignumber.js' +import Decimal from 'decimal.js' declare type PoolTransactionType = 'swap' | 'join' | 'exit' @@ -336,7 +338,7 @@ export class OceanPool extends Pool { * @param poolAddress * @param poolShares */ - public async getPoolSharesForRemoveDT( + public async getDTRemovedforPoolShares( poolAddress: string, poolShares: string ): Promise { @@ -357,11 +359,11 @@ export class OceanPool extends Pool { } /** - * Returns DT amnount received after spending poolShares + * Returns Ocean amnount received after spending poolShares * @param poolAddress * @param poolShares */ - public async getPoolSharesForRemoveOcean( + public async getOceanRemovedforPoolShares( poolAddress: string, poolShares: string ): Promise { @@ -395,7 +397,11 @@ export class OceanPool extends Pool { tokenAddress: string ): Promise { const balance = await super.getReserve(poolAddress, tokenAddress) - return String(parseFloat(balance) / 2) + const result = new BigNumber(this.web3.utils.toWei(balance)) + .dividedBy(3) + .integerValue(BigNumber.ROUND_DOWN) + .minus(1) + return this.web3.utils.fromWei(result.toString()) } /** @@ -408,7 +414,11 @@ export class OceanPool extends Pool { tokenAddress: string ): Promise { const balance = await super.getReserve(poolAddress, tokenAddress) - return String(parseFloat(balance) / 3) + const result = new BigNumber(this.web3.utils.toWei(balance)) + .dividedBy(3) + .integerValue(BigNumber.ROUND_DOWN) + .minus(1) + return this.web3.utils.fromWei(result.toString()) } /** @@ -450,9 +460,6 @@ export class OceanPool extends Pool { console.error('oceanAddress is not defined') return null } - if (!maxPrice) { - maxPrice = String(2 ** 256 - 1) - } const dtAddress = await this.getDTAddress(poolAddress) if ( parseFloat(dtAmountWanted) > parseFloat(await this.getDTMaxBuyQuantity(poolAddress)) @@ -501,9 +508,6 @@ export class OceanPool extends Pool { oceanAmountWanted: string, maxPrice?: string ): Promise { - if (!maxPrice) { - maxPrice = String(2 ** 256 - 1) - } if (this.oceanAddress == null) { console.error('oceanAddress is not defined') return null @@ -522,6 +526,7 @@ export class OceanPool extends Pool { console.error('Not enough Data Tokens') return null } + await super.approve(account, dtAddress, poolAddress, this.web3.utils.toWei(dtAmount)) return this.swapExactAmountIn( account, poolAddress, @@ -618,7 +623,7 @@ export class OceanPool extends Pool { console.error('oceanAddress is not defined') return null } - const maxAmount = await this.getMaxAddLiquidity(poolAddress, this.oceanAddress) + const maxAmount = await this.getOceanMaxAddLiquidity(poolAddress) if (parseFloat(amount) > parseFloat(maxAmount)) { console.error('Too much reserve to add') return null diff --git a/src/balancer/Pool.ts b/src/balancer/Pool.ts index c5345a02..c09f5955 100644 --- a/src/balancer/Pool.ts +++ b/src/balancer/Pool.ts @@ -2,9 +2,13 @@ import Web3 from 'web3' import { AbiItem } from 'web3-utils/types' import { TransactionReceipt } from 'web3-core' import Decimal from 'decimal.js' +import BigNumber from 'bignumber.js' import jsonpoolABI from '@oceanprotocol/contracts/artifacts/BPool.json' import { PoolFactory } from './PoolFactory' +const MaxUint256: BigNumber = new BigNumber( + '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' +) /** * Provides an interface to Balancer BPool & BFactory */ @@ -500,7 +504,7 @@ export class Pool extends PoolFactory { tokenAmountIn: string, tokenOut: string, minAmountOut: string, - maxPrice: string + maxPrice?: string ): Promise { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, { from: account @@ -513,7 +517,7 @@ export class Pool extends PoolFactory { this.web3.utils.toWei(tokenAmountIn), tokenOut, this.web3.utils.toWei(minAmountOut), - this.web3.utils.toWei(maxPrice) + maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256 ) .send({ from: account, gas: this.GASLIMIT_DEFAULT }) } catch (e) { @@ -540,7 +544,7 @@ export class Pool extends PoolFactory { maxAmountIn: string, tokenOut: string, minAmountOut: string, - maxPrice: string + maxPrice?: string ): Promise { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, { from: account @@ -553,7 +557,7 @@ export class Pool extends PoolFactory { this.web3.utils.toWei(maxAmountIn), tokenOut, this.web3.utils.toWei(minAmountOut), - this.web3.utils.toWei(maxPrice) + maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256 ) .send({ from: account, gas: this.GASLIMIT_DEFAULT }) } catch (e) { diff --git a/test/unit/balancer/Balancer.test.ts b/test/unit/balancer/Balancer.test.ts index 04a8e650..124e6a58 100644 --- a/test/unit/balancer/Balancer.test.ts +++ b/test/unit/balancer/Balancer.test.ts @@ -177,27 +177,35 @@ describe('Balancer flow', () => { assert(pools.length > 0) greatPool = pools[0] }) - it('Bob should buy a DT ', async () => { + it('Bob should buy 2 DT ', async () => { const maxPrice = parseFloat(currentDtPrice) * 2 - await Pool.buyDT(bob, greatPool, '1', '2', String(maxPrice)) + await Pool.buyDT(bob, greatPool, '2', '4') const bobDtBalance = await datatoken.balance(tokenAddress, bob) const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob) assert(Number(bobDtBalance) > 0) assert(Number(bobOceanBalance) > 0) }) + it('Bob should sell 1 DT ', async () => { + const maxPrice = parseFloat(currentDtPrice) * 2 + await Pool.sellDT(bob, greatPool, '1', '1') + const bobDtBalance = await datatoken.balance(tokenAddress, bob) + const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob) + assert(Number(bobDtBalance) === 1) + assert(Number(bobOceanBalance) > 0) + }) it('Bob should get maximum DT liquidity that he can add to pool ', async () => { - const maxDT = await Pool.getMaxAddLiquidity(greatPool, tokenAddress) + const maxDT = await Pool.getDTMaxAddLiquidity(greatPool) if (consoleDebug) console.error('maxDT:' + maxDT) assert(parseFloat(maxDT) > 0) }) it('Bob should fail to add more than maximum DT liquidity that he can add to pool ', async () => { - const maxDT = await Pool.getMaxAddLiquidity(greatPool, tokenAddress) + const maxDT = await Pool.getDTMaxAddLiquidity(greatPool) const tx = await Pool.addDTLiquidity(bob, greatPool, String(parseFloat(maxDT) * 2)) assert(tx === null) }) it('Bob should add DT liquidity to pool ', async () => { - const maxDT = await Pool.getMaxAddLiquidity(greatPool, tokenAddress) + const maxDT = await Pool.getDTMaxAddLiquidity(greatPool) if (consoleDebug) console.error('maxDT:' + maxDT) const currentDtReserve = await Pool.getDTReserve(greatPool) if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve) @@ -222,12 +230,26 @@ describe('Balancer flow', () => { assert(parseFloat(sharesBalance) > 0) }) it('Bob should get maximum DT liquidity that he can remove from pool ', async () => { - const maxDT = await Pool.getMaxRemoveLiquidity(greatPool, tokenAddress) + const maxDT = await Pool.getDTMaxRemoveLiquidity(greatPool) if (consoleDebug) console.log('maxDT:' + maxDT) assert(parseFloat(maxDT) > 0) }) + it('Bob should know how many Pool Shares he needs to remove 1 DT ', async () => { + const poolShares = await Pool.getPoolSharesRequiredToRemoveDT(greatPool, '1') + if (consoleDebug) console.log('poolShares:' + poolShares) + assert(parseFloat(poolShares) > 0) + }) + it('Bob should know how many DT gets in exchange of his Pool Shares', async () => { + const poolShares = await Pool.getDTRemovedforPoolShares( + greatPool, + await Pool.sharesBalance(bob, greatPool) + ) + if (consoleDebug) console.log('poolShares:' + poolShares) + assert(parseFloat(poolShares) > 0) + }) + it('Bob should fail to remove more than maximum DT liquidity that he can remove from the pool ', async () => { - const maxDT = await Pool.getMaxRemoveLiquidity(greatPool, tokenAddress) + const maxDT = await Pool.getDTMaxRemoveLiquidity(greatPool) if (consoleDebug) console.log('maxDT:' + maxDT) const poolShares = await Pool.sharesBalance(bob, greatPool) const tx = await Pool.removeDTLiquidity( @@ -266,12 +288,12 @@ describe('Balancer flow', () => { }) it('Bob should get maximum Ocean liquidity that he can add to pool ', async () => { - const maxOcean = await Pool.getMaxAddLiquidity(greatPool, oceanTokenAddress) + const maxOcean = await Pool.getOceanMaxAddLiquidity(greatPool) assert(parseFloat(maxOcean) > 0) }) it('Bob should fail to add more than maximum Ocean liquidity that he can add to pool ', async () => { - const maxOcean = await Pool.getMaxAddLiquidity(greatPool, oceanTokenAddress) + const maxOcean = await Pool.getOceanMaxAddLiquidity(greatPool) const tx = await Pool.addOceanLiquidity( bob, greatPool, @@ -285,8 +307,13 @@ describe('Balancer flow', () => { const bobDtBalance = await datatoken.balance(oceanTokenAddress, bob) if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve) if (consoleDebug) console.log('bobDtBalance:' + bobDtBalance) - const maxOcean = await Pool.getMaxAddLiquidity(greatPool, oceanTokenAddress) - await Pool.addOceanLiquidity(bob, greatPool, maxOcean) + const maxOcean = await Pool.getOceanMaxAddLiquidity(greatPool) + + await Pool.addOceanLiquidity( + bob, + greatPool, + String(Math.min(parseFloat(maxOcean), parseFloat(bobDtBalance))) + ) const newbobDtBalance = await datatoken.balance(oceanTokenAddress, bob) @@ -305,7 +332,7 @@ describe('Balancer flow', () => { assert(parseFloat(maxOcean) > 0) }) it('Bob should fail to remove more than maximum Ocean liquidity that he can remove from the pool ', async () => { - const maxOcean = await Pool.getMaxRemoveLiquidity(greatPool, oceanTokenAddress) + const maxOcean = await Pool.getOceanMaxRemoveLiquidity(greatPool) const poolShares = await Pool.sharesBalance(bob, greatPool) const tx = await Pool.removeOceanLiquidity( bob, @@ -315,6 +342,20 @@ describe('Balancer flow', () => { ) assert(tx === null) }) + it('Bob should know how many Pool Shares he needs to remove 1 OCEAN ', async () => { + const poolShares = await Pool.getPoolSharesRequiredToRemoveOcean(greatPool, '1') + if (consoleDebug) console.log('poolShares:' + poolShares) + assert(parseFloat(poolShares) > 0) + }) + it('Bob should know how many OCEAN gets in exchange of his Pool Shares', async () => { + const poolShares = await Pool.getOceanRemovedforPoolShares( + greatPool, + await Pool.sharesBalance(bob, greatPool) + ) + if (consoleDebug) console.log('poolShares:' + poolShares) + assert(parseFloat(poolShares) > 0) + }) + it('Bob should remove Ocean liquidity from pool ', async () => { const currentDtReserve = await Pool.getOceanReserve(greatPool) const bobDtBalance = await datatoken.balance(oceanTokenAddress, bob)