1
0
mirror of https://github.com/oceanprotocol/ocean.js.git synced 2024-11-26 20:39:05 +01:00

add pool validation and helpers

This commit is contained in:
alexcos20 2020-10-12 03:03:06 -07:00
parent a4d3c063d9
commit 8de3d29b2f
3 changed files with 564 additions and 46 deletions

View File

@ -3,6 +3,7 @@ import { AbiItem } from 'web3-utils/types'
import { TransactionReceipt } from 'web3-core'
import { Pool } from './Pool'
import { EventData, Filter } from 'web3-eth-contract'
import { parse } from 'path'
declare type PoolTransactionType = 'swap' | 'join' | 'exit'
@ -143,6 +144,189 @@ export class OceanPool extends Pool {
return super.getReserve(poolAddress, dtAddress)
}
/**
* Returns max amount that you can buy.
* @param poolAddress
* @param tokenAddress
*/
public async getMaxBuyQuantity(
poolAddress: string,
tokenAddress: string
): Promise<string> {
const balance = await super.getReserve(poolAddress, tokenAddress)
return String(parseFloat(balance) / 3)
}
/**
* Returns tokenInAmount required to get tokenOutAmount
* @param poolAddress
* @param tokenInAddress
* @param tokenOutAddress
* @param tokenOutAmount
*/
public async calcInGivenOut(
poolAddress: string,
tokenInAddress: string,
tokenOutAddress: string,
tokenOutAmount: string
): Promise<string> {
const result = await super.calcInGivenOut(
poolAddress,
await super.getReserve(poolAddress, tokenInAddress),
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
await super.getReserve(poolAddress, tokenOutAddress),
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
tokenOutAmount,
await this.getSwapFee(poolAddress)
)
return result
}
/**
* Returns tokenOutAmount given tokenInAmount
* @param poolAddress
* @param tokenInAddress
* @param tokenOutAddress
* @param tokenInAmount
*/
public async calcOutGivenIn(
poolAddress: string,
tokenInAddress: string,
tokenOutAddress: string,
tokenInAmount: string
): Promise<string> {
const result = await super.calcOutGivenIn(
poolAddress,
await super.getReserve(poolAddress, tokenInAddress),
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
await super.getReserve(poolAddress, tokenOutAddress),
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
tokenInAmount,
await super.getSwapFee(poolAddress)
)
return result
}
/**
* Returns no of shares receved for adding a token to the pool
* @param poolAddress
* @param tokenInAddress
* @param tokenInAmount
*/
public async calcPoolOutGivenSingleIn(
poolAddress: string,
tokenInAddress: string,
tokenInAmount: string
): Promise<string> {
const result = super.calcPoolOutGivenSingleIn(
poolAddress,
await super.getReserve(poolAddress, tokenInAddress),
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
await super.getPoolSharesTotalSupply(poolAddress),
await super.getTotalDenormalizedWeight(poolAddress),
tokenInAmount,
await super.getSwapFee(poolAddress)
)
return result
}
/**
* Returns no of tokens required to get a specific no of poolShares
* @param poolAddress
* @param tokenInAddress
* @param poolShares
*/
public async calcSingleInGivenPoolOut(
poolAddress: string,
tokenInAddress: string,
poolShares: string
): Promise<string> {
const result = super.calcSingleInGivenPoolOut(
poolAddress,
await super.getReserve(poolAddress, tokenInAddress),
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
await super.getPoolSharesTotalSupply(poolAddress),
await super.getTotalDenormalizedWeight(poolAddress),
poolShares,
await super.getSwapFee(poolAddress)
)
return result
}
/**
* Returns no of tokens received for spending a specific no of poolShares
* @param poolAddress
* @param tokenOutAddress
* @param poolShares
*/
public async calcSingleOutGivenPoolIn(
poolAddress: string,
tokenOutAddress: string,
poolShares: string
): Promise<string> {
const result = super.calcSingleOutGivenPoolIn(
poolAddress,
await super.getReserve(poolAddress, tokenOutAddress),
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
await super.getPoolSharesTotalSupply(poolAddress),
await super.getTotalDenormalizedWeight(poolAddress),
poolShares,
await super.getSwapFee(poolAddress)
)
return result
}
/**
* Returns no of pool shares required to receive a specified amount of tokens
* @param poolAddress
* @param tokenOutAddress
* @param tokenOutAmount
*/
public async calcPoolInGivenSingleOut(
poolAddress: string,
tokenOutAddress: string,
tokenOutAmount: string
): Promise<string> {
const result = super.calcPoolInGivenSingleOut(
poolAddress,
await super.getReserve(poolAddress, tokenOutAddress),
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
await super.getPoolSharesTotalSupply(poolAddress),
await super.getTotalDenormalizedWeight(poolAddress),
tokenOutAmount,
await super.getSwapFee(poolAddress)
)
return result
}
/**
* Returns max amount of tokens that you can add to the pool
* @param poolAddress
* @param tokenAddress
*/
public async getMaxAddLiquidity(
poolAddress: string,
tokenAddress: string
): Promise<string> {
const balance = await super.getReserve(poolAddress, tokenAddress)
return String(parseFloat(balance) / 2)
}
/**
* Returns max amount of tokens that you can withdraw from the pool
* @param poolAddress
* @param tokenAddress
*/
public async getMaxRemoveLiquidity(
poolAddress: string,
tokenAddress: string
): Promise<string> {
const balance = await super.getReserve(poolAddress, tokenAddress)
return String(parseFloat(balance) / 3)
}
/**
* Buy Data Token from a pool
* @param {String} account
@ -155,31 +339,51 @@ export class OceanPool extends Pool {
public async buyDT(
account: string,
poolAddress: string,
amount: string,
oceanAmount: string,
maxPrice: string
dtAmountWanted: string,
maxOceanAmount: string,
maxPrice?: string
): Promise<TransactionReceipt> {
if (this.oceanAddress == null) {
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.getMaxBuyQuantity(poolAddress, dtAddress))
) {
console.error('Buy quantity exceeds quantity allowed')
return null
}
const calcInGivenOut = await this.calcInGivenOut(
poolAddress,
this.oceanAddress,
dtAddress,
dtAmountWanted
)
if (parseFloat(calcInGivenOut) > parseFloat(maxOceanAmount)) {
console.error('Not enough Ocean Tokens')
return null
}
// TODO - check balances first
await super.approve(
account,
this.oceanAddress,
poolAddress,
this.web3.utils.toWei(oceanAmount)
this.web3.utils.toWei(maxOceanAmount)
)
return this.swapExactAmountOut(
account,
poolAddress,
this.oceanAddress,
oceanAmount,
maxOceanAmount,
dtAddress,
amount,
dtAmountWanted,
maxPrice
)
}
@ -188,7 +392,7 @@ export class OceanPool extends Pool {
* Sell Data Token
* @param {String} account
* @param {String} poolAddress
* @param {String} amount Data Token amount
* @param {String} amount Data Token amount to be sold
* @param {String} oceanAmount Ocean Token amount expected
* @param {String} maxPrice Minimum price to sell
* @return {TransactionReceipt}
@ -196,23 +400,43 @@ export class OceanPool extends Pool {
public async sellDT(
account: string,
poolAddress: string,
amount: string,
oceanAmount: string,
minPrice: string
dtAmount: string,
oceanAmountWanted: string,
maxPrice?: string
): Promise<TransactionReceipt> {
if (!maxPrice) {
maxPrice = String(2 ** 256 - 1)
}
if (this.oceanAddress == null) {
console.error('oceanAddress is not defined')
return null
}
const dtAddress = await this.getDTAddress(poolAddress)
return this.swapExactAmountOut(
if (
parseFloat(oceanAmountWanted) >
parseFloat(await this.getMaxBuyQuantity(poolAddress, this.oceanAddress))
) {
console.error('Buy quantity exceeds quantity allowed')
return null
}
const calcOutGivenIn = await this.calcOutGivenIn(
poolAddress,
dtAddress,
this.oceanAddress,
dtAmount
)
if (parseFloat(calcOutGivenIn) < parseFloat(oceanAmountWanted)) {
console.error('Not enough Data Tokens')
return null
}
return this.swapExactAmountIn(
account,
poolAddress,
dtAddress,
amount,
dtAmount,
this.oceanAddress,
oceanAmount,
minPrice
oceanAmountWanted,
maxPrice
)
}
@ -229,6 +453,11 @@ export class OceanPool extends Pool {
amount: string
): Promise<TransactionReceipt> {
const dtAddress = await this.getDTAddress(poolAddress)
const maxAmount = await this.getMaxAddLiquidity(poolAddress, dtAddress)
if (parseFloat(amount) > parseFloat(maxAmount)) {
console.error('Too much reserve to add')
return null
}
await super.approve(account, dtAddress, poolAddress, this.web3.utils.toWei(amount))
const result = await super.joinswapExternAmountIn(
account,
@ -254,7 +483,23 @@ export class OceanPool extends Pool {
maximumPoolShares: string
): Promise<TransactionReceipt> {
const dtAddress = await this.getDTAddress(poolAddress)
// TODO Check balance of PoolShares before doing exit
const maxAmount = await this.getMaxRemoveLiquidity(poolAddress, dtAddress)
if (parseFloat(amount) > parseFloat(maxAmount)) {
console.error('Too much reserve to remove')
return null
}
const usershares = await this.sharesBalance(account, poolAddress)
if (parseFloat(usershares) < parseFloat(maximumPoolShares)) {
console.error('Not enough poolShares')
return null
}
if (
parseFloat(maximumPoolShares) <
parseFloat(await this.calcPoolInGivenSingleOut(poolAddress, dtAddress, amount))
) {
console.error('Not enough poolShares')
return null
}
return this.exitswapExternAmountOut(
account,
poolAddress,
@ -280,6 +525,11 @@ export class OceanPool extends Pool {
console.error('oceanAddress is not defined')
return null
}
const maxAmount = await this.getMaxAddLiquidity(poolAddress, this.oceanAddress)
if (parseFloat(amount) > parseFloat(maxAmount)) {
console.error('Too much reserve to add')
return null
}
await super.approve(
account,
this.oceanAddress,
@ -303,7 +553,7 @@ export class OceanPool extends Pool {
* @param {String} amount Ocean Token amount in OCEAN
* @return {TransactionReceipt}
*/
public removeOceanLiquidity(
public async removeOceanLiquidity(
account: string,
poolAddress: string,
amount: string,
@ -313,7 +563,25 @@ export class OceanPool extends Pool {
console.error('oceanAddress is not defined')
return null
}
// TODO Check balance of PoolShares before doing exit
const maxAmount = await this.getMaxRemoveLiquidity(poolAddress, this.oceanAddress)
if (parseFloat(amount) > parseFloat(maxAmount)) {
console.error('Too much reserve to remove')
return null
}
const usershares = await this.sharesBalance(account, poolAddress)
if (parseFloat(usershares) < parseFloat(maximumPoolShares)) {
console.error('Not enough poolShares')
return null
}
if (
parseFloat(maximumPoolShares) <
parseFloat(
await this.calcPoolInGivenSingleOut(poolAddress, this.oceanAddress, amount)
)
) {
console.error('Not enough poolShares')
return null
}
return super.exitswapExternAmountOut(
account,
poolAddress,
@ -323,6 +591,27 @@ export class OceanPool extends Pool {
)
}
/**
* Remove pool liquidity
* @param {String} account
* @param {String} poolAddress
* @param {String} poolShares
* @return {TransactionReceipt}
*/
public async removePoolLiquidity(
account: string,
poolAddress: string,
poolShares: string
): Promise<TransactionReceipt> {
const usershares = await this.sharesBalance(account, poolAddress)
if (parseFloat(usershares) < parseFloat(poolShares)) {
console.error('Not enough poolShares')
return null
}
return this.exitPool(account, poolAddress, poolShares, ['0', '0'])
}
/**
* Get Data Token price from pool
* @param {String} poolAddress
@ -358,19 +647,7 @@ export class OceanPool extends Pool {
public async getOceanNeeded(poolAddress: string, dtRequired: string): Promise<string> {
const dtAddress = await this.getDTAddress(poolAddress)
const tokenBalanceIn = await this.getReserve(poolAddress, this.oceanAddress)
const tokenWeightIn = await this.getDenormalizedWeight(poolAddress, this.oceanAddress)
const tokenBalanceOut = await this.getReserve(poolAddress, dtAddress)
const tokenWeightOut = await this.getDenormalizedWeight(poolAddress, dtAddress)
const swapFee = await this.getSwapFee(poolAddress)
return super.calcInGivenOut(
tokenBalanceIn,
tokenWeightIn,
tokenBalanceOut,
tokenWeightOut,
dtRequired,
swapFee
)
return this.calcInGivenOut(poolAddress, this.oceanAddress, dtAddress, dtRequired)
}
/**

View File

@ -270,6 +270,23 @@ export class Pool extends PoolFactory {
return result
}
/**
* Get total supply of pool shares
* @param {String} poolAddress
* @return {String}
*/
async getPoolSharesTotalSupply(poolAddress: string): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
try {
const result = await pool.methods.totalSupply().call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
console.error(e)
}
return amount
}
/**
* Get tokens composing this pool
* @param {String} poolAddress
@ -594,7 +611,7 @@ export class Pool extends PoolFactory {
account: string,
poolAddress: string,
poolAmountIn: string,
minAmountsOut: string
minAmountsOut: string[]
): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, {
from: account
@ -799,6 +816,7 @@ export class Pool extends PoolFactory {
}
public async calcInGivenOut(
poolAddress: string,
tokenBalanceIn: string,
tokenWeightIn: string,
tokenBalanceOut: string,
@ -806,14 +824,168 @@ export class Pool extends PoolFactory {
tokenAmountOut: string,
swapFee: string
): Promise<string> {
const weightRatio = new Decimal(tokenWeightOut).div(new Decimal(tokenWeightIn))
const diff = new Decimal(tokenBalanceOut).minus(tokenAmountOut)
const y = new Decimal(tokenBalanceOut).div(diff)
const foo = y.pow(weightRatio).minus(new Decimal(1))
const tokenAmountIn = new Decimal(tokenBalanceIn)
.times(foo)
.div(new Decimal(1).minus(new Decimal(swapFee)))
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
try {
const result = await pool.methods
.calcInGivenOut(
this.web3.utils.toWei(tokenBalanceIn),
this.web3.utils.toWei(tokenWeightIn),
this.web3.utils.toWei(tokenBalanceOut),
this.web3.utils.toWei(tokenWeightOut),
this.web3.utils.toWei(tokenAmountOut),
this.web3.utils.toWei(swapFee)
)
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
console.error(e)
}
return amount
}
return tokenAmountIn.toString()
public async calcOutGivenIn(
poolAddress: string,
tokenBalanceIn: string,
tokenWeightIn: string,
tokenBalanceOut: string,
tokenWeightOut: string,
tokenAmountIn: string,
swapFee: string
): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
try {
const result = await pool.methods
.calcOutGivenIn(
this.web3.utils.toWei(tokenBalanceIn),
this.web3.utils.toWei(tokenWeightIn),
this.web3.utils.toWei(tokenBalanceOut),
this.web3.utils.toWei(tokenWeightOut),
this.web3.utils.toWei(tokenAmountIn),
this.web3.utils.toWei(swapFee)
)
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
console.error(e)
}
return amount
}
public async calcPoolOutGivenSingleIn(
poolAddress: string,
tokenBalanceIn: string,
tokenWeightIn: string,
poolSupply: string,
totalWeight: string,
tokenAmountIn: string,
swapFee: string
): Promise<string> {
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)
)
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
console.error(e)
}
return amount
}
public async calcSingleInGivenPoolOut(
poolAddress: string,
tokenBalanceIn: string,
tokenWeightIn: string,
poolSupply: string,
totalWeight: string,
poolAmountOut: string,
swapFee: string
): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null
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)
)
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
console.error(e)
}
return amount
}
public async calcSingleOutGivenPoolIn(
poolAddress: string,
tokenBalanceOut: string,
tokenWeightOut: string,
poolSupply: string,
totalWeight: string,
poolAmountIn: string,
swapFee: string
): Promise<string> {
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)
)
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
console.error(e)
}
return amount
}
public async calcPoolInGivenSingleOut(
poolAddress: string,
tokenBalanceOut: string,
tokenWeightOut: string,
poolSupply: string,
totalWeight: string,
tokenAmountOut: string,
swapFee: string
): Promise<string> {
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)
)
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
console.error(e)
}
return amount
}
}

View File

@ -27,7 +27,7 @@ describe('Balancer flow', () => {
let contracts: TestContractHandler
let datatoken: DataTokens
let tokenAddress: string
let consoleDebug: false
let consoleDebug: true
let greatPool: string
const tokenAmount = '1000'
const transferAmount = '200'
@ -185,12 +185,29 @@ describe('Balancer flow', () => {
assert(Number(bobDtBalance) > 0)
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)
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 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)
if (consoleDebug) console.error('maxDT:' + maxDT)
const currentDtReserve = await Pool.getDTReserve(greatPool)
if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve)
const bobDtBalance = await datatoken.balance(tokenAddress, bob)
if (consoleDebug) console.log('BOB DT Balance:' + bobDtBalance)
await Pool.addDTLiquidity(bob, greatPool, bobDtBalance)
await Pool.addDTLiquidity(
bob,
greatPool,
String(Math.min(parseFloat(maxDT), parseFloat(bobDtBalance)))
)
const newbobDtBalance = await datatoken.balance(tokenAddress, bob)
@ -204,7 +221,23 @@ describe('Balancer flow', () => {
assert(parseFloat(newDtReserve) > parseFloat(currentDtReserve))
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)
if (consoleDebug) console.log('maxDT:' + maxDT)
assert(parseFloat(maxDT) > 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)
if (consoleDebug) console.log('maxDT:' + maxDT)
const poolShares = await Pool.sharesBalance(bob, greatPool)
const tx = await Pool.removeDTLiquidity(
bob,
greatPool,
String(parseFloat(maxDT) * 2),
poolShares
)
assert(tx === null)
})
it('Bob should remove DT liquidity from pool ', async () => {
const currentDtReserve = await Pool.getDTReserve(greatPool)
if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve)
@ -212,7 +245,14 @@ describe('Balancer flow', () => {
if (consoleDebug) console.log('bobDtBalance:' + bobDtBalance)
const poolShares = await Pool.sharesBalance(bob, greatPool)
if (consoleDebug) console.log('poolShares:' + poolShares)
await Pool.removeDTLiquidity(bob, greatPool, '0.75', poolShares)
const maxDT = await Pool.getMaxRemoveLiquidity(greatPool, tokenAddress)
if (consoleDebug) console.log('maxDT:' + maxDT)
await Pool.removeDTLiquidity(
bob,
greatPool,
String(Math.min(parseFloat(maxDT), parseFloat('0.75'))),
poolShares
)
const newDtReserve = await Pool.getDTReserve(greatPool)
if (consoleDebug) console.log('newDtReserve:' + newDtReserve)
@ -225,13 +265,28 @@ describe('Balancer flow', () => {
assert(parseFloat(poolShares) > parseFloat(newpoolShares))
})
it('Bob should get maximum Ocean liquidity that he can add to pool ', async () => {
const maxOcean = await Pool.getMaxAddLiquidity(greatPool, oceanTokenAddress)
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 tx = await Pool.addOceanLiquidity(
bob,
greatPool,
String(parseFloat(maxOcean) * 2)
)
assert(tx === null)
})
it('Bob should add Ocean liquidity to pool ', async () => {
const currentDtReserve = await Pool.getOceanReserve(greatPool)
const bobDtBalance = await datatoken.balance(oceanTokenAddress, bob)
if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve)
if (consoleDebug) console.log('bobDtBalance:' + bobDtBalance)
await Pool.addOceanLiquidity(bob, greatPool, '1')
const maxOcean = await Pool.getMaxAddLiquidity(greatPool, oceanTokenAddress)
await Pool.addOceanLiquidity(bob, greatPool, maxOcean)
const newbobDtBalance = await datatoken.balance(oceanTokenAddress, bob)
@ -245,7 +300,21 @@ describe('Balancer flow', () => {
assert(parseFloat(newDtReserve) > parseFloat(currentDtReserve))
assert(parseFloat(sharesBalance) > 0)
})
it('Bob should get maximum Ocean liquidity that he can remove from pool ', async () => {
const maxOcean = await Pool.getMaxRemoveLiquidity(greatPool, oceanTokenAddress)
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 poolShares = await Pool.sharesBalance(bob, greatPool)
const tx = await Pool.removeOceanLiquidity(
bob,
greatPool,
String(parseFloat(maxOcean) * 2),
poolShares
)
assert(tx === null)
})
it('Bob should remove Ocean liquidity from pool ', async () => {
const currentDtReserve = await Pool.getOceanReserve(greatPool)
const bobDtBalance = await datatoken.balance(oceanTokenAddress, bob)