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

Issue-#1409: Excessive contract calls (#1424)

* add decimals parameter to unitsToAmount() and amountToUnits()

* unify use of amountToUnits() and unitsToAmount()

* use tokenDecimals in TokenUtils

* add tokenDecimals to functions in SideStaking

* add parameters to doc comments

* calculate amountToUnits and unitsToAmount using  decimals in FixedRateExchange

* remove unused amountToUnits() function from SideStaking

* use decimals in unitsToAmount() function in Pool

* add tokenInDecimals and tokenOutDecimals to TokenInOutMarket interface

* use decimals in amountToUnits() function in Pool

* fix errors related to pool decimals

Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro>
This commit is contained in:
Miquel A. Cabot 2022-05-03 18:06:39 +02:00 committed by GitHub
parent 9cb1ea51a8
commit f8a42d9559
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 294 additions and 184 deletions

View File

@ -23,6 +23,8 @@ export interface TokenInOutMarket {
tokenIn: string tokenIn: string
tokenOut: string tokenOut: string
marketFeeAddress: string marketFeeAddress: string
tokenInDecimals?: number
tokenOutDecimals?: number
} }
export interface AmountsInMaxFee { export interface AmountsInMaxFee {

View File

@ -52,6 +52,22 @@ export class Pool {
this.config = config || new ConfigHelper().getConfig(network || 'unknown') this.config = config || new ConfigHelper().getConfig(network || 'unknown')
} }
async amountToUnits(
token: string,
amount: string,
tokenDecimals?: number
): Promise<string> {
return amountToUnits(this.web3, token, amount, tokenDecimals)
}
async unitsToAmount(
token: string,
amount: string,
tokenDecimals?: number
): Promise<string> {
return unitsToAmount(this.web3, token, amount, tokenDecimals)
}
/** /**
* Get user shares of pool tokens * Get user shares of pool tokens
* @param {String} account * @param {String} account
@ -367,9 +383,14 @@ export class Pool {
* Returns the current token reserve amount * Returns the current token reserve amount
* @param {String} poolAddress * @param {String} poolAddress
* @param {String} token Address of the token to be checked * @param {String} token Address of the token to be checked
* @param {number} tokenDecimals optional number of decimals of the token
* @return {String} * @return {String}
*/ */
async getReserve(poolAddress: string, token: string): Promise<string> { async getReserve(
poolAddress: string,
token: string,
tokenDecimals?: number
): Promise<string> {
let amount = null let amount = null
try { try {
const pool = setContractDefaults( const pool = setContractDefaults(
@ -377,7 +398,7 @@ export class Pool {
this.config this.config
) )
const result = await pool.methods.getBalance(token).call() const result = await pool.methods.getBalance(token).call()
amount = await unitsToAmount(this.web3, token, result) amount = await this.unitsToAmount(token, result, tokenDecimals)
} catch (e) { } catch (e) {
LoggerInstance.error(`ERROR: Failed to get how many tokens \ LoggerInstance.error(`ERROR: Failed to get how many tokens \
are in the pool: ${e.message}`) are in the pool: ${e.message}`)
@ -503,9 +524,14 @@ export class Pool {
* Get Market Fees available to be collected for a specific token * Get Market Fees available to be collected for a specific token
* @param {String} poolAddress * @param {String} poolAddress
* @param {String} token token we want to check fees * @param {String} token token we want to check fees
* @param {number} tokenDecimals optional number of decimals of the token
* @return {String} * @return {String}
*/ */
async getMarketFees(poolAddress: string, token: string): Promise<string> { async getMarketFees(
poolAddress: string,
token: string,
tokenDecimals?: number
): Promise<string> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
this.config this.config
@ -513,7 +539,7 @@ export class Pool {
let weight = null let weight = null
try { try {
const result = await pool.methods.publishMarketFees(token).call() const result = await pool.methods.publishMarketFees(token).call()
weight = await unitsToAmount(this.web3, token, result) weight = await this.unitsToAmount(token, result, tokenDecimals)
} catch (e) { } catch (e) {
LoggerInstance.error(`ERROR: Failed to get market fees for a token: ${e.message}`) LoggerInstance.error(`ERROR: Failed to get market fees for a token: ${e.message}`)
} }
@ -562,9 +588,14 @@ export class Pool {
* Get Community Fees available to be collected for a specific token * Get Community Fees available to be collected for a specific token
* @param {String} poolAddress * @param {String} poolAddress
* @param {String} token token we want to check fees * @param {String} token token we want to check fees
* @param {number} tokenDecimals optional number of decimals of the token
* @return {String} * @return {String}
*/ */
async getCommunityFees(poolAddress: string, token: string): Promise<string> { async getCommunityFees(
poolAddress: string,
token: string,
tokenDecimals?: number
): Promise<string> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
this.config this.config
@ -572,7 +603,7 @@ export class Pool {
let weight = null let weight = null
try { try {
const result = await pool.methods.communityFees(token).call() const result = await pool.methods.communityFees(token).call()
weight = await unitsToAmount(this.web3, token, result) weight = await this.unitsToAmount(token, result, tokenDecimals)
} catch (e) { } catch (e) {
LoggerInstance.error( LoggerInstance.error(
`ERROR: Failed to get community fees for a token: ${e.message}` `ERROR: Failed to get community fees for a token: ${e.message}`
@ -807,21 +838,20 @@ export class Pool {
this.config this.config
) )
const tokenAmountIn = await amountToUnits( const tokenAmountIn = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenIn, tokenInOutMarket.tokenIn,
amountsInOutMaxFee.tokenAmountIn amountsInOutMaxFee.tokenAmountIn,
tokenInOutMarket.tokenInDecimals
) )
const minAmountOut = await amountToUnits( const minAmountOut = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenOut, tokenInOutMarket.tokenOut,
amountsInOutMaxFee.minAmountOut amountsInOutMaxFee.minAmountOut,
tokenInOutMarket.tokenOutDecimals
) )
const maxPrice = amountsInOutMaxFee.maxPrice const maxPrice = amountsInOutMaxFee.maxPrice
? amountToUnits( ? this.amountToUnits(
this.web3,
await this.getBaseToken(poolAddress), await this.getBaseToken(poolAddress),
amountsInOutMaxFee.maxPrice amountsInOutMaxFee.maxPrice
) )
@ -887,23 +917,22 @@ export class Pool {
amountsInOutMaxFee amountsInOutMaxFee
) )
const tokenAmountIn = await amountToUnits( const tokenAmountIn = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenIn, tokenInOutMarket.tokenIn,
amountsInOutMaxFee.tokenAmountIn amountsInOutMaxFee.tokenAmountIn,
tokenInOutMarket.tokenInDecimals
) )
const minAmountOut = await amountToUnits( const minAmountOut = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenOut, tokenInOutMarket.tokenOut,
amountsInOutMaxFee.minAmountOut amountsInOutMaxFee.minAmountOut,
tokenInOutMarket.tokenOutDecimals
) )
let result = null let result = null
const maxPrice = amountsInOutMaxFee.maxPrice const maxPrice = amountsInOutMaxFee.maxPrice
? await amountToUnits( ? await this.amountToUnits(
this.web3,
await this.getBaseToken(poolAddress), await this.getBaseToken(poolAddress),
amountsInOutMaxFee.maxPrice amountsInOutMaxFee.maxPrice
) )
@ -961,21 +990,20 @@ export class Pool {
const gasLimitDefault = this.GASLIMIT_DEFAULT const gasLimitDefault = this.GASLIMIT_DEFAULT
const maxAmountIn = await amountToUnits( const maxAmountIn = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenIn, tokenInOutMarket.tokenIn,
amountsInOutMaxFee.maxAmountIn amountsInOutMaxFee.maxAmountIn,
tokenInOutMarket.tokenInDecimals
) )
const tokenAmountOut = await amountToUnits( const tokenAmountOut = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenOut, tokenInOutMarket.tokenOut,
amountsInOutMaxFee.tokenAmountOut amountsInOutMaxFee.tokenAmountOut,
tokenInOutMarket.tokenOutDecimals
) )
const maxPrice = amountsInOutMaxFee.maxPrice const maxPrice = amountsInOutMaxFee.maxPrice
? await amountToUnits( ? await this.amountToUnits(
this.web3,
await this.getBaseToken(poolAddress), await this.getBaseToken(poolAddress),
amountsInOutMaxFee.maxPrice amountsInOutMaxFee.maxPrice
) )
@ -1036,21 +1064,20 @@ export class Pool {
amountsInOutMaxFee amountsInOutMaxFee
) )
const maxAmountIn = await amountToUnits( const maxAmountIn = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenIn, tokenInOutMarket.tokenIn,
amountsInOutMaxFee.maxAmountIn amountsInOutMaxFee.maxAmountIn,
tokenInOutMarket.tokenInDecimals
) )
const tokenAmountOut = await amountToUnits( const tokenAmountOut = await this.amountToUnits(
this.web3,
tokenInOutMarket.tokenOut, tokenInOutMarket.tokenOut,
amountsInOutMaxFee.tokenAmountOut amountsInOutMaxFee.tokenAmountOut,
tokenInOutMarket.tokenOutDecimals
) )
const maxPrice = amountsInOutMaxFee.maxPrice const maxPrice = amountsInOutMaxFee.maxPrice
? amountToUnits( ? this.amountToUnits(
this.web3,
await this.getBaseToken(poolAddress), await this.getBaseToken(poolAddress),
amountsInOutMaxFee.maxPrice amountsInOutMaxFee.maxPrice
) )
@ -1145,7 +1172,7 @@ export class Pool {
throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`) throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`)
} }
const amountInFormatted = await amountToUnits(this.web3, tokenIn, tokenAmountIn) const amountInFormatted = await this.amountToUnits(tokenIn, tokenAmountIn)
const estGas = await this.estJoinswapExternAmountIn( const estGas = await this.estJoinswapExternAmountIn(
account, account,
poolAddress, poolAddress,
@ -1240,8 +1267,7 @@ export class Pool {
throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`) throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`)
} }
const minTokenOutFormatted = await amountToUnits( const minTokenOutFormatted = await this.amountToUnits(
this.web3,
await this.getBaseToken(poolAddress), await this.getBaseToken(poolAddress),
minTokenAmountOut minTokenAmountOut
) )
@ -1340,13 +1366,17 @@ export class Pool {
* @param tokenOut token to get * @param tokenOut token to get
* @param tokenAmountOut exact amount of tokenOut * @param tokenAmountOut exact amount of tokenOut
* @param swapMarketFee consume market swap fee * @param swapMarketFee consume market swap fee
* @param {number} tokenInDecimals optional number of decimals of the token to be swaped
* @param {number} tokenOutDecimals optional number of decimals of the token to get
*/ */
public async getAmountInExactOut( public async getAmountInExactOut(
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
tokenOut: string, tokenOut: string,
tokenAmountOut: string, tokenAmountOut: string,
swapMarketFee: string swapMarketFee: string,
tokenInDecimals?: number,
tokenOutDecimals?: number
): Promise<PoolPriceAndFees> { ): Promise<PoolPriceAndFees> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
@ -1359,7 +1389,11 @@ export class Pool {
throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`) throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`)
} }
const amountOutFormatted = await amountToUnits(this.web3, tokenOut, tokenAmountOut) const amountOutFormatted = await this.amountToUnits(
tokenOut,
tokenAmountOut,
tokenOutDecimals
)
let amount = null let amount = null
@ -1373,22 +1407,30 @@ export class Pool {
) )
.call() .call()
amount = { amount = {
tokenAmount: await unitsToAmount(this.web3, tokenOut, result.tokenAmountIn), tokenAmount: await this.unitsToAmount(
liquidityProviderSwapFeeAmount: await unitsToAmount( tokenOut,
this.web3, result.tokenAmountIn,
tokenIn, tokenOutDecimals
result.lpFeeAmount
), ),
oceanFeeAmount: await unitsToAmount(this.web3, tokenIn, result.oceanFeeAmount), liquidityProviderSwapFeeAmount: await this.unitsToAmount(
publishMarketSwapFeeAmount: await unitsToAmount(
this.web3,
tokenIn, tokenIn,
result.publishMarketSwapFeeAmount result.lpFeeAmount,
tokenInDecimals
), ),
consumeMarketSwapFeeAmount: await unitsToAmount( oceanFeeAmount: await this.unitsToAmount(
this.web3,
tokenIn, tokenIn,
result.consumeMarketSwapFeeAmount result.oceanFeeAmount,
tokenInDecimals
),
publishMarketSwapFeeAmount: await this.unitsToAmount(
tokenIn,
result.publishMarketSwapFeeAmount,
tokenInDecimals
),
consumeMarketSwapFeeAmount: await this.unitsToAmount(
tokenIn,
result.consumeMarketSwapFeeAmount,
tokenInDecimals
) )
} }
} catch (e) { } catch (e) {
@ -1402,15 +1444,19 @@ export class Pool {
* Returns: tokenAmountOut, LPFee, opcFee , publishMarketSwapFee, consumeMarketSwapFee * Returns: tokenAmountOut, LPFee, opcFee , publishMarketSwapFee, consumeMarketSwapFee
* @param tokenIn token to be swaped * @param tokenIn token to be swaped
* @param tokenOut token to get * @param tokenOut token to get
* @param tokenAmountOut exact amount of tokenOut * @param tokenAmountIn exact amount of tokenIn
* @param _consumeMarketSwapFee consume market swap fee * @param swapMarketFee
* @param {number} tokenInDecimals optional number of decimals of the token to be swaped
* @param {number} tokenOutDecimals optional number of decimals of the token to get
*/ */
public async getAmountOutExactIn( public async getAmountOutExactIn(
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
tokenOut: string, tokenOut: string,
tokenAmountIn: string, tokenAmountIn: string,
swapMarketFee: string swapMarketFee: string,
tokenInDecimals?: number,
tokenOutDecimals?: number
): Promise<PoolPriceAndFees> { ): Promise<PoolPriceAndFees> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
@ -1422,7 +1468,11 @@ export class Pool {
throw new Error(`tokenAmountIn is greater than ${maxSwap.toString()}`) throw new Error(`tokenAmountIn is greater than ${maxSwap.toString()}`)
} }
const amountInFormatted = await amountToUnits(this.web3, tokenIn, tokenAmountIn) const amountInFormatted = await this.amountToUnits(
tokenIn,
tokenAmountIn,
tokenInDecimals
)
let amount = null let amount = null
@ -1437,22 +1487,30 @@ export class Pool {
.call() .call()
amount = { amount = {
tokenAmount: await unitsToAmount(this.web3, tokenOut, result.tokenAmountOut), tokenAmount: await this.unitsToAmount(
liquidityProviderSwapFeeAmount: await unitsToAmount( tokenOut,
this.web3, result.tokenAmountOut,
tokenIn, tokenOutDecimals
result.lpFeeAmount
), ),
oceanFeeAmount: await unitsToAmount(this.web3, tokenIn, result.oceanFeeAmount), liquidityProviderSwapFeeAmount: await this.unitsToAmount(
publishMarketSwapFeeAmount: await unitsToAmount(
this.web3,
tokenIn, tokenIn,
result.publishMarketSwapFeeAmount result.lpFeeAmount,
tokenInDecimals
), ),
consumeMarketSwapFeeAmount: await unitsToAmount( oceanFeeAmount: await this.unitsToAmount(
this.web3,
tokenIn, tokenIn,
result.consumeMarketSwapFeeAmount result.oceanFeeAmount,
tokenInDecimals
),
publishMarketSwapFeeAmount: await this.unitsToAmount(
tokenIn,
result.publishMarketSwapFeeAmount,
tokenInDecimals
),
consumeMarketSwapFeeAmount: await this.unitsToAmount(
tokenIn,
result.consumeMarketSwapFeeAmount,
tokenInDecimals
) )
} }
} catch (e) { } catch (e) {
@ -1465,11 +1523,15 @@ export class Pool {
* Returns number of poolshares obtain by staking exact tokenAmountIn tokens * Returns number of poolshares obtain by staking exact tokenAmountIn tokens
* @param tokenIn tokenIn * @param tokenIn tokenIn
* @param tokenAmountIn exact number of tokens staked * @param tokenAmountIn exact number of tokens staked
* @param {number} poolDecimals optional number of decimals of the poool
* @param {number} tokenInDecimals optional number of decimals of the token
*/ */
public async calcPoolOutGivenSingleIn( public async calcPoolOutGivenSingleIn(
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
tokenAmountIn: string tokenAmountIn: string,
poolDecimals?: number,
tokenInDecimals?: number
): Promise<string> { ): Promise<string> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
@ -1481,11 +1543,11 @@ export class Pool {
const result = await pool.methods const result = await pool.methods
.calcPoolOutSingleIn( .calcPoolOutSingleIn(
tokenIn, tokenIn,
await amountToUnits(this.web3, tokenIn, tokenAmountIn) await this.amountToUnits(tokenIn, tokenAmountIn, tokenInDecimals)
) )
.call() .call()
amount = await unitsToAmount(this.web3, poolAddress, result) amount = await this.unitsToAmount(poolAddress, result, poolDecimals)
} catch (e) { } catch (e) {
LoggerInstance.error( LoggerInstance.error(
`ERROR: Failed to calculate PoolOutGivenSingleIn : ${e.message}` `ERROR: Failed to calculate PoolOutGivenSingleIn : ${e.message}`
@ -1498,25 +1560,32 @@ export class Pool {
* Returns number of tokens to be staked to the pool in order to get an exact number of poolshares * Returns number of tokens to be staked to the pool in order to get an exact number of poolshares
* @param tokenIn tokenIn * @param tokenIn tokenIn
* @param poolAmountOut expected amount of pool shares * @param poolAmountOut expected amount of pool shares
* @param {number} poolDecimals optional number of decimals of the pool
* @param {number} tokenInDecimals optional number of decimals of the token
*/ */
public async calcSingleInGivenPoolOut( public async calcSingleInGivenPoolOut(
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
poolAmountOut: string poolAmountOut: string,
poolDecimals?: number,
tokenInDecimals?: number
): Promise<string> { ): Promise<string> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
this.config this.config
) )
let amount = null let amount = null
const amountFormatted = await amountToUnits(this.web3, poolAddress, poolAmountOut) const amountFormatted = await this.amountToUnits(
poolAddress,
poolAmountOut,
poolDecimals
)
try { try {
const result = await pool.methods const result = await pool.methods
.calcSingleInPoolOut(tokenIn, amountFormatted) .calcSingleInPoolOut(tokenIn, amountFormatted)
.call() .call()
amount = await unitsToAmount(this.web3, tokenIn, result) amount = await this.unitsToAmount(tokenIn, result, tokenInDecimals)
} catch (e) { } catch (e) {
LoggerInstance.error( LoggerInstance.error(
`ERROR: Failed to calculate SingleInGivenPoolOut : ${e.message}` `ERROR: Failed to calculate SingleInGivenPoolOut : ${e.message}`
@ -1529,11 +1598,15 @@ export class Pool {
* Returns expected amount of tokenOut for removing exact poolAmountIn pool shares from the pool * Returns expected amount of tokenOut for removing exact poolAmountIn pool shares from the pool
* @param tokenOut tokenOut * @param tokenOut tokenOut
* @param poolAmountIn amount of shares spent * @param poolAmountIn amount of shares spent
* @param {number} poolDecimals optional number of decimals of the pool
* @param {number} tokenOutDecimals optional number of decimals of the token
*/ */
public async calcSingleOutGivenPoolIn( public async calcSingleOutGivenPoolIn(
poolAddress: string, poolAddress: string,
tokenOut: string, tokenOut: string,
poolAmountIn: string poolAmountIn: string,
poolDecimals?: number,
tokenOutDecimals?: number
): Promise<string> { ): Promise<string> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
@ -1545,10 +1618,10 @@ export class Pool {
const result = await pool.methods const result = await pool.methods
.calcSingleOutPoolIn( .calcSingleOutPoolIn(
tokenOut, tokenOut,
await amountToUnits(this.web3, poolAddress, poolAmountIn) await this.amountToUnits(poolAddress, poolAmountIn, poolDecimals)
) )
.call() .call()
amount = await unitsToAmount(this.web3, tokenOut, result) amount = await this.unitsToAmount(tokenOut, result, tokenOutDecimals)
} catch (e) { } catch (e) {
LoggerInstance.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e}`) LoggerInstance.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e}`)
} }
@ -1559,11 +1632,15 @@ export class Pool {
* Returns number of poolshares needed to withdraw exact tokenAmountOut tokens * Returns number of poolshares needed to withdraw exact tokenAmountOut tokens
* @param tokenOut tokenOut * @param tokenOut tokenOut
* @param tokenAmountOut expected amount of tokensOut * @param tokenAmountOut expected amount of tokensOut
* @param {number} poolDecimals optional number of decimals of the pool
* @param {number} tokenOutDecimals optional number of decimals of the token
*/ */
public async calcPoolInGivenSingleOut( public async calcPoolInGivenSingleOut(
poolAddress: string, poolAddress: string,
tokenOut: string, tokenOut: string,
tokenAmountOut: string tokenAmountOut: string,
poolDecimals?: number,
tokenOutDecimals?: number
): Promise<string> { ): Promise<string> {
const pool = setContractDefaults( const pool = setContractDefaults(
new this.web3.eth.Contract(this.poolAbi, poolAddress), new this.web3.eth.Contract(this.poolAbi, poolAddress),
@ -1575,11 +1652,11 @@ export class Pool {
const result = await pool.methods const result = await pool.methods
.calcPoolInSingleOut( .calcPoolInSingleOut(
tokenOut, tokenOut,
await amountToUnits(this.web3, tokenOut, tokenAmountOut) await this.amountToUnits(tokenOut, tokenAmountOut, tokenOutDecimals)
) )
.call() .call()
amount = await unitsToAmount(this.web3, poolAddress, result) amount = await this.unitsToAmount(poolAddress, result, poolDecimals)
} catch (e) { } catch (e) {
LoggerInstance.error( LoggerInstance.error(
`ERROR: Failed to calculate PoolInGivenSingleOut : ${e.message}` `ERROR: Failed to calculate PoolInGivenSingleOut : ${e.message}`

View File

@ -92,12 +92,20 @@ export class FixedRateExchange {
) )
} }
async amountToUnits(token: string, amount: string): Promise<string> { async amountToUnits(
return amountToUnits(this.web3, token, amount) token: string,
amount: string,
tokenDecimals: number
): Promise<string> {
return amountToUnits(this.web3, token, amount, tokenDecimals)
} }
async unitsToAmount(token: string, amount: string): Promise<string> { async unitsToAmount(
return unitsToAmount(this.web3, token, amount) token: string,
amount: string,
tokenDecimals: number
): Promise<string> {
return unitsToAmount(this.web3, token, amount, tokenDecimals)
} }
/** /**
@ -173,11 +181,13 @@ export class FixedRateExchange {
const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee) const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)
const dtAmountFormatted = await this.amountToUnits( const dtAmountFormatted = await this.amountToUnits(
exchange.datatoken, exchange.datatoken,
datatokenAmount datatokenAmount,
+exchange.dtDecimals
) )
const maxBtFormatted = await this.amountToUnits( const maxBtFormatted = await this.amountToUnits(
exchange.baseToken, exchange.baseToken,
maxBaseTokenAmount maxBaseTokenAmount,
+exchange.btDecimals
) )
const estGas = await this.estBuyDT( const estGas = await this.estBuyDT(
@ -269,11 +279,13 @@ export class FixedRateExchange {
const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee) const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)
const dtAmountFormatted = await this.amountToUnits( const dtAmountFormatted = await this.amountToUnits(
exchange.datatoken, exchange.datatoken,
datatokenAmount datatokenAmount,
+exchange.dtDecimals
) )
const minBtFormatted = await this.amountToUnits( const minBtFormatted = await this.amountToUnits(
exchange.baseToken, exchange.baseToken,
minBaseTokenAmount minBaseTokenAmount,
+exchange.btDecimals
) )
const estGas = await this.estBuyDT( const estGas = await this.estBuyDT(
address, address,
@ -531,12 +543,8 @@ export class FixedRateExchange {
*/ */
public async getDTSupply(exchangeId: string): Promise<string> { public async getDTSupply(exchangeId: string): Promise<string> {
const dtSupply = await this.contract.methods.getDTSupply(exchangeId).call() const dtSupply = await this.contract.methods.getDTSupply(exchangeId).call()
return await this.unitsToAmount( const exchange = await this.getExchange(exchangeId)
( return await this.unitsToAmount(exchange.datatoken, dtSupply, +exchange.dtDecimals)
await this.getExchange(exchangeId)
).datatoken,
dtSupply
)
} }
/** /**
@ -546,12 +554,8 @@ export class FixedRateExchange {
*/ */
public async getBTSupply(exchangeId: string): Promise<string> { public async getBTSupply(exchangeId: string): Promise<string> {
const btSupply = await this.contract.methods.getBTSupply(exchangeId).call() const btSupply = await this.contract.methods.getBTSupply(exchangeId).call()
return await this.unitsToAmount( const exchange = await this.getExchange(exchangeId)
( return await this.unitsToAmount(exchange.baseToken, btSupply, +exchange.btDecimals)
await this.getExchange(exchangeId)
).baseToken,
btSupply
)
} }
/** /**
@ -579,7 +583,11 @@ export class FixedRateExchange {
const result = await this.contract.methods const result = await this.contract.methods
.calcBaseInGivenOutDT( .calcBaseInGivenOutDT(
exchangeId, exchangeId,
await this.amountToUnits(fixedRateExchange.datatoken, datatokenAmount), await this.amountToUnits(
fixedRateExchange.datatoken,
datatokenAmount,
+fixedRateExchange.dtDecimals
),
this.web3.utils.toWei(consumeMarketFee) this.web3.utils.toWei(consumeMarketFee)
) )
.call() .call()
@ -587,19 +595,23 @@ export class FixedRateExchange {
const priceAndFees = { const priceAndFees = {
baseTokenAmount: await this.unitsToAmount( baseTokenAmount: await this.unitsToAmount(
fixedRateExchange.baseToken, fixedRateExchange.baseToken,
result.baseTokenAmount result.baseTokenAmount,
+fixedRateExchange.btDecimals
), ),
marketFeeAmount: await this.unitsToAmount( marketFeeAmount: await this.unitsToAmount(
fixedRateExchange.baseToken, fixedRateExchange.baseToken,
result.marketFeeAmount result.marketFeeAmount,
+fixedRateExchange.btDecimals
), ),
oceanFeeAmount: await this.unitsToAmount( oceanFeeAmount: await this.unitsToAmount(
fixedRateExchange.baseToken, fixedRateExchange.baseToken,
result.oceanFeeAmount result.oceanFeeAmount,
+fixedRateExchange.btDecimals
), ),
consumeMarketFeeAmount: await this.unitsToAmount( consumeMarketFeeAmount: await this.unitsToAmount(
fixedRateExchange.baseToken, fixedRateExchange.baseToken,
result.consumeMarketFeeAmount result.consumeMarketFeeAmount,
+fixedRateExchange.btDecimals
) )
} as PriceAndFees } as PriceAndFees
return priceAndFees return priceAndFees
@ -621,17 +633,16 @@ export class FixedRateExchange {
const result = await this.contract.methods const result = await this.contract.methods
.calcBaseOutGivenInDT( .calcBaseOutGivenInDT(
exchangeId, exchangeId,
await this.amountToUnits(exchange.datatoken, datatokenAmount), await this.amountToUnits(
exchange.datatoken,
datatokenAmount,
+exchange.dtDecimals
),
this.web3.utils.toWei(consumeMarketFee) this.web3.utils.toWei(consumeMarketFee)
) )
.call() .call()
return await this.unitsToAmount( return await this.unitsToAmount(exchange.baseToken, result[0], +exchange.btDecimals)
(
await this.getExchange(exchangeId)
).baseToken,
result[0]
)
} }
/** /**
@ -645,10 +656,26 @@ export class FixedRateExchange {
.call() .call()
result.dtDecimals = result.dtDecimals.toString() result.dtDecimals = result.dtDecimals.toString()
result.btDecimals = result.btDecimals.toString() result.btDecimals = result.btDecimals.toString()
result.dtBalance = await this.unitsToAmount(result.datatoken, result.dtBalance) result.dtBalance = await this.unitsToAmount(
result.btBalance = await this.unitsToAmount(result.baseToken, result.btBalance) result.datatoken,
result.dtSupply = await this.unitsToAmount(result.datatoken, result.dtSupply) result.dtBalance,
result.btSupply = await this.unitsToAmount(result.baseToken, result.btSupply) +result.dtDecimals
)
result.btBalance = await this.unitsToAmount(
result.baseToken,
result.btBalance,
+result.btDecimals
)
result.dtSupply = await this.unitsToAmount(
result.datatoken,
result.dtSupply,
+result.dtDecimals
)
result.btSupply = await this.unitsToAmount(
result.baseToken,
result.btSupply,
+result.btDecimals
)
result.fixedRate = this.web3.utils.fromWei(result.fixedRate) result.fixedRate = this.web3.utils.fromWei(result.fixedRate)
result.exchangeId = exchangeId result.exchangeId = exchangeId
return result return result
@ -664,17 +691,16 @@ export class FixedRateExchange {
result.opcFee = this.web3.utils.fromWei(result.opcFee.toString()) result.opcFee = this.web3.utils.fromWei(result.opcFee.toString())
result.marketFee = this.web3.utils.fromWei(result.marketFee.toString()) result.marketFee = this.web3.utils.fromWei(result.marketFee.toString())
const exchange = await this.getExchange(exchangeId)
result.marketFeeAvailable = await this.unitsToAmount( result.marketFeeAvailable = await this.unitsToAmount(
( exchange.baseToken,
await this.getExchange(exchangeId) result.marketFeeAvailable,
).baseToken, +exchange.btDecimals
result.marketFeeAvailable
) )
result.oceanFeeAvailable = await this.unitsToAmount( result.oceanFeeAvailable = await this.unitsToAmount(
( exchange.baseToken,
await this.getExchange(exchangeId) result.oceanFeeAvailable,
).baseToken, +exchange.btDecimals
result.oceanFeeAvailable
) )
result.exchangeId = exchangeId result.exchangeId = exchangeId
@ -822,7 +848,11 @@ export class FixedRateExchange {
const fixedrate: FixedPriceExchange = await this.contract.methods const fixedrate: FixedPriceExchange = await this.contract.methods
.getExchange(exchangeId) .getExchange(exchangeId)
.call() .call()
const amountWei = await this.amountToUnits(fixedrate.baseToken, amount) const amountWei = await this.amountToUnits(
fixedrate.baseToken,
amount,
+fixedrate.btDecimals
)
try { try {
estGas = await fixedRate.methods estGas = await fixedRate.methods
.collectBT(exchangeId, amountWei) .collectBT(exchangeId, amountWei)
@ -852,7 +882,11 @@ export class FixedRateExchange {
const fixedrate: FixedPriceExchange = await this.contract.methods const fixedrate: FixedPriceExchange = await this.contract.methods
.getExchange(exchangeId) .getExchange(exchangeId)
.call() .call()
const amountWei = await this.amountToUnits(fixedrate.baseToken, amount) const amountWei = await this.amountToUnits(
fixedrate.baseToken,
amount,
+fixedrate.btDecimals
)
const trxReceipt = await this.contract.methods.collectBT(exchangeId, amountWei).send({ const trxReceipt = await this.contract.methods.collectBT(exchangeId, amountWei).send({
from: address, from: address,
gas: estGas + 1, gas: estGas + 1,
@ -881,7 +915,11 @@ export class FixedRateExchange {
const fixedrate: FixedPriceExchange = await this.contract.methods const fixedrate: FixedPriceExchange = await this.contract.methods
.getExchange(exchangeId) .getExchange(exchangeId)
.call() .call()
const amountWei = await this.amountToUnits(fixedrate.datatoken, amount) const amountWei = await this.amountToUnits(
fixedrate.datatoken,
amount,
+fixedrate.dtDecimals
)
try { try {
estGas = await fixedRate.methods estGas = await fixedRate.methods
.collectDT(exchangeId, amountWei) .collectDT(exchangeId, amountWei)
@ -911,7 +949,11 @@ export class FixedRateExchange {
const fixedrate: FixedPriceExchange = await this.contract.methods const fixedrate: FixedPriceExchange = await this.contract.methods
.getExchange(exchangeId) .getExchange(exchangeId)
.call() .call()
const amountWei = await this.amountToUnits(fixedrate.datatoken, amount) const amountWei = await this.amountToUnits(
fixedrate.datatoken,
amount,
+fixedrate.dtDecimals
)
const trxReceipt = await this.contract.methods.collectDT(exchangeId, amountWei).send({ const trxReceipt = await this.contract.methods.collectDT(exchangeId, amountWei).send({
from: address, from: address,
gas: estGas + 1, gas: estGas + 1,

View File

@ -2,10 +2,8 @@ import Web3 from 'web3'
import { AbiItem } from 'web3-utils/types' import { AbiItem } from 'web3-utils/types'
import { TransactionReceipt } from 'web3-core' import { TransactionReceipt } from 'web3-core'
import { Contract } from 'web3-eth-contract' import { Contract } from 'web3-eth-contract'
import { LoggerInstance, getFairGasPrice, ConfigHelper } from '../../utils' import { LoggerInstance, getFairGasPrice, ConfigHelper, unitsToAmount } from '../../utils'
import BigNumber from 'bignumber.js'
import SideStakingTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json' import SideStakingTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
import defaultErc20Abi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
import { Config } from '../../models' import { Config } from '../../models'
export class SideStaking { export class SideStaking {
@ -26,38 +24,12 @@ export class SideStaking {
this.config = config || new ConfigHelper().getConfig(network || 'unknown') this.config = config || new ConfigHelper().getConfig(network || 'unknown')
} }
async amountToUnits(token: string, amount: string): Promise<string> { async unitsToAmount(
let decimals = 18 token: string,
const tokenContract = new this.web3.eth.Contract( amount: string,
defaultErc20Abi.abi as AbiItem[], tokenDecimals?: number
token ): Promise<string> {
) return unitsToAmount(this.web3, token, amount, tokenDecimals)
try {
decimals = await tokenContract.methods.decimals().call()
} catch (e) {
LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')
}
const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)
return amountFormatted.toString()
}
async unitsToAmount(token: string, amount: string): Promise<string> {
let decimals = 18
const tokenContract = new this.web3.eth.Contract(
defaultErc20Abi.abi as AbiItem[],
token
)
try {
decimals = await tokenContract.methods.decimals().call()
} catch (e) {
LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')
}
const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)
return amountFormatted.toString()
} }
/** /**
@ -183,11 +155,13 @@ export class SideStaking {
* Get dt balance in the staking contract available for being added as liquidity * Get dt balance in the staking contract available for being added as liquidity
* @param {String} ssAddress side staking contract address * @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress * @param {String} datatokenAddress datatokenAddress
* @param {number} tokenDecimals optional number of decimals of the token
* @return {String} * @return {String}
*/ */
async getDatatokenBalance( async getDatatokenBalance(
ssAddress: string, ssAddress: string,
datatokenAddress: string datatokenAddress: string,
tokenDecimals?: number
): Promise<string> { ): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress) const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
let result = null let result = null
@ -196,7 +170,7 @@ export class SideStaking {
} catch (e) { } catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`) LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
} }
result = await this.unitsToAmount(datatokenAddress, result) result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)
return result return result
} }
@ -221,9 +195,14 @@ export class SideStaking {
* Get total amount vesting * Get total amount vesting
* @param {String} ssAddress side staking contract address * @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress * @param {String} datatokenAddress datatokenAddress
* @param {number} tokenDecimals optional number of decimals of the token
* @return {String} * @return {String}
*/ */
async getvestingAmount(ssAddress: string, datatokenAddress: string): Promise<string> { async getvestingAmount(
ssAddress: string,
datatokenAddress: string,
tokenDecimals?: number
): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress) const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
let result = null let result = null
try { try {
@ -231,7 +210,7 @@ export class SideStaking {
} catch (e) { } catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`) LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
} }
result = await this.unitsToAmount(datatokenAddress, result) result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)
return result return result
} }
@ -259,11 +238,13 @@ export class SideStaking {
* Get how much has been taken from the vesting amount * Get how much has been taken from the vesting amount
* @param {String} ssAddress side staking contract address * @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress * @param {String} datatokenAddress datatokenAddress
* @param {number} tokenDecimals optional number of decimals of the token
* @return {String} * @return {String}
*/ */
async getvestingAmountSoFar( async getvestingAmountSoFar(
ssAddress: string, ssAddress: string,
datatokenAddress: string datatokenAddress: string,
tokenDecimals?: number
): Promise<string> { ): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress) const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
let result = null let result = null
@ -272,7 +253,7 @@ export class SideStaking {
} catch (e) { } catch (e) {
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`) LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
} }
result = await this.unitsToAmount(datatokenAddress, result) result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)
return result return result
} }

View File

@ -120,11 +120,12 @@ export async function getPoolCreationParams(
export async function unitsToAmount( export async function unitsToAmount(
web3: Web3, web3: Web3,
token: string, token: string,
amount: string amount: string,
tokenDecimals?: number
): Promise<string> { ): Promise<string> {
try { try {
const tokenContract = new web3.eth.Contract(minAbi, token) const tokenContract = new web3.eth.Contract(minAbi, token)
let decimals = await tokenContract.methods.decimals().call() let decimals = tokenDecimals || (await tokenContract.methods.decimals().call())
if (decimals === '0') { if (decimals === '0') {
decimals = 18 decimals = 18
} }
@ -143,11 +144,12 @@ export async function unitsToAmount(
export async function amountToUnits( export async function amountToUnits(
web3: Web3, web3: Web3,
token: string, token: string,
amount: string amount: string,
tokenDecimals?: number
): Promise<string> { ): Promise<string> {
try { try {
const tokenContract = new web3.eth.Contract(minAbi, token) const tokenContract = new web3.eth.Contract(minAbi, token)
let decimals = await tokenContract.methods.decimals().call() let decimals = tokenDecimals || (await tokenContract.methods.decimals().call())
if (decimals === '0') { if (decimals === '0') {
decimals = 18 decimals = 18
} }

View File

@ -46,7 +46,8 @@ export async function estApprove(
* @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 * @param {boolean} 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
* @param {number} tokenDecimals optional number of decimals of the token
*/ */
export async function approve( export async function approve(
web3: Web3, web3: Web3,
@ -54,7 +55,8 @@ export async function approve(
tokenAddress: string, tokenAddress: string,
spender: string, spender: string,
amount: string, amount: string,
force = false force = false,
tokenDecimals?: number
): Promise<TransactionReceipt | string> { ): Promise<TransactionReceipt | string> {
const tokenContract = new web3.eth.Contract(minAbi, tokenAddress) const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)
if (!force) { if (!force) {
@ -64,7 +66,7 @@ export async function approve(
} }
} }
let result = null let result = null
const amountFormatted = await amountToUnits(web3, tokenAddress, amount) const amountFormatted = await amountToUnits(web3, tokenAddress, amount, tokenDecimals)
const estGas = await estApprove( const estGas = await estApprove(
web3, web3,
account, account,
@ -94,17 +96,19 @@ export async function approve(
* @param {String } tokenAdress * @param {String } tokenAdress
* @param {String} account * @param {String} account
* @param {String} spender * @param {String} spender
* @param {number} tokenDecimals optional number of decimals of the token
*/ */
export async function allowance( export async function allowance(
web3: Web3, web3: Web3,
tokenAddress: string, tokenAddress: string,
account: string, account: string,
spender: string spender: string,
tokenDecimals?: number
): Promise<string> { ): Promise<string> {
const tokenContract = new web3.eth.Contract(minAbi, tokenAddress) const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)
const trxReceipt = await tokenContract.methods.allowance(account, spender).call() const trxReceipt = await tokenContract.methods.allowance(account, spender).call()
return await unitsToAmount(web3, tokenAddress, trxReceipt) return await unitsToAmount(web3, tokenAddress, trxReceipt, tokenDecimals)
} }
/** /**
@ -113,14 +117,16 @@ export async function allowance(
* @param {String} tokenAdress * @param {String} tokenAdress
* @param {String} owner * @param {String} owner
* @param {String} spender * @param {String} spender
* @param {number} tokenDecimals optional number of decimals of the token
*/ */
export async function balance( export async function balance(
web3: Web3, web3: Web3,
tokenAddress: string, tokenAddress: string,
account: string account: string,
tokenDecimals?: number
): Promise<string> { ): Promise<string> {
const tokenContract = new web3.eth.Contract(minAbi, tokenAddress) const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)
const trxReceipt = await tokenContract.methods.balanceOf(account).call() const trxReceipt = await tokenContract.methods.balanceOf(account).call()
return await unitsToAmount(web3, tokenAddress, trxReceipt) return await unitsToAmount(web3, tokenAddress, trxReceipt, tokenDecimals)
} }