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:
parent
a4d3c063d9
commit
8de3d29b2f
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user