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

add more Pool tests

This commit is contained in:
lacoop6tu 2021-10-27 16:29:13 -05:00
parent 2728dc3c68
commit 6e135231d3
3 changed files with 252 additions and 50 deletions

View File

@ -14,7 +14,7 @@ const MaxUint256 =
/**
* Provides an interface to Ocean friendly fork from Balancer BPool
*/
// TODO: Add decimals handling
export class Pool {
public poolABI: AbiItem | AbiItem[]
public web3: Web3
@ -35,12 +35,12 @@ export class Pool {
* @param {String} spender
*/
public async allowance(
tokenAdress: string,
tokenAddress: string,
owner: string,
spender: string
): Promise<string> {
const tokenAbi = defaultERC20ABI.abi as AbiItem[]
const datatoken = new this.web3.eth.Contract(tokenAbi, tokenAdress, {
const datatoken = new this.web3.eth.Contract(tokenAbi, tokenAddress, {
from: spender
})
const trxReceipt = await datatoken.methods.allowance(owner, spender).call()
@ -391,7 +391,7 @@ export class Pool {
minAmountOut: string,
maxPrice: string,
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -488,7 +488,7 @@ export class Pool {
amountOut: string,
maxPrice?: string,
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -579,7 +579,7 @@ export class Pool {
poolAmountOut: string,
maxAmountsIn: string[],
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -657,7 +657,7 @@ export class Pool {
poolAmountIn: string,
minAmountsOut: string[],
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -696,13 +696,12 @@ export class Pool {
weiMinAmountsOut.push(this.web3.utils.toWei(amount))
}
let result = null
const estGas = this.estExitPool(
const estGas = await this.estExitPool(
account,
poolAddress,
this.web3.utils.toWei(poolAmountIn),
weiMinAmountsOut
)
try {
result = await pool.methods
.exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut)
@ -730,7 +729,7 @@ export class Pool {
tokenAmountIn: string,
minPoolAmountOut: string,
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -794,7 +793,7 @@ export class Pool {
}
/**
* Estimate gas cost for joinswapExternAmountOut
* Estimate gas cost for joinswapPoolAmountOut
* @param {String} address
* @param {String} poolAddress
* @param {String} tokenIn
@ -803,14 +802,14 @@ export class Pool {
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estJoinswapExternAmountOut(
public async estJoinswapPoolAmountOut(
address: string,
poolAddress: string,
tokenIn: string,
poolAmountOut: string,
maxAmountIn: string,
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -819,13 +818,16 @@ export class Pool {
let estGas
try {
estGas = await poolContract.methods
.joinswapExternAmountOut(tokenIn, poolAmountOut, maxAmountIn)
.joinswapPoolAmountOut(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).
* @param {String} account
@ -845,7 +847,7 @@ export class Pool {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null
const estGas = await this.estJoinswapExternAmountOut(
const estGas = await this.estJoinswapPoolAmountOut(
account,
poolAddress,
tokenIn,
@ -887,7 +889,7 @@ export class Pool {
poolAmountIn: string,
minTokenAmountOut: string,
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -965,7 +967,7 @@ export class Pool {
tokenAmountOut: string,
maxPoolAmountIn: string,
contractInstance?: Contract
) {
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
@ -1086,10 +1088,10 @@ export class Pool {
let amount = null
// if (new Decimal(tokenAmountOut).gte(tokenBalanceOut)) return null
try {
const result = await pool.methods
const result = await pool.methods
.getAmountInExactOut(tokenIn, tokenOut, tokenAmountOut)
.call()
// amount = this.web3.utils.fromWei(result)
amount = this.web3.utils.fromWei(result)
} catch (e) {
this.logger.error('ERROR: Failed to calcInGivenOut')
}
@ -1102,17 +1104,18 @@ export class Pool {
tokenOut: string,
tokenAmountIn: string
): Promise<string> {
// TODO: solve decimals issue FIRST
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
const tokenInContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
tokenIn
)
let amountInFormatted
let tokenInDecimals
let tokenInDecimals = 18
try {
tokenInDecimals = await tokenInContract.methods.decimals().call()
} catch (e) {
this.logger.error('ERROR: FAILED TO CALL DECIMALS()')
this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')
}
//const tokenInDecimals = await tokenInContract.methods.decimals().call()
if (tokenInDecimals == 18) {
@ -1125,7 +1128,12 @@ export class Pool {
const result = await pool.methods
.getAmountOutExactIn(tokenIn, tokenOut, amountInFormatted)
.call()
amount = this.web3.utils.fromWei(result)
if (tokenInDecimals == 18){
amount = this.web3.utils.fromWei(result)
}
else{
amount = parseInt(result) / (10**tokenInDecimals)
}
} catch (e) {
this.logger.error('ERROR: Failed to calcOutGivenIn')
}

View File

@ -1,2 +1 @@
export * from './PoolFactory'
export * from './OceanPool'
export * from './Pool'

View File

@ -78,11 +78,9 @@ describe('Pool unit test', () => {
})
it('should initiate Pool instance', async () => {
pool = new Pool(web3, LoggerInstance,PoolTemplate.abi as AbiItem[])
pool = new Pool(web3, LoggerInstance, PoolTemplate.abi as AbiItem[])
})
it('#create a pool', async () => {
// CREATE A POOL
// we prepare transaction parameters objects
@ -138,42 +136,239 @@ describe('Pool unit test', () => {
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
erc20Contract = new web3.eth.Contract(
ERC20Template.abi as AbiItem[],
erc20Token
)
erc20Contract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], erc20Token)
// user2 has no dt1
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
})
it('#sharesBalance - should return user shares balance (datatoken balance, LPT balance, etc) ', async () => {
expect(await daiContract.methods.balanceOf(user2).call()).to.equal(
await pool.sharesBalance(user2, contracts.daiAddress)
)
})
it('#getNumTokens - should return num of tokens in pool (2)', async () => {
expect(await pool.getNumTokens(poolAddress)).to.equal('2')
})
it('#getPoolSharesTotalSupply - should return totalSupply of LPT', async () => {
// dt owner which added liquidity has half of pool shares (the rest is in the sidestaking contracta)
const dtOwnerLPTBalance = await pool.sharesBalance(contracts.accounts[0], poolAddress)
expect(await pool.sharesBalance(contracts.accounts[0], poolAddress)).to.equal(
await pool.sharesBalance(contracts.sideStakingAddress, poolAddress)
)
// total supply is twice the dtOwner balance
expect(await pool.getPoolSharesTotalSupply(poolAddress)).to.equal(
(2 * Number(dtOwnerLPTBalance)).toString()
)
})
it('#getCurrentTokens - should return current pool tokens', async () => {
const currentTokens = await pool.getCurrentTokens(poolAddress)
expect(currentTokens[0]).to.equal(erc20Token)
expect(currentTokens[1]).to.equal(contracts.daiAddress)
const currentTokens = await pool.getCurrentTokens(poolAddress)
expect(currentTokens[0]).to.equal(erc20Token)
expect(currentTokens[1]).to.equal(contracts.daiAddress)
})
it('#getFinalTokens - should return final pool tokens', async () => {
const finalTokens = await pool.getFinalTokens(poolAddress)
expect(finalTokens[0]).to.equal(erc20Token)
expect(finalTokens[1]).to.equal(contracts.daiAddress)
})
it('#getController - should return the pool controller (sideStaking address)', async () => {
expect(await pool.getController(poolAddress)).to.equal(contracts.sideStakingAddress)
})
it('#isBound - should return true if token is bound into the pool', async () => {
expect(await pool.isBound(poolAddress, contracts.daiAddress)).to.equal(true)
expect(await pool.isBound(poolAddress, contracts.oceanAddress)).to.equal(false)
})
it('#getReserve - should return final pool tokens', async () => {
expect(await pool.getReserve(poolAddress, contracts.daiAddress)).to.equal('2000') // base token initial liquidity
// rate is 1 so we have the same amount of DTs
expect(await pool.getReserve(poolAddress, erc20Token)).to.equal('2000')
})
it('#isFinalized - should return true if pool is finalized', async () => {
expect(await pool.isFinalized(poolAddress)).to.equal(true)
expect(await pool.isFinalized(contracts.oceanAddress)).to.equal(null)
})
it('#getSwapFee - should return the swap fee', async () => {
expect(await pool.getSwapFee(poolAddress)).to.equal('0.001')
})
it('#getNormalizedWeight - should return the normalized weight', async () => {
expect(await pool.getNormalizedWeight(poolAddress, contracts.daiAddress)).to.equal(
'0.5'
)
expect(await pool.getNormalizedWeight(poolAddress, erc20Token)).to.equal('0.5')
})
it('#getDenormalizedWeight - should return the swap fee', async () => {
expect(await pool.getDenormalizedWeight(poolAddress, contracts.daiAddress)).to.equal(
'5'
)
expect(await pool.getDenormalizedWeight(poolAddress, erc20Token)).to.equal('5')
})
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'))
await daiContract.methods
.transfer(user2, web3.utils.toWei('1000'))
.send({ from: contracts.accounts[0] })
expect(await daiContract.methods.balanceOf(user2).call()).to.equal(
web3.utils.toWei('1000')
)
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)
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')
})
// 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('990')
)
const tx = await pool.swapExactAmountOut(
user2,
poolAddress,
contracts.daiAddress,
'100',
erc20Token,
'50'
)
assert(tx != null)
})
it('#joinPool- user2 should add liquidity, receiving LP tokens', async () => {
const BPTAmountOut = '0.01'
const maxAmountsIn = [
'50', // Amounts IN
'50' // Amounts IN
]
await pool.approve(user2, erc20Token, poolAddress, web3.utils.toWei('1000'))
await pool.approve(user2, contracts.daiAddress, poolAddress, '1000')
const tx = await pool.joinPool(user2, poolAddress, BPTAmountOut, maxAmountsIn)
assert(tx != null)
expect(await pool.sharesBalance(user2, poolAddress)).to.equal(BPTAmountOut)
expect(tx.events.LOG_JOIN.event === 'LOG_JOIN')
expect(tx.events.LOG_BPT.event === 'LOG_BPT')
//console.log(tx)
// console.log(tx.events.LOG_JOIN)
// console.log(tx.events.LOG_BPT)
})
it('#joinswapExternAmountIn- user2 should add liquidity, receiving LP tokens', async () => {
const daiAmountIn = '100'
const minBPTOut = '0.1'
await pool.approve(user2, contracts.daiAddress, poolAddress, web3.utils.toWei('1000'))
const tx = await pool.joinswapExternAmountIn(
user2,
poolAddress,
contracts.daiAddress,
daiAmountIn,
minBPTOut
)
assert(tx != null)
expect(tx.events.LOG_JOIN[0].event === 'LOG_JOIN')
expect(tx.events.LOG_BPT.event === 'LOG_BPT')
// 2 JOIN EVENTS BECAUSE SIDE STAKING ALSO STAKED DTs, TODO: we should add to whom has been sent in the LOG_BPT event
expect(tx.events.LOG_JOIN[0].returnValues.bptAmount).to.equal(
tx.events.LOG_JOIN[0].returnValues.bptAmount
)
})
it('#joinswapPoolAmountOut- user2 should add liquidity, receiving LP tokens', async () => {
const BPTAmountOut = '0.1'
const maxDAIIn = '100'
await pool.approve(user2, contracts.daiAddress, poolAddress, web3.utils.toWei('1000'))
const tx = await pool.joinswapPoolAmountOut(
user2,
poolAddress,
contracts.daiAddress,
BPTAmountOut,
maxDAIIn
)
assert(tx != null)
expect(tx.events.LOG_JOIN[0].event === 'LOG_JOIN')
expect(tx.events.LOG_BPT.event === 'LOG_BPT')
// 2 JOIN EVENTS BECAUSE SIDE STAKING ALSO STAKED DTs, TODO: we should add to whom has been sent in the LOG_BPT event
expect(tx.events.LOG_JOIN[0].returnValues.bptAmount).to.equal(
tx.events.LOG_JOIN[0].returnValues.bptAmount
)
})
it('#exitPool- user2 exit the pool receiving both tokens, burning LP', async () => {
const BPTAmountIn = '0.5'
const minAmountOut = [
'1', // min amount out for OCEAN AND DT
'1'
]
const tx = await pool.exitPool(user2, poolAddress, BPTAmountIn, minAmountOut)
assert(tx != null)
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(erc20Token)
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(contracts.daiAddress)
})
it('#exitswapPoolAmountIn- user2 exit the pool receiving only DAI', async () => {
const BPTAmountIn = '0.5'
const minDAIOut = '0.5'
const tx = await pool.exitswapPoolAmountIn(
user2,
poolAddress,
contracts.daiAddress,
BPTAmountIn,
minDAIOut
)
assert(tx != null)
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.daiAddress)
// DTs were also unstaked in the same transaction (went to the staking contract)
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
})
it('#exitswapExternAmountOut- user2 exit the pool receiving only DAI', async () => {
const maxBTPIn = "0.5"
const exactDAIOut = "1"
const tx = await pool.exitswapPoolAmountIn(
user2,
poolAddress,
contracts.daiAddress,
maxBTPIn,
exactDAIOut
)
assert(tx != null)
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.daiAddress)
// DTs were also unstaked in the same transaction (went to the staking contract)
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
})
})