mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-06-29 00:58:06 +02: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
|
||||
): Promise<string> {
|
||||
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 dtReserve = await this.getDTReserve(poolAddress)
|
||||
const oceanReserve = await this.getOceanReserve(poolAddress)
|
||||
|
||||
const dtAmount = `${
|
||||
(Number(poolShares) / Number(totalPoolTokens)) * Number(dtReserve)
|
||||
}`
|
||||
const oceanAmount = `${
|
||||
(Number(poolShares) / Number(totalPoolTokens)) * Number(oceanReserve)
|
||||
}`
|
||||
|
||||
const dtAmount = new Decimal(poolShares)
|
||||
.div(totalPoolTokens)
|
||||
.mul(dtReserve)
|
||||
.toString()
|
||||
const oceanAmount = new Decimal(poolShares)
|
||||
.div(totalPoolTokens)
|
||||
.mul(oceanReserve)
|
||||
.toString()
|
||||
return { dtAmount, oceanAmount }
|
||||
} catch (e) {
|
||||
this.logger.error(`ERROR: Unable to get token info. ${e.message}`)
|
||||
|
@ -491,11 +491,7 @@ export class OceanPool extends Pool {
|
|||
): Promise<string> {
|
||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||
if (parseFloat(balance) > 0) {
|
||||
const result = new BigNumber(this.web3.utils.toWei(balance))
|
||||
.multipliedBy(POOL_MAX_AMOUNT_IN_LIMIT)
|
||||
.integerValue(BigNumber.ROUND_DOWN)
|
||||
.minus(1)
|
||||
return this.web3.utils.fromWei(result.toString(10))
|
||||
return new Decimal(balance).mul(POOL_MAX_AMOUNT_IN_LIMIT).toString()
|
||||
} else return '0'
|
||||
}
|
||||
|
||||
|
@ -510,11 +506,7 @@ export class OceanPool extends Pool {
|
|||
): Promise<string> {
|
||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||
if (parseFloat(balance) > 0) {
|
||||
const result = new BigNumber(this.web3.utils.toWei(balance))
|
||||
.multipliedBy(POOL_MAX_AMOUNT_OUT_LIMIT)
|
||||
.integerValue(BigNumber.ROUND_DOWN)
|
||||
.minus(1)
|
||||
return this.web3.utils.fromWei(result.toString(10))
|
||||
return new Decimal(balance).mul(POOL_MAX_AMOUNT_OUT_LIMIT).toString()
|
||||
} else return '0'
|
||||
}
|
||||
|
||||
|
@ -559,14 +551,13 @@ export class OceanPool extends Pool {
|
|||
}
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
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')
|
||||
return null
|
||||
}
|
||||
const calcInGivenOut = await this.getOceanNeeded(poolAddress, dtAmountWanted)
|
||||
|
||||
if (parseFloat(calcInGivenOut) > parseFloat(maxOceanAmount)) {
|
||||
if (new Decimal(calcInGivenOut).greaterThan(maxOceanAmount)) {
|
||||
this.logger.error('ERROR: Not enough Ocean Tokens')
|
||||
return null
|
||||
}
|
||||
|
@ -615,15 +606,15 @@ export class OceanPool extends Pool {
|
|||
}
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
if (
|
||||
parseFloat(minimumdtAmountWanted) >
|
||||
parseFloat(await this.getDTMaxBuyQuantity(poolAddress))
|
||||
new Decimal(minimumdtAmountWanted).greaterThan(
|
||||
await this.getDTMaxBuyQuantity(poolAddress)
|
||||
)
|
||||
) {
|
||||
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
||||
return null
|
||||
}
|
||||
const calcInGivenOut = await this.getOceanNeeded(poolAddress, minimumdtAmountWanted)
|
||||
|
||||
if (parseFloat(calcInGivenOut) > parseFloat(OceanAmount)) {
|
||||
if (new Decimal(calcInGivenOut).greaterThan(OceanAmount)) {
|
||||
this.logger.error('ERROR: Not enough Ocean Tokens')
|
||||
return null
|
||||
}
|
||||
|
@ -672,15 +663,15 @@ export class OceanPool extends Pool {
|
|||
}
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
if (
|
||||
parseFloat(oceanAmountWanted) >
|
||||
parseFloat(await this.getOceanMaxBuyQuantity(poolAddress))
|
||||
new Decimal(oceanAmountWanted).greaterThan(
|
||||
await this.getOceanMaxBuyQuantity(poolAddress)
|
||||
)
|
||||
) {
|
||||
this.logger.error('ERROR: Buy quantity exceeds quantity allowed')
|
||||
return null
|
||||
}
|
||||
const calcOutGivenIn = await this.getOceanReceived(poolAddress, dtAmount)
|
||||
|
||||
if (parseFloat(calcOutGivenIn) < parseFloat(oceanAmountWanted)) {
|
||||
if (new Decimal(calcOutGivenIn).lessThan(oceanAmountWanted)) {
|
||||
this.logger.error('ERROR: Not enough datatokens')
|
||||
return null
|
||||
}
|
||||
|
@ -720,7 +711,7 @@ export class OceanPool extends Pool {
|
|||
): Promise<TransactionReceipt> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
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')
|
||||
return null
|
||||
}
|
||||
|
@ -760,23 +751,23 @@ export class OceanPool extends Pool {
|
|||
): Promise<TransactionReceipt> {
|
||||
const dtAddress = await this.getDTAddress(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')
|
||||
return null
|
||||
}
|
||||
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')
|
||||
return null
|
||||
}
|
||||
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')
|
||||
return null
|
||||
}
|
||||
// Balancer bug fix
|
||||
if (parseFloat(maximumPoolShares) < parseFloat(sharesRequired))
|
||||
maximumPoolShares = String(parseFloat(maximumPoolShares) * 0.9999)
|
||||
if (new Decimal(maximumPoolShares).lessThan(sharesRequired))
|
||||
maximumPoolShares = new Decimal(maximumPoolShares).mul(0.9999).toString()
|
||||
// Balance bug fix
|
||||
return this.exitswapExternAmountOut(
|
||||
account,
|
||||
|
@ -804,7 +795,7 @@ export class OceanPool extends Pool {
|
|||
return null
|
||||
}
|
||||
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')
|
||||
return null
|
||||
}
|
||||
|
@ -847,7 +838,7 @@ export class OceanPool extends Pool {
|
|||
return null
|
||||
}
|
||||
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')
|
||||
return null
|
||||
}
|
||||
|
@ -880,12 +871,12 @@ export class OceanPool extends Pool {
|
|||
return null
|
||||
}
|
||||
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')
|
||||
return null
|
||||
}
|
||||
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')
|
||||
return null
|
||||
}
|
||||
|
@ -893,13 +884,13 @@ export class OceanPool extends Pool {
|
|||
poolAddress,
|
||||
amount
|
||||
)
|
||||
if (parseFloat(maximumPoolShares) < parseFloat(sharesRequired)) {
|
||||
if (new Decimal(maximumPoolShares).lessThan(sharesRequired)) {
|
||||
this.logger.error('ERROR: Not enough poolShares')
|
||||
return null
|
||||
}
|
||||
// Balancer bug fix
|
||||
if (parseFloat(maximumPoolShares) < parseFloat(sharesRequired))
|
||||
maximumPoolShares = String(parseFloat(maximumPoolShares) * 0.9999)
|
||||
if (new Decimal(maximumPoolShares).lessThan(sharesRequired))
|
||||
maximumPoolShares = new Decimal(maximumPoolShares).mul(0.9999).toString()
|
||||
// Balance bug fix
|
||||
return super.exitswapExternAmountOut(
|
||||
account,
|
||||
|
@ -927,13 +918,13 @@ export class OceanPool extends Pool {
|
|||
minOcean = '0'
|
||||
): Promise<TransactionReceipt> {
|
||||
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')
|
||||
return null
|
||||
}
|
||||
// Balancer bug fix
|
||||
if (parseFloat(usershares) === parseFloat(poolShares))
|
||||
poolShares = String(parseFloat(poolShares) * 0.9999)
|
||||
if (new Decimal(usershares).equals(poolShares))
|
||||
poolShares = new Decimal(poolShares).mul(0.9999).toString()
|
||||
// Balance bug fix
|
||||
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> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
if (
|
||||
parseFloat(dtRequired) > parseFloat(await this.getDTMaxBuyQuantity(poolAddress))
|
||||
new Decimal(dtRequired).greaterThan(await this.getDTMaxBuyQuantity(poolAddress))
|
||||
) {
|
||||
return '0'
|
||||
}
|
||||
|
@ -1007,8 +998,9 @@ export class OceanPool extends Pool {
|
|||
public async getDTNeeded(poolAddress: string, OceanRequired: string): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
if (
|
||||
parseFloat(OceanRequired) >
|
||||
parseFloat(await this.getOceanMaxBuyQuantity(poolAddress))
|
||||
new Decimal(OceanRequired).greaterThan(
|
||||
await this.getOceanMaxBuyQuantity(poolAddress)
|
||||
)
|
||||
) {
|
||||
return '0'
|
||||
}
|
||||
|
@ -1295,8 +1287,7 @@ export class OceanPool extends Pool {
|
|||
tokenOutWeight,
|
||||
swapfee
|
||||
)
|
||||
const slippage = (parseFloat(newPrice) * 100) / parseFloat(initialPrice) - 100
|
||||
return String(slippage)
|
||||
return new Decimal(newPrice).mul(100).div(initialPrice).minus(100).toString()
|
||||
}
|
||||
|
||||
/* 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} spender
|
||||
* @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(
|
||||
account: string,
|
||||
tokenAddress: string,
|
||||
spender: string,
|
||||
amount: string
|
||||
amount: string,
|
||||
force = false
|
||||
): Promise<TransactionReceipt> {
|
||||
const minABI = [
|
||||
{
|
||||
|
@ -169,6 +171,13 @@ export class Pool extends PoolFactory {
|
|||
const token = new this.web3.eth.Contract(minABI, tokenAddress, {
|
||||
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
|
||||
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||
let estGas
|
||||
|
@ -890,7 +899,7 @@ export class Pool extends PoolFactory {
|
|||
)
|
||||
.send({
|
||||
from: account,
|
||||
gas: this.GASLIMIT_DEFAULT,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3)
|
||||
})
|
||||
} catch (e) {
|
||||
|
|
|
@ -45,10 +45,19 @@ export class PoolFactory {
|
|||
from: account
|
||||
})
|
||||
let txid = null
|
||||
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||
let estGas
|
||||
try {
|
||||
txid = await factory.methods
|
||||
estGas = await factory.methods
|
||||
.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]
|
||||
} catch (e) {
|
||||
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> {
|
||||
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…
Reference in New Issue
Block a user