mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
Feature/use decimal in pool (#775)
* change default gas settings * check allowance & fix gas estimate * use Decimal * fix estimateGas for new Pools
This commit is contained in:
parent
c544eaf446
commit
3a5569b12f
@ -220,7 +220,7 @@ export class OceanPool extends Pool {
|
|||||||
tokenAddress: string
|
tokenAddress: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||||
return String(parseFloat(balance) / 3)
|
return new Decimal(balance).div(3).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -449,14 +449,14 @@ export class OceanPool extends Pool {
|
|||||||
const totalPoolTokens = await this.getPoolSharesTotalSupply(poolAddress)
|
const totalPoolTokens = await this.getPoolSharesTotalSupply(poolAddress)
|
||||||
const dtReserve = await this.getDTReserve(poolAddress)
|
const dtReserve = await this.getDTReserve(poolAddress)
|
||||||
const oceanReserve = await this.getOceanReserve(poolAddress)
|
const oceanReserve = await this.getOceanReserve(poolAddress)
|
||||||
|
const dtAmount = new Decimal(poolShares)
|
||||||
const dtAmount = `${
|
.div(totalPoolTokens)
|
||||||
(Number(poolShares) / Number(totalPoolTokens)) * Number(dtReserve)
|
.mul(dtReserve)
|
||||||
}`
|
.toString()
|
||||||
const oceanAmount = `${
|
const oceanAmount = new Decimal(poolShares)
|
||||||
(Number(poolShares) / Number(totalPoolTokens)) * Number(oceanReserve)
|
.div(totalPoolTokens)
|
||||||
}`
|
.mul(oceanReserve)
|
||||||
|
.toString()
|
||||||
return { dtAmount, oceanAmount }
|
return { dtAmount, oceanAmount }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.error(`ERROR: Unable to get token info. ${e.message}`)
|
this.logger.error(`ERROR: Unable to get token info. ${e.message}`)
|
||||||
@ -491,11 +491,7 @@ export class OceanPool extends Pool {
|
|||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||||
if (parseFloat(balance) > 0) {
|
if (parseFloat(balance) > 0) {
|
||||||
const result = new BigNumber(this.web3.utils.toWei(balance))
|
return new Decimal(balance).mul(POOL_MAX_AMOUNT_IN_LIMIT).toString()
|
||||||
.multipliedBy(POOL_MAX_AMOUNT_IN_LIMIT)
|
|
||||||
.integerValue(BigNumber.ROUND_DOWN)
|
|
||||||
.minus(1)
|
|
||||||
return this.web3.utils.fromWei(result.toString(10))
|
|
||||||
} else return '0'
|
} else return '0'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,11 +506,7 @@ export class OceanPool extends Pool {
|
|||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||||
if (parseFloat(balance) > 0) {
|
if (parseFloat(balance) > 0) {
|
||||||
const result = new BigNumber(this.web3.utils.toWei(balance))
|
return new Decimal(balance).mul(POOL_MAX_AMOUNT_OUT_LIMIT).toString()
|
||||||
.multipliedBy(POOL_MAX_AMOUNT_OUT_LIMIT)
|
|
||||||
.integerValue(BigNumber.ROUND_DOWN)
|
|
||||||
.minus(1)
|
|
||||||
return this.web3.utils.fromWei(result.toString(10))
|
|
||||||
} else return '0'
|
} else return '0'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,14 +551,13 @@ export class OceanPool extends Pool {
|
|||||||
}
|
}
|
||||||
const dtAddress = await this.getDTAddress(poolAddress)
|
const dtAddress = await this.getDTAddress(poolAddress)
|
||||||
if (
|
if (
|
||||||
parseFloat(dtAmountWanted) > parseFloat(await this.getDTMaxBuyQuantity(poolAddress))
|
new Decimal(dtAmountWanted).greaterThan(await this.getDTMaxBuyQuantity(poolAddress))
|
||||||
) {
|
) {
|
||||||
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const calcInGivenOut = await this.getOceanNeeded(poolAddress, dtAmountWanted)
|
const calcInGivenOut = await this.getOceanNeeded(poolAddress, dtAmountWanted)
|
||||||
|
if (new Decimal(calcInGivenOut).greaterThan(maxOceanAmount)) {
|
||||||
if (parseFloat(calcInGivenOut) > parseFloat(maxOceanAmount)) {
|
|
||||||
this.logger.error('ERROR: Not enough Ocean Tokens')
|
this.logger.error('ERROR: Not enough Ocean Tokens')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -615,15 +606,15 @@ export class OceanPool extends Pool {
|
|||||||
}
|
}
|
||||||
const dtAddress = await this.getDTAddress(poolAddress)
|
const dtAddress = await this.getDTAddress(poolAddress)
|
||||||
if (
|
if (
|
||||||
parseFloat(minimumdtAmountWanted) >
|
new Decimal(minimumdtAmountWanted).greaterThan(
|
||||||
parseFloat(await this.getDTMaxBuyQuantity(poolAddress))
|
await this.getDTMaxBuyQuantity(poolAddress)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const calcInGivenOut = await this.getOceanNeeded(poolAddress, minimumdtAmountWanted)
|
const calcInGivenOut = await this.getOceanNeeded(poolAddress, minimumdtAmountWanted)
|
||||||
|
if (new Decimal(calcInGivenOut).greaterThan(OceanAmount)) {
|
||||||
if (parseFloat(calcInGivenOut) > parseFloat(OceanAmount)) {
|
|
||||||
this.logger.error('ERROR: Not enough Ocean Tokens')
|
this.logger.error('ERROR: Not enough Ocean Tokens')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -672,15 +663,15 @@ export class OceanPool extends Pool {
|
|||||||
}
|
}
|
||||||
const dtAddress = await this.getDTAddress(poolAddress)
|
const dtAddress = await this.getDTAddress(poolAddress)
|
||||||
if (
|
if (
|
||||||
parseFloat(oceanAmountWanted) >
|
new Decimal(oceanAmountWanted).greaterThan(
|
||||||
parseFloat(await this.getOceanMaxBuyQuantity(poolAddress))
|
await this.getOceanMaxBuyQuantity(poolAddress)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const calcOutGivenIn = await this.getOceanReceived(poolAddress, dtAmount)
|
const calcOutGivenIn = await this.getOceanReceived(poolAddress, dtAmount)
|
||||||
|
if (new Decimal(calcOutGivenIn).lessThan(oceanAmountWanted)) {
|
||||||
if (parseFloat(calcOutGivenIn) < parseFloat(oceanAmountWanted)) {
|
|
||||||
this.logger.error('ERROR: Not enough datatokens')
|
this.logger.error('ERROR: Not enough datatokens')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -720,7 +711,7 @@ export class OceanPool extends Pool {
|
|||||||
): Promise<TransactionReceipt> {
|
): Promise<TransactionReceipt> {
|
||||||
const dtAddress = await this.getDTAddress(poolAddress)
|
const dtAddress = await this.getDTAddress(poolAddress)
|
||||||
const maxAmount = await this.getMaxAddLiquidity(poolAddress, dtAddress)
|
const maxAmount = await this.getMaxAddLiquidity(poolAddress, dtAddress)
|
||||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
if (new Decimal(amount).greaterThan(maxAmount)) {
|
||||||
this.logger.error('ERROR: Too much reserve to add')
|
this.logger.error('ERROR: Too much reserve to add')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -760,23 +751,23 @@ export class OceanPool extends Pool {
|
|||||||
): Promise<TransactionReceipt> {
|
): Promise<TransactionReceipt> {
|
||||||
const dtAddress = await this.getDTAddress(poolAddress)
|
const dtAddress = await this.getDTAddress(poolAddress)
|
||||||
const maxAmount = await this.getDTMaxRemoveLiquidity(poolAddress)
|
const maxAmount = await this.getDTMaxRemoveLiquidity(poolAddress)
|
||||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
if (new Decimal(amount).greaterThan(maxAmount)) {
|
||||||
this.logger.error('ERROR: Too much reserve to remove')
|
this.logger.error('ERROR: Too much reserve to remove')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const usershares = await this.sharesBalance(account, poolAddress)
|
const usershares = await this.sharesBalance(account, poolAddress)
|
||||||
if (parseFloat(usershares) < parseFloat(maximumPoolShares)) {
|
if (new Decimal(usershares).lessThan(maximumPoolShares)) {
|
||||||
this.logger.error('ERROR: Not enough poolShares')
|
this.logger.error('ERROR: Not enough poolShares')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const sharesRequired = await this.getPoolSharesRequiredToRemoveDT(poolAddress, amount)
|
const sharesRequired = await this.getPoolSharesRequiredToRemoveDT(poolAddress, amount)
|
||||||
if (parseFloat(maximumPoolShares) < parseFloat(sharesRequired)) {
|
if (new Decimal(maximumPoolShares).lessThan(sharesRequired)) {
|
||||||
this.logger.error('ERROR: Not enough poolShares')
|
this.logger.error('ERROR: Not enough poolShares')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
// Balancer bug fix
|
// Balancer bug fix
|
||||||
if (parseFloat(maximumPoolShares) < parseFloat(sharesRequired))
|
if (new Decimal(maximumPoolShares).lessThan(sharesRequired))
|
||||||
maximumPoolShares = String(parseFloat(maximumPoolShares) * 0.9999)
|
maximumPoolShares = new Decimal(maximumPoolShares).mul(0.9999).toString()
|
||||||
// Balance bug fix
|
// Balance bug fix
|
||||||
return this.exitswapExternAmountOut(
|
return this.exitswapExternAmountOut(
|
||||||
account,
|
account,
|
||||||
@ -804,7 +795,7 @@ export class OceanPool extends Pool {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const maxAmount = await this.getOceanMaxAddLiquidity(poolAddress)
|
const maxAmount = await this.getOceanMaxAddLiquidity(poolAddress)
|
||||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
if (new Decimal(amount).greaterThan(maxAmount)) {
|
||||||
this.logger.error('ERROR: Too much reserve to add')
|
this.logger.error('ERROR: Too much reserve to add')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -847,7 +838,7 @@ export class OceanPool extends Pool {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const usershares = await this.sharesBalance(account, poolAddress)
|
const usershares = await this.sharesBalance(account, poolAddress)
|
||||||
if (parseFloat(usershares) < parseFloat(poolShares)) {
|
if (new Decimal(usershares).lessThan(poolShares)) {
|
||||||
this.logger.error('ERROR: Not enough poolShares')
|
this.logger.error('ERROR: Not enough poolShares')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -880,12 +871,12 @@ export class OceanPool extends Pool {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const maxAmount = await this.getOceanMaxRemoveLiquidity(poolAddress)
|
const maxAmount = await this.getOceanMaxRemoveLiquidity(poolAddress)
|
||||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
if (new Decimal(amount).greaterThan(maxAmount)) {
|
||||||
this.logger.error('ERROR: Too much reserve to remove')
|
this.logger.error('ERROR: Too much reserve to remove')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const usershares = await this.sharesBalance(account, poolAddress)
|
const usershares = await this.sharesBalance(account, poolAddress)
|
||||||
if (parseFloat(usershares) < parseFloat(maximumPoolShares)) {
|
if (new Decimal(usershares).lessThan(maximumPoolShares)) {
|
||||||
this.logger.error('ERROR: Not enough poolShares')
|
this.logger.error('ERROR: Not enough poolShares')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -893,13 +884,13 @@ export class OceanPool extends Pool {
|
|||||||
poolAddress,
|
poolAddress,
|
||||||
amount
|
amount
|
||||||
)
|
)
|
||||||
if (parseFloat(maximumPoolShares) < parseFloat(sharesRequired)) {
|
if (new Decimal(maximumPoolShares).lessThan(sharesRequired)) {
|
||||||
this.logger.error('ERROR: Not enough poolShares')
|
this.logger.error('ERROR: Not enough poolShares')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
// Balancer bug fix
|
// Balancer bug fix
|
||||||
if (parseFloat(maximumPoolShares) < parseFloat(sharesRequired))
|
if (new Decimal(maximumPoolShares).lessThan(sharesRequired))
|
||||||
maximumPoolShares = String(parseFloat(maximumPoolShares) * 0.9999)
|
maximumPoolShares = new Decimal(maximumPoolShares).mul(0.9999).toString()
|
||||||
// Balance bug fix
|
// Balance bug fix
|
||||||
return super.exitswapExternAmountOut(
|
return super.exitswapExternAmountOut(
|
||||||
account,
|
account,
|
||||||
@ -927,13 +918,13 @@ export class OceanPool extends Pool {
|
|||||||
minOcean = '0'
|
minOcean = '0'
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<TransactionReceipt> {
|
||||||
const usershares = await this.sharesBalance(account, poolAddress)
|
const usershares = await this.sharesBalance(account, poolAddress)
|
||||||
if (parseFloat(usershares) < parseFloat(poolShares)) {
|
if (new Decimal(usershares).lessThan(poolShares)) {
|
||||||
this.logger.error('ERROR: Not enough poolShares')
|
this.logger.error('ERROR: Not enough poolShares')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
// Balancer bug fix
|
// Balancer bug fix
|
||||||
if (parseFloat(usershares) === parseFloat(poolShares))
|
if (new Decimal(usershares).equals(poolShares))
|
||||||
poolShares = String(parseFloat(poolShares) * 0.9999)
|
poolShares = new Decimal(poolShares).mul(0.9999).toString()
|
||||||
// Balance bug fix
|
// Balance bug fix
|
||||||
return this.exitPool(account, poolAddress, poolShares, [minDT, minOcean])
|
return this.exitPool(account, poolAddress, poolShares, [minDT, minOcean])
|
||||||
}
|
}
|
||||||
@ -975,7 +966,7 @@ export class OceanPool extends Pool {
|
|||||||
public async getOceanNeeded(poolAddress: string, dtRequired: string): Promise<string> {
|
public async getOceanNeeded(poolAddress: string, dtRequired: string): Promise<string> {
|
||||||
const dtAddress = await this.getDTAddress(poolAddress)
|
const dtAddress = await this.getDTAddress(poolAddress)
|
||||||
if (
|
if (
|
||||||
parseFloat(dtRequired) > parseFloat(await this.getDTMaxBuyQuantity(poolAddress))
|
new Decimal(dtRequired).greaterThan(await this.getDTMaxBuyQuantity(poolAddress))
|
||||||
) {
|
) {
|
||||||
return '0'
|
return '0'
|
||||||
}
|
}
|
||||||
@ -1007,8 +998,9 @@ export class OceanPool extends Pool {
|
|||||||
public async getDTNeeded(poolAddress: string, OceanRequired: string): Promise<string> {
|
public async getDTNeeded(poolAddress: string, OceanRequired: string): Promise<string> {
|
||||||
const dtAddress = await this.getDTAddress(poolAddress)
|
const dtAddress = await this.getDTAddress(poolAddress)
|
||||||
if (
|
if (
|
||||||
parseFloat(OceanRequired) >
|
new Decimal(OceanRequired).greaterThan(
|
||||||
parseFloat(await this.getOceanMaxBuyQuantity(poolAddress))
|
await this.getOceanMaxBuyQuantity(poolAddress)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return '0'
|
return '0'
|
||||||
}
|
}
|
||||||
@ -1295,8 +1287,7 @@ export class OceanPool extends Pool {
|
|||||||
tokenOutWeight,
|
tokenOutWeight,
|
||||||
swapfee
|
swapfee
|
||||||
)
|
)
|
||||||
const slippage = (parseFloat(newPrice) * 100) / parseFloat(initialPrice) - 100
|
return new Decimal(newPrice).mul(100).div(initialPrice).minus(100).toString()
|
||||||
return String(slippage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get slippage for buying some datatokens while spending exactly oceanAmount ocean tokens */
|
/* Get slippage for buying some datatokens while spending exactly oceanAmount ocean tokens */
|
||||||
|
@ -134,12 +134,14 @@ export class Pool extends PoolFactory {
|
|||||||
* @param {String} tokenAddress
|
* @param {String} tokenAddress
|
||||||
* @param {String} spender
|
* @param {String} spender
|
||||||
* @param {String} amount (always expressed as wei)
|
* @param {String} amount (always expressed as wei)
|
||||||
|
* @param {String} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed
|
||||||
*/
|
*/
|
||||||
async approve(
|
async approve(
|
||||||
account: string,
|
account: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
spender: string,
|
spender: string,
|
||||||
amount: string
|
amount: string,
|
||||||
|
force = false
|
||||||
): Promise<TransactionReceipt> {
|
): Promise<TransactionReceipt> {
|
||||||
const minABI = [
|
const minABI = [
|
||||||
{
|
{
|
||||||
@ -169,6 +171,13 @@ export class Pool extends PoolFactory {
|
|||||||
const token = new this.web3.eth.Contract(minABI, tokenAddress, {
|
const token = new this.web3.eth.Contract(minABI, tokenAddress, {
|
||||||
from: account
|
from: account
|
||||||
})
|
})
|
||||||
|
if (!force) {
|
||||||
|
const currentAllowence = await this.allowance(tokenAddress, account, spender)
|
||||||
|
if (new Decimal(currentAllowence).greaterThanOrEqualTo(amount)) {
|
||||||
|
// we have enough
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
let result = null
|
let result = null
|
||||||
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
let estGas
|
let estGas
|
||||||
@ -890,7 +899,7 @@ export class Pool extends PoolFactory {
|
|||||||
)
|
)
|
||||||
.send({
|
.send({
|
||||||
from: account,
|
from: account,
|
||||||
gas: this.GASLIMIT_DEFAULT,
|
gas: estGas + 1,
|
||||||
gasPrice: await getFairGasPrice(this.web3)
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -45,10 +45,19 @@ export class PoolFactory {
|
|||||||
from: account
|
from: account
|
||||||
})
|
})
|
||||||
let txid = null
|
let txid = null
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
try {
|
try {
|
||||||
txid = await factory.methods
|
estGas = await factory.methods
|
||||||
.newBPool()
|
.newBPool()
|
||||||
.send({ from: account, gas: this.GASLIMIT_DEFAULT })
|
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.log('Error estimate gas newBPool')
|
||||||
|
this.logger.log(e)
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
txid = await factory.methods.newBPool().send({ from: account, gas: estGas + 1 })
|
||||||
// pooladdress = transactiondata.events.BPoolRegistered.returnValues[0]
|
// pooladdress = transactiondata.events.BPoolRegistered.returnValues[0]
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.error(`ERROR: Failed to create new pool: ${e.message}`)
|
this.logger.error(`ERROR: Failed to create new pool: ${e.message}`)
|
||||||
|
@ -3,5 +3,5 @@ import Web3 from 'web3'
|
|||||||
|
|
||||||
export async function getFairGasPrice(web3: Web3): Promise<string> {
|
export async function getFairGasPrice(web3: Web3): Promise<string> {
|
||||||
const x = new BigNumber(await web3.eth.getGasPrice())
|
const x = new BigNumber(await web3.eth.getGasPrice())
|
||||||
return x.multipliedBy(1.25).integerValue(BigNumber.ROUND_DOWN).toString(10)
|
return x.multipliedBy(1.05).integerValue(BigNumber.ROUND_DOWN).toString(10)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user