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

add more estGas split, add some test check

This commit is contained in:
lacoop6tu 2021-10-26 17:05:47 -05:00
parent d9a149bd5c
commit 2728dc3c68
2 changed files with 405 additions and 230 deletions

View File

@ -15,26 +15,19 @@ const MaxUint256 =
* Provides an interface to Ocean friendly fork from Balancer BPool * Provides an interface to Ocean friendly fork from Balancer BPool
*/ */
export class Pool { export class Pool {
public poolABI: AbiItem | AbiItem[] public poolABI: AbiItem | AbiItem[]
public web3: Web3 public web3: Web3
public GASLIMIT_DEFAULT = 1000000 public GASLIMIT_DEFAULT = 1000000
private logger: Logger private logger: Logger
constructor( constructor(web3: Web3, logger: Logger, poolABI: AbiItem | AbiItem[] = null) {
web3: Web3,
logger: Logger,
poolABI: AbiItem | AbiItem[] = null
) {
if (poolABI) this.poolABI = poolABI if (poolABI) this.poolABI = poolABI
else this.poolABI = PoolTemplate.abi as AbiItem[] else this.poolABI = PoolTemplate.abi as AbiItem[]
this.web3 = web3 this.web3 = web3
this.logger = logger this.logger = logger
} }
/** /**
* Get Alloance for both DataToken and Ocean * Get Alloance for both DataToken and Ocean
* @param {String } tokenAdress * @param {String } tokenAdress
@ -146,7 +139,6 @@ export class Pool {
return result return result
} }
/** /**
* Set pool fee * Set pool fee
* @param {String} account * @param {String} account
@ -174,7 +166,6 @@ export class Pool {
return result return result
} }
/** /**
* Get number of tokens composing this pool * Get number of tokens composing this pool
* @param {String} poolAddress * @param {String} poolAddress
@ -256,7 +247,6 @@ export class Pool {
return result return result
} }
/** /**
* Get if a token is bounded to a pool * Get if a token is bounded to a pool
* @param {String} poolAddress * @param {String} poolAddress
@ -380,7 +370,7 @@ export class Pool {
return weight return weight
} }
/** /**
* Estimate gas cost for swapExactAmountIn * Estimate gas cost for swapExactAmountIn
* @param {String} address * @param {String} address
* @param {String} poolAddress * @param {String} poolAddress
@ -392,36 +382,37 @@ export class Pool {
* @param {Contract} contractInstance optional contract instance * @param {Contract} contractInstance optional contract instance
* @return {Promise<number>} * @return {Promise<number>}
*/ */
public async estSwapExactAmountIn( public async estSwapExactAmountIn(
address: string, address: string,
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
tokenAmountIn: string, tokenAmountIn: string,
tokenOut: string, tokenOut: string,
minAmountOut: string, minAmountOut: string,
maxPrice: string, maxPrice: string,
contractInstance?: Contract contractInstance?: Contract
) { ) {
const poolContract = const poolContract =
contractInstance || new this.web3.eth.Contract(this.poolABI as AbiItem[],poolAddress) contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas const gasLimitDefault = this.GASLIMIT_DEFAULT
try { let estGas
estGas = await poolContract.methods try {
.swapExactAmountIn( estGas = await poolContract.methods
tokenIn, .swapExactAmountIn(
this.web3.utils.toWei(tokenAmountIn), tokenIn,
tokenOut, this.web3.utils.toWei(tokenAmountIn),
this.web3.utils.toWei(minAmountOut), tokenOut,
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256 this.web3.utils.toWei(minAmountOut),
) maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) )
} catch (e) { .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
estGas = gasLimitDefault } catch (e) {
} estGas = gasLimitDefault
return estGas }
} return estGas
}
/** /**
* swapExactAmountIn - Trades an exact tokenAmountIn of tokenIn taken from the caller by the pool, in exchange for at least minAmountOut of tokenOut given to the caller from the pool, with a maximum marginal price of maxPrice. Returns (tokenAmountOut, spotPriceAfter), where tokenAmountOut is the amount of token that came out of the pool, and spotPriceAfter is the new marginal spot price, ie, the result of getSpotPrice after the call. (These values are what are limited by the arguments; you are guaranteed tokenAmountOut >= minAmountOut and spotPriceAfter <= maxPrice). * swapExactAmountIn - Trades an exact tokenAmountIn of tokenIn taken from the caller by the pool, in exchange for at least minAmountOut of tokenOut given to the caller from the pool, with a maximum marginal price of maxPrice. Returns (tokenAmountOut, spotPriceAfter), where tokenAmountOut is the amount of token that came out of the pool, and spotPriceAfter is the new marginal spot price, ie, the result of getSpotPrice after the call. (These values are what are limited by the arguments; you are guaranteed tokenAmountOut >= minAmountOut and spotPriceAfter <= maxPrice).
@ -446,12 +437,16 @@ export class Pool {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null let result = null
// TODO: add multiple decimals support // TODO: add multiple decimals support
const estGas = await this.estSwapExactAmountIn(address,poolAddress,tokenIn, const estGas = await this.estSwapExactAmountIn(
this.web3.utils.toWei(tokenAmountIn), address,
tokenOut, poolAddress,
this.web3.utils.toWei(minAmountOut), tokenIn,
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256) this.web3.utils.toWei(tokenAmountIn),
tokenOut,
this.web3.utils.toWei(minAmountOut),
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
)
try { try {
result = await pool.methods result = await pool.methods
.swapExactAmountIn( .swapExactAmountIn(
@ -472,7 +467,7 @@ export class Pool {
return result return result
} }
/** /**
* Estimate gas cost for swapExactAmountOut * Estimate gas cost for swapExactAmountOut
* @param {String} address * @param {String} address
* @param {String} poolAddress * @param {String} poolAddress
@ -484,36 +479,37 @@ export class Pool {
* @param {Contract} contractInstance optional contract instance * @param {Contract} contractInstance optional contract instance
* @return {Promise<number>} * @return {Promise<number>}
*/ */
public async estSwapExactAmountOut( public async estSwapExactAmountOut(
address: string, address: string,
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
maxAmountIn: string, maxAmountIn: string,
tokenOut: string, tokenOut: string,
amountOut: string, amountOut: string,
maxPrice?: string, maxPrice?: string,
contractInstance?: Contract contractInstance?: Contract
) { ) {
const poolContract = const poolContract =
contractInstance || new this.web3.eth.Contract(this.poolABI as AbiItem[],poolAddress) contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas const gasLimitDefault = this.GASLIMIT_DEFAULT
try { let estGas
estGas = await poolContract.methods try {
.swapExactAmountOut( estGas = await poolContract.methods
tokenIn, .swapExactAmountOut(
this.web3.utils.toWei(maxAmountIn), tokenIn,
tokenOut, this.web3.utils.toWei(maxAmountIn),
this.web3.utils.toWei(amountOut), tokenOut,
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256 this.web3.utils.toWei(amountOut),
) maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) )
} catch (e) { .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
estGas = gasLimitDefault } catch (e) {
} estGas = gasLimitDefault
return estGas }
} return estGas
}
/** /**
* swapExactAmountOut * swapExactAmountOut
@ -537,13 +533,17 @@ export class Pool {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null let result = null
const estGas = await this.estSwapExactAmountOut(account,poolAddress,tokenIn, const estGas = await this.estSwapExactAmountOut(
this.web3.utils.toWei(maxAmountIn), account,
tokenOut, poolAddress,
this.web3.utils.toWei(amountOut), tokenIn,
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256) this.web3.utils.toWei(maxAmountIn),
tokenOut,
this.web3.utils.toWei(amountOut),
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
)
try { try {
result = await pool.methods result = await pool.methods
.swapExactAmountOut( .swapExactAmountOut(
@ -564,23 +564,53 @@ export class Pool {
return result return result
} }
/**
* Estimate gas cost for swapExactAmountOut
* @param {String} address
* @param {String} poolAddress
* @param {String} poolAmountOut will be converted to wei
* @param {String[]} maxAmountsIn array holding maxAmount per each token, will be converted to wei
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estJoinPool(
address: string,
poolAddress: string,
poolAmountOut: string,
maxAmountsIn: string[],
contractInstance?: Contract
) {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.joinPool(this.web3.utils.toWei(poolAmountOut), maxAmountsIn)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/** /**
* Join the pool, getting poolAmountOut pool tokens. This will pull some of each of the currently trading tokens in the pool, meaning you must have called approve for each token for this pool. These values are limited by the array of maxAmountsIn in the order of the pool tokens. * Join the pool, getting poolAmountOut pool tokens. This will pull some of each of the currently trading tokens in the pool, meaning you must have called approve for each token for this pool. These values are limited by the array of maxAmountsIn in the order of the pool tokens.
* @param {String} account * @param {String} address
* @param {String} poolAddress * @param {String} poolAddress
* @param {String} poolAmountOut will be converted to wei * @param {String} poolAmountOut will be converted to wei
* @param {String[]} maxAmountsIn array holding maxAmount per each token, will be converted to wei * @param {String[]} maxAmountsIn array holding maxAmount per each token, will be converted to wei
* @return {TransactionReceipt} * @return {TransactionReceipt}
*/ */
async joinPool( async joinPool(
account: string, address: string,
poolAddress: string, poolAddress: string,
poolAmountOut: string, poolAmountOut: string,
maxAmountsIn: string[] maxAmountsIn: string[]
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
from: account
})
const weiMaxAmountsIn = [] const weiMaxAmountsIn = []
let amount: string let amount: string
@ -590,20 +620,19 @@ export class Pool {
} }
let result = null let result = null
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas const estGas = await this.estJoinPool(
try { address,
estGas = await pool.methods poolAddress,
.joinPool(this.web3.utils.toWei(poolAmountOut), weiMaxAmountsIn) this.web3.utils.toWei(poolAmountOut),
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas)) weiMaxAmountsIn
} catch (e) { )
estGas = gasLimitDefault
}
try { try {
result = await pool.methods result = await pool.methods
.joinPool(this.web3.utils.toWei(poolAmountOut), weiMaxAmountsIn) .joinPool(this.web3.utils.toWei(poolAmountOut), weiMaxAmountsIn)
.send({ .send({
from: account, from: address,
gas: estGas + 1, gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3) gasPrice: await getFairGasPrice(this.web3)
}) })
@ -613,6 +642,38 @@ export class Pool {
return result return result
} }
/**
* Estimate gas cost for exitPool
* @param {String} address
* @param {String} poolAddress
``* @param {String} poolAmountIn will be converted to wei
* @param {String[]} minAmountsOut array holding minAmount per each token, will be converted to wei
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estExitPool(
address: string,
poolAddress: string,
poolAmountIn: string,
minAmountsOut: string[],
contractInstance?: Contract
) {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.exitPool(this.web3.utils.toWei(poolAmountIn), minAmountsOut)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/** /**
* Exit the pool, paying poolAmountIn pool tokens and getting some of each of the currently trading tokens in return. These values are limited by the array of minAmountsOut in the order of the pool tokens. * Exit the pool, paying poolAmountIn pool tokens and getting some of each of the currently trading tokens in return. These values are limited by the array of minAmountsOut in the order of the pool tokens.
* @param {String} account * @param {String} account
@ -627,9 +688,7 @@ export class Pool {
poolAmountIn: string, poolAmountIn: string,
minAmountsOut: string[] minAmountsOut: string[]
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
from: account
})
const weiMinAmountsOut = [] const weiMinAmountsOut = []
let amount: string let amount: string
@ -637,15 +696,13 @@ export class Pool {
weiMinAmountsOut.push(this.web3.utils.toWei(amount)) weiMinAmountsOut.push(this.web3.utils.toWei(amount))
} }
let result = null let result = null
const gasLimitDefault = this.GASLIMIT_DEFAULT const estGas = this.estExitPool(
let estGas account,
try { poolAddress,
estGas = await pool.methods this.web3.utils.toWei(poolAmountIn),
.exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut) weiMinAmountsOut
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas)) )
} catch (e) {
estGas = gasLimitDefault
}
try { try {
result = await pool.methods result = await pool.methods
.exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut) .exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut)
@ -656,6 +713,40 @@ export class Pool {
return result return result
} }
/**
* Estimate gas cost for joinswapExternAmountIn
* @param {String} address
* @param {String} poolAddress
* @param {String} tokenIn
* @param {String} tokenAmountIn will be converted to wei
* @param {String} minPoolAmountOut will be converted to wei
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estJoinswapExternAmountIn(
address: string,
poolAddress: string,
tokenIn: string,
tokenAmountIn: string,
minPoolAmountOut: string,
contractInstance?: Contract
) {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.joinswapExternAmountIn(tokenIn, tokenAmountIn, minPoolAmountOut)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/** /**
* Pay tokenAmountIn of token tokenIn to join the pool, getting poolAmountOut of the pool shares. * Pay tokenAmountIn of token tokenIn to join the pool, getting poolAmountOut of the pool shares.
* @param {String} account * @param {String} account
@ -672,23 +763,17 @@ export class Pool {
tokenAmountIn: string, tokenAmountIn: string,
minPoolAmountOut: string minPoolAmountOut: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
from: account
})
let result = null let result = null
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas const estGas = await this.estJoinswapExternAmountIn(
try { account,
estGas = await pool.methods poolAddress,
.joinswapExternAmountIn( tokenIn,
tokenIn, this.web3.utils.toWei(tokenAmountIn),
this.web3.utils.toWei(tokenAmountIn), this.web3.utils.toWei(minPoolAmountOut)
this.web3.utils.toWei(minPoolAmountOut) )
)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
try { try {
result = await pool.methods result = await pool.methods
.joinswapExternAmountIn( .joinswapExternAmountIn(
@ -708,6 +793,39 @@ export class Pool {
return result return result
} }
/**
* Estimate gas cost for joinswapExternAmountOut
* @param {String} address
* @param {String} poolAddress
* @param {String} tokenIn
* @param {String} poolAmountOut will be converted to wei
* @param {String} maxAmountIn will be converted to wei
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estJoinswapExternAmountOut(
address: string,
poolAddress: string,
tokenIn: string,
poolAmountOut: string,
maxAmountIn: string,
contractInstance?: Contract
) {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.joinswapExternAmountOut(tokenIn, poolAmountOut, maxAmountIn)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/** /**
* Specify poolAmountOut pool shares that you want to get, and a token tokenIn to pay with. This costs tokenAmountIn tokens (these went into the pool). * Specify poolAmountOut pool shares that you want to get, and a token tokenIn to pay with. This costs tokenAmountIn tokens (these went into the pool).
* @param {String} account * @param {String} account
@ -724,23 +842,16 @@ export class Pool {
poolAmountOut: string, poolAmountOut: string,
maxAmountIn: string maxAmountIn: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
from: account
})
let result = null let result = null
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas const estGas = await this.estJoinswapExternAmountOut(
try { account,
estGas = await pool.methods poolAddress,
.joinswapPoolAmountOut( tokenIn,
tokenIn, this.web3.utils.toWei(poolAmountOut),
this.web3.utils.toWei(poolAmountOut), this.web3.utils.toWei(maxAmountIn)
this.web3.utils.toWei(maxAmountIn) )
)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
try { try {
result = await pool.methods result = await pool.methods
.joinswapPoolAmountOut( .joinswapPoolAmountOut(
@ -759,6 +870,40 @@ export class Pool {
return result return result
} }
/**
* Estimate gas cost for joinswapExternAmountIn
* @param {String} address
@param {String} poolAddress
* @param {String} tokenOut
* @param {String} poolAmountIn will be converted to wei
* @param {String} minTokenAmountOut will be converted to wei
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estExitswapPoolAmountIn(
address: string,
poolAddress: string,
tokenOut: string,
poolAmountIn: string,
minTokenAmountOut: string,
contractInstance?: Contract
) {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.exitswapPoolAmountIn(tokenOut, poolAmountIn, minTokenAmountOut)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/** /**
* Pay poolAmountIn pool shares into the pool, getting minTokenAmountOut of the given token tokenOut out of the pool. * Pay poolAmountIn pool shares into the pool, getting minTokenAmountOut of the given token tokenOut out of the pool.
* @param {String} account * @param {String} account
@ -775,23 +920,16 @@ export class Pool {
poolAmountIn: string, poolAmountIn: string,
minTokenAmountOut: string minTokenAmountOut: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, { const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
from: account
})
let result = null let result = null
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas const estGas = await this.estExitswapPoolAmountIn(
try { account,
estGas = await pool.methods poolAddress,
.exitswapPoolAmountIn( tokenOut,
tokenOut, this.web3.utils.toWei(poolAmountIn),
this.web3.utils.toWei(poolAmountIn), this.web3.utils.toWei(minTokenAmountOut)
this.web3.utils.toWei(minTokenAmountOut) )
)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
try { try {
result = await pool.methods result = await pool.methods
.exitswapPoolAmountIn( .exitswapPoolAmountIn(
@ -810,6 +948,40 @@ export class Pool {
return result return result
} }
/**
* Estimate gas cost for joinswapExternAmountIn
* @param {String} address
* @param {String} poolAddress
* @param {String} tokenOut
* @param {String} tokenAmountOut will be converted to wei
* @param {String} maxPoolAmountIn will be converted to wei
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estExitswapExternAmountOut(
address: string,
poolAddress: string,
tokenOut: string,
tokenAmountOut: string,
maxPoolAmountIn: string,
contractInstance?: Contract
) {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.exitswapExternAmountOut(tokenOut, tokenAmountOut, maxPoolAmountIn)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/** /**
* Specify tokenAmountOut of token tokenOut that you want to get out of the pool. This costs poolAmountIn pool shares (these went into the pool). * Specify tokenAmountOut of token tokenOut that you want to get out of the pool. This costs poolAmountIn pool shares (these went into the pool).
* @param {String} account * @param {String} account
@ -826,26 +998,16 @@ export class Pool {
tokenAmountOut: string, tokenAmountOut: string,
maxPoolAmountIn: string maxPoolAmountIn: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const gasLimitDefault = this.GASLIMIT_DEFAULT const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, {
from: account
})
let result = null let result = null
let estGas
try {
estGas = await pool.methods
.exitswapExternAmountOut(
tokenOut,
this.web3.utils.toWei(tokenAmountOut),
this.web3.utils.toWei(maxPoolAmountIn)
)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
const estGas = await this.estExitswapExternAmountOut(
account,
poolAddress,
tokenOut,
this.web3.utils.toWei(tokenAmountOut),
this.web3.utils.toWei(maxPoolAmountIn)
)
try { try {
result = await pool.methods result = await pool.methods
.exitswapExternAmountOut( .exitswapExternAmountOut(
@ -887,52 +1049,47 @@ export class Pool {
return price return price
} }
// public async calcSpotPrice(
// public async calcSpotPrice( // poolAddress: string,
// poolAddress: string, // tokenBalanceIn: string,
// tokenBalanceIn: string, // tokenWeightIn: string,
// tokenWeightIn: string, // tokenBalanceOut: string,
// tokenBalanceOut: string, // tokenWeightOut: string,
// tokenWeightOut: string, // swapFee: string
// swapFee: string // ): Promise<string> {
// ): Promise<string> { // const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
// const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) // let amount = '0'
// let amount = '0' // try {
// try { // const result = await pool.methods
// const result = await pool.methods // .calcSpotPrice(
// .calcSpotPrice( // this.web3.utils.toWei(tokenBalanceIn),
// this.web3.utils.toWei(tokenBalanceIn), // this.web3.utils.toWei(tokenWeightIn),
// this.web3.utils.toWei(tokenWeightIn), // this.web3.utils.toWei(tokenBalanceOut),
// this.web3.utils.toWei(tokenBalanceOut), // this.web3.utils.toWei(tokenWeightOut),
// this.web3.utils.toWei(tokenWeightOut), // this.web3.utils.toWei(swapFee)
// this.web3.utils.toWei(swapFee) // )
// ) // .call()
// .call() // amount = this.web3.utils.fromWei(result)
// amount = this.web3.utils.fromWei(result) // } catch (e) {
// } catch (e) { // this.logger.error('ERROR: Failed to call calcSpotPrice')
// this.logger.error('ERROR: Failed to call calcSpotPrice') // }
// } // return amount
// return amount // }
// }
public async getAmountInExactOut( public async getAmountInExactOut(
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
tokenOut: string, tokenOut: string,
tokenAmountOut: string, tokenAmountOut: string
): Promise<string> { ): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = null let amount = null
// if (new Decimal(tokenAmountOut).gte(tokenBalanceOut)) return null // if (new Decimal(tokenAmountOut).gte(tokenBalanceOut)) return null
try { try {
const result = await pool.methods const result = await pool.methods
. getAmountInExactOut( .getAmountInExactOut(tokenIn, tokenOut, tokenAmountOut)
tokenIn,
tokenOut,
tokenAmountOut
)
.call() .call()
// amount = this.web3.utils.fromWei(result) // amount = this.web3.utils.fromWei(result)
} catch (e) { } catch (e) {
this.logger.error('ERROR: Failed to calcInGivenOut') this.logger.error('ERROR: Failed to calcInGivenOut')
} }
@ -943,31 +1100,30 @@ export class Pool {
poolAddress: string, poolAddress: string,
tokenIn: string, tokenIn: string,
tokenOut: string, tokenOut: string,
tokenAmountIn: string, tokenAmountIn: string
): Promise<string> { ): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
const tokenInContract = new this.web3.eth.Contract(defaultERC20ABI.abi as AbiItem[], tokenIn) const tokenInContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
tokenIn
)
let amountInFormatted let amountInFormatted
let tokenInDecimals let tokenInDecimals
try { try {
tokenInDecimals = await tokenInContract.methods.decimals().call() tokenInDecimals = await tokenInContract.methods.decimals().call()
} catch(e) { } catch (e) {
this.logger.error('ERROR: FAILED TO CALL DECIMALS()') this.logger.error('ERROR: FAILED TO CALL DECIMALS()')
} }
//const tokenInDecimals = await tokenInContract.methods.decimals().call() //const tokenInDecimals = await tokenInContract.methods.decimals().call()
if ( tokenInDecimals == 18){ if (tokenInDecimals == 18) {
amountInFormatted = this.web3.utils.toWei(tokenAmountIn) amountInFormatted = this.web3.utils.toWei(tokenAmountIn)
} else { } else {
amountInFormatted = parseInt(tokenAmountIn)*10**(tokenInDecimals) amountInFormatted = parseInt(tokenAmountIn) * 10 ** tokenInDecimals
} }
let amount = null let amount = null
try { try {
const result = await pool.methods const result = await pool.methods
.getAmountOutExactIn( .getAmountOutExactIn(tokenIn, tokenOut, amountInFormatted)
tokenIn,
tokenOut,
amountInFormatted
)
.call() .call()
amount = this.web3.utils.fromWei(result) amount = this.web3.utils.fromWei(result)
} catch (e) { } catch (e) {
@ -1130,4 +1286,4 @@ export class Pool {
const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any) const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)
return topic return topic
} }
} }

View File

@ -1,6 +1,7 @@
import { assert, expect } from 'chai' import { assert, expect } from 'chai'
import { AbiItem } from 'web3-utils/types' import { AbiItem } from 'web3-utils/types'
import { TestContractHandler } from '../../../TestContractHandler' import { TestContractHandler } from '../../../TestContractHandler'
import { Contract } from 'web3-eth-contract'
import Web3 from 'web3' import Web3 from 'web3'
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json' import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
@ -30,6 +31,8 @@ describe('Pool unit test', () => {
let dtAddress2: string let dtAddress2: string
let poolAddress: string let poolAddress: string
let erc20Token: string let erc20Token: string
let erc20Contract: Contract
let daiContract: Contract
it('should deploy contracts', async () => { it('should deploy contracts', async () => {
contracts = new TestContractHandler( contracts = new TestContractHandler(
@ -61,7 +64,7 @@ describe('Pool unit test', () => {
await contracts.deployContracts(factoryOwner, FactoryRouter.abi as AbiItem[]) await contracts.deployContracts(factoryOwner, FactoryRouter.abi as AbiItem[])
const daiContract = new web3.eth.Contract( daiContract = new web3.eth.Contract(
contracts.MockERC20.options.jsonInterface, contracts.MockERC20.options.jsonInterface,
contracts.daiAddress contracts.daiAddress
) )
@ -138,7 +141,7 @@ describe('Pool unit test', () => {
const erc20Contract = new web3.eth.Contract( erc20Contract = new web3.eth.Contract(
ERC20Template.abi as AbiItem[], ERC20Template.abi as AbiItem[],
erc20Token erc20Token
) )
@ -156,5 +159,21 @@ describe('Pool unit test', () => {
}) })
it('#swapExactAmountIn - should swap', async () => {
await daiContract.methods.transfer(user2,web3.utils.toWei('100')).send({from:contracts.accounts[0]})
expect(await daiContract.methods.balanceOf(user2).call()).to.equal(web3.utils.toWei('100'))
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
await pool.approve(user2,contracts.daiAddress,poolAddress,web3.utils.toWei('100'))
const tx = await pool.swapExactAmountIn(user2,poolAddress,contracts.daiAddress,'10',erc20Token,'1')
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal(tx.events.LOG_SWAP.returnValues.tokenAmountOut)
})
it('#swapExactAmountOut - should swap', async () => {
// await pool.approve(contracts.accounts[0],contracts.daiAddress,poolAddress,web3.utils.toWei('100'))
expect(await daiContract.methods.balanceOf(user2).call()).to.equal(web3.utils.toWei('90'))
await pool.swapExactAmountOut(user2,poolAddress,contracts.daiAddress,'10',erc20Token,'1')
})
}) })