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

add computeBuySlippage and computeSellSlippage

This commit is contained in:
alexcos20 2020-11-16 04:20:06 -08:00
parent ab0d0400b1
commit 6424caca69
3 changed files with 173 additions and 13 deletions

View File

@ -1222,4 +1222,128 @@ export class OceanPool extends Pool {
} }
return result return result
} }
private async computeSlippage(
poolAddress: string,
tokenInBalance: string,
tokenInWeight: string,
tokenOutBalance: string,
tokenOutWeight: string,
newTokenInBalance: string,
newTokenOutBalance: string,
swapfee: string
) {
const initialPrice = await super.calcSpotPrice(
poolAddress,
tokenInBalance,
tokenInWeight,
tokenOutBalance,
tokenOutWeight,
swapfee
)
const newPrice = await super.calcSpotPrice(
poolAddress,
newTokenInBalance,
tokenInWeight,
newTokenOutBalance,
tokenOutWeight,
swapfee
)
console.log(
'In:' +
tokenInBalance +
', Out:' +
tokenOutBalance +
'| NEW In:' +
newTokenInBalance +
', Out:' +
newTokenOutBalance
)
console.log('initial Price:' + initialPrice)
console.log('new price:' + newPrice)
const slippage = (parseFloat(newPrice) * 100) / parseFloat(initialPrice) - 100
console.log('Slippage:' + slippage)
return String(slippage)
}
/* Get slippage for buying some datatokens while spending exactly oceanAmount ocean tokens */
public async computeBuySlippage(
poolAddress: string,
oceanAmount: string
): Promise<string> {
const dtAddress = await this.getDTAddress(poolAddress)
const dtWeight = await super.getDenormalizedWeight(poolAddress, dtAddress)
const oceanWeight = await super.getDenormalizedWeight(poolAddress, this.oceanAddress)
const dtReserve = await super.getReserve(poolAddress, dtAddress)
const oceanReserve = await super.getReserve(poolAddress, dtAddress)
const swapFee = await super.getSwapFee(poolAddress)
const dtReceived = await super.calcOutGivenIn(
poolAddress,
oceanReserve,
oceanWeight,
dtReserve,
dtWeight,
oceanAmount,
swapFee
)
const newDtReserve = new BigNumber(this.web3.utils.toWei(dtReserve)).minus(
this.web3.utils.toWei(dtReceived)
)
const newOceanReserve = new BigNumber(this.web3.utils.toWei(oceanReserve)).plus(
this.web3.utils.toWei(oceanAmount)
)
const slippage = await this.computeSlippage(
poolAddress,
oceanReserve,
oceanWeight,
dtReserve,
dtWeight,
this.web3.utils.fromWei(newOceanReserve.toString()),
this.web3.utils.fromWei(newDtReserve.toString()),
swapFee
)
console.log('Buy slippage:' + slippage)
return slippage
}
/* Get slippage for selling an exact amount of datatokens to get some ocean tokens */
public async computeSellSlippage(
poolAddress: string,
dtAmount: string
): Promise<string> {
const dtAddress = await this.getDTAddress(poolAddress)
const dtWeight = await super.getDenormalizedWeight(poolAddress, dtAddress)
const oceanWeight = await super.getDenormalizedWeight(poolAddress, this.oceanAddress)
const dtReserve = await super.getReserve(poolAddress, dtAddress)
const oceanReserve = await super.getReserve(poolAddress, dtAddress)
const swapFee = await super.getSwapFee(poolAddress)
const oceanReceived = await super.calcOutGivenIn(
poolAddress,
dtReserve,
dtWeight,
oceanReserve,
oceanWeight,
dtAmount,
swapFee
)
const newDtReserve = new BigNumber(this.web3.utils.toWei(dtReserve)).plus(
this.web3.utils.toWei(dtAmount)
)
const newOceanReserve = new BigNumber(this.web3.utils.toWei(oceanReserve)).minus(
this.web3.utils.toWei(oceanReceived)
)
const slippage = await this.computeSlippage(
poolAddress,
dtReserve,
dtWeight,
oceanReserve,
oceanWeight,
this.web3.utils.fromWei(newDtReserve.toString()),
this.web3.utils.fromWei(newOceanReserve.toString()),
swapFee
)
console.log('Sell slippage:' + slippage)
return slippage
}
} }

View File

@ -975,6 +975,33 @@ export class Pool extends PoolFactory {
return price return price
} }
public async calcSpotPrice(
poolAddress: string,
tokenBalanceIn: string,
tokenWeightIn: string,
tokenBalanceOut: string,
tokenWeightOut: string,
swapFee: string
): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let amount = '0'
try {
const result = await pool.methods
.calcSpotPrice(
this.web3.utils.toWei(tokenBalanceIn),
this.web3.utils.toWei(tokenWeightIn),
this.web3.utils.toWei(tokenBalanceOut),
this.web3.utils.toWei(tokenWeightOut),
this.web3.utils.toWei(swapFee)
)
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
this.logger.error('ERROR: Failed to call calcSpotPrice')
}
return amount
}
public async calcInGivenOut( public async calcInGivenOut(
poolAddress: string, poolAddress: string,
tokenBalanceIn: string, tokenBalanceIn: string,

View File

@ -115,13 +115,13 @@ describe('Balancer flow', () => {
assert(Pool !== null) assert(Pool !== null)
}) })
it('Alice mints 1000 tokens', async () => { it('Alice mints 2000 tokens', async () => {
await datatoken.mint(tokenAddress, alice, tokenAmount) await datatoken.mint(tokenAddress, alice, tokenAmount)
}) })
it('Alice mints 1000 Ocean tokens', async () => { it('Alice mints 2000 Ocean tokens', async () => {
await oceandatatoken.mint(oceanTokenAddress, alice, tokenAmount) await oceandatatoken.mint(oceanTokenAddress, alice, tokenAmount)
}) })
it('Alice transfers 200 ocean token to Bob', async () => { it('Alice transfers 500 ocean token to Bob', async () => {
await datatoken.transfer(oceanTokenAddress, bob, transferAmount, alice) await datatoken.transfer(oceanTokenAddress, bob, transferAmount, alice)
}) })
it('Alice creates a new OceanPool pool', async () => { it('Alice creates a new OceanPool pool', async () => {
@ -212,27 +212,36 @@ describe('Balancer flow', () => {
assert(pools.length > 0) assert(pools.length > 0)
greatPool = pools[0] greatPool = pools[0]
}) })
it('Bob should buy 2 DT ', async () => { it('Bob should buy 1 DT ', async () => {
await Pool.buyDT(bob, greatPool, '2', '4') await Pool.buyDT(bob, greatPool, '1', '4')
const bobDtBalance = await datatoken.balance(tokenAddress, bob) const bobDtBalance = await datatoken.balance(tokenAddress, bob)
const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob) const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob)
assert(Number(bobDtBalance) > 0) assert(Number(bobDtBalance) > 0)
assert(Number(bobOceanBalance) > 0) assert(Number(bobOceanBalance) > 0)
}) })
it('Bob should spend 5 Oceans to buy at least 1 DT ', async () => { it('Bob should spend 2 Oceans to buy at least 0.1 DT ', async () => {
await Pool.buyDTWithExactOcean(bob, greatPool, '1', '5') await Pool.buyDTWithExactOcean(bob, greatPool, '0.1', '2')
const bobDtBalance = await datatoken.balance(tokenAddress, bob) const bobDtBalance = await datatoken.balance(tokenAddress, bob)
const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob) const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob)
assert(Number(bobDtBalance) > 0) assert(Number(bobDtBalance) > 0)
assert(Number(bobOceanBalance) > 0) assert(Number(bobOceanBalance) > 0)
}) })
it('Bob should get slippage for buying some DT with 5 Ocean Tokens ', async () => {
const slippage = await Pool.computeBuySlippage(greatPool, '5')
assert(Number(slippage) > 0)
})
it('Bob should get slippage for selling 1 DT', async () => {
const slippage = await Pool.computeSellSlippage(greatPool, '1')
assert(Number(slippage) > 0)
})
it('Bob should sell 1 DT ', async () => { it('Bob should sell 1 DT ', async () => {
const maxPrice = parseFloat(currentDtPrice) * 2
await Pool.sellDT(bob, greatPool, '1', '1')
const bobDtBalance = await datatoken.balance(tokenAddress, bob) const bobDtBalance = await datatoken.balance(tokenAddress, bob)
const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob) const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob)
assert(Number(bobDtBalance) === 1) await Pool.sellDT(bob, greatPool, '1', '0.1')
assert(Number(bobOceanBalance) > 0) const newbobDtBalance = await datatoken.balance(tokenAddress, bob)
const newbobOceanBalance = await datatoken.balance(oceanTokenAddress, bob)
assert(Number(newbobDtBalance) < Number(bobDtBalance))
assert(Number(newbobOceanBalance) > Number(bobOceanBalance))
}) })
it('Bob should get maximum DT liquidity that he can add to pool ', async () => { it('Bob should get maximum DT liquidity that he can add to pool ', async () => {
const maxDT = await Pool.getDTMaxAddLiquidity(greatPool) const maxDT = await Pool.getDTMaxAddLiquidity(greatPool)
@ -255,7 +264,7 @@ describe('Balancer flow', () => {
await Pool.addDTLiquidity( await Pool.addDTLiquidity(
bob, bob,
greatPool, greatPool,
String(Math.min(parseFloat(maxDT), parseFloat(bobDtBalance))) String(Math.min(parseFloat(maxDT), parseFloat(bobDtBalance) / 2))
) )
const newbobDtBalance = await datatoken.balance(tokenAddress, bob) const newbobDtBalance = await datatoken.balance(tokenAddress, bob)
@ -313,7 +322,7 @@ describe('Balancer flow', () => {
await Pool.removeDTLiquidity( await Pool.removeDTLiquidity(
bob, bob,
greatPool, greatPool,
String(Math.min(parseFloat(maxDT), parseFloat('0.75'))), String(Math.min(parseFloat(maxDT), parseFloat('0.1'))),
poolShares poolShares
) )