mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
Merge pull request #348 from oceanprotocol/feature/pool_validations
add pool validation and helpers
This commit is contained in:
commit
5c2cef618e
@ -21,9 +21,14 @@ before_script:
|
||||
- cd barge
|
||||
- git checkout v3
|
||||
- export ADDRESS_FILE="${HOME}/.ocean/ocean-contracts/artifacts/address.json"
|
||||
- mkdir "${HOME}/.ocean/"
|
||||
- mkdir "${HOME}/.ocean/ocean-contracts/"
|
||||
- mkdir "${HOME}/.ocean/ocean-contracts/artifacts"
|
||||
- touch $ADDRESS_FILE
|
||||
- echo "{}" >> $ADDRESS_FILE
|
||||
- export AQUARIUS_URI="http://172.15.0.5:5000"
|
||||
- export DEPLOY_CONTRACTS=true
|
||||
- export CONTRACTS_VERSION=v0.5.3
|
||||
- export DEPLOY_CONTRACTS="true"
|
||||
- export CONTRACTS_VERSION=v0.5.5
|
||||
- bash -x start_ocean.sh --no-dashboard 2>&1 > start_ocean.log &
|
||||
- cd ..
|
||||
- ./scripts/waitforcontracts.sh
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -939,9 +939,9 @@
|
||||
}
|
||||
},
|
||||
"@oceanprotocol/contracts": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/contracts/-/contracts-0.5.3.tgz",
|
||||
"integrity": "sha512-gJ8qQACJgxOPIrPE0OFQ09iYXBAisOGg56EmelQlsMUgp0yY0DKgBntDP83S/Ho1yBjGygqfxCjQrPH63hh/PA=="
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/contracts/-/contracts-0.5.5.tgz",
|
||||
"integrity": "sha512-Omwlh3KxPm2JOuLd6DW4teAQhGaIv0fRTopCvctey0XGsf3DcbJpwS0A0YfgLQnvCyyVMKsiq90YCqpJ3SO/cw=="
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "2.4.2",
|
||||
|
@ -42,7 +42,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ethereum-navigator/navigator": "^0.5.0",
|
||||
"@oceanprotocol/contracts": "^0.5.3",
|
||||
"@oceanprotocol/contracts": "^0.5.5",
|
||||
"decimal.js": "^10.2.0",
|
||||
"fs": "0.0.1-security",
|
||||
"lzma": "^2.3.2",
|
||||
|
@ -3,3 +3,7 @@ if [ "${DEPLOY_CONTRACTS}" = "true" ]; then
|
||||
sleep 2
|
||||
done
|
||||
fi
|
||||
cat "barge/start_ocean.log"
|
||||
ls -lh "${HOME}/.ocean/ocean-contracts/"
|
||||
ls -lh "${HOME}/.ocean/ocean-contracts/artifacts/"
|
||||
cat "${HOME}/.ocean/ocean-contracts/artifacts/address.json"
|
||||
|
@ -3,6 +3,8 @@ import { AbiItem } from 'web3-utils/types'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { Pool } from './Pool'
|
||||
import { EventData, Filter } from 'web3-eth-contract'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
declare type PoolTransactionType = 'swap' | 'join' | 'exit'
|
||||
|
||||
@ -63,31 +65,43 @@ export class OceanPool extends Pool {
|
||||
fee: string
|
||||
): Promise<string> {
|
||||
if (this.oceanAddress == null) {
|
||||
console.error('oceanAddress is not defined')
|
||||
console.error('ERROR: oceanAddress is not defined')
|
||||
return null
|
||||
}
|
||||
if (parseFloat(fee) > 0.1) {
|
||||
console.error('Swap fee too high. The maximum allowed swapFee is 0.1 (10%).')
|
||||
console.error('ERROR: Swap fee too high. The maximum allowed swapFee is 0.1 (10%).')
|
||||
return null
|
||||
}
|
||||
if (parseFloat(weight) > 9 || parseFloat(weight) < 1) {
|
||||
console.error('Weight out of bounds (min 1, max9)')
|
||||
console.error('ERROR: Weight out of bounds (min 1, max9)')
|
||||
return null
|
||||
}
|
||||
const address = await super.createPool(account)
|
||||
const oceanWeight = 10 - parseFloat(weight)
|
||||
const oceanAmount = (parseFloat(amount) * oceanWeight) / parseFloat(weight)
|
||||
this.dtAddress = token
|
||||
|
||||
await this.approve(account, token, address, this.web3.utils.toWei(String(amount)))
|
||||
await this.approve(
|
||||
let txid
|
||||
txid = await this.approve(
|
||||
account,
|
||||
token,
|
||||
address,
|
||||
this.web3.utils.toWei(String(amount))
|
||||
)
|
||||
if (!txid) {
|
||||
console.error('ERROR: Failed to call approve DT token')
|
||||
return null
|
||||
}
|
||||
txid = await this.approve(
|
||||
account,
|
||||
this.oceanAddress,
|
||||
address,
|
||||
this.web3.utils.toWei(String(oceanAmount))
|
||||
)
|
||||
|
||||
await super.setup(
|
||||
if (!txid) {
|
||||
console.error('ERROR: Failed to call approve OCEAN token')
|
||||
return null
|
||||
}
|
||||
txid = await super.setup(
|
||||
account,
|
||||
address,
|
||||
token,
|
||||
@ -98,7 +112,10 @@ export class OceanPool extends Pool {
|
||||
this.web3.utils.toWei(String(oceanWeight)),
|
||||
this.web3.utils.toWei(fee)
|
||||
)
|
||||
|
||||
if (!txid) {
|
||||
console.error('ERROR: Failed to create a new pool')
|
||||
return null
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
@ -127,14 +144,14 @@ export class OceanPool extends Pool {
|
||||
*/
|
||||
public async getOceanReserve(poolAddress: string): Promise<string> {
|
||||
if (this.oceanAddress == null) {
|
||||
console.error('oceanAddress is not defined')
|
||||
console.error('ERROR: oceanAddress is not defined')
|
||||
return null
|
||||
}
|
||||
return super.getReserve(poolAddress, this.oceanAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Data Token balance of a pool
|
||||
* Get datatoken balance of a pool
|
||||
* @param {String} poolAddress
|
||||
* @return {String}
|
||||
*/
|
||||
@ -144,10 +161,309 @@ export class OceanPool extends Pool {
|
||||
}
|
||||
|
||||
/**
|
||||
* Buy Data Token from a pool
|
||||
* Returns max amount that you can buy.
|
||||
* @param poolAddress
|
||||
* @param tokenAddress
|
||||
*/
|
||||
public async getMaxBuyQuantity(
|
||||
poolAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<string> {
|
||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||
return String(parseFloat(balance) / 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max amount of OCEAN that you can buy.
|
||||
* @param poolAddress
|
||||
* @param tokenAddress
|
||||
*/
|
||||
public async getOceanMaxBuyQuantity(poolAddress: string): Promise<string> {
|
||||
return this.getMaxBuyQuantity(poolAddress, this.oceanAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max amount of DT that you can buy.
|
||||
* @param poolAddress
|
||||
* @param tokenAddress
|
||||
*/
|
||||
public async getDTMaxBuyQuantity(poolAddress: string): Promise<string> {
|
||||
return this.getMaxBuyQuantity(poolAddress, await this.getDTAddress(poolAddress))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns tokenInAmount required to get tokenOutAmount
|
||||
* @param poolAddress
|
||||
* @param tokenInAddress
|
||||
* @param tokenOutAddress
|
||||
* @param tokenOutAmount
|
||||
*/
|
||||
public async calcInGivenOut(
|
||||
poolAddress: string,
|
||||
tokenInAddress: string,
|
||||
tokenOutAddress: string,
|
||||
tokenOutAmount: string
|
||||
): Promise<string> {
|
||||
const result = await super.calcInGivenOut(
|
||||
poolAddress,
|
||||
await super.getReserve(poolAddress, tokenInAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
|
||||
await super.getReserve(poolAddress, tokenOutAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
|
||||
tokenOutAmount,
|
||||
await this.getSwapFee(poolAddress)
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns tokenOutAmount given tokenInAmount
|
||||
* @param poolAddress
|
||||
* @param tokenInAddress
|
||||
* @param tokenOutAddress
|
||||
* @param tokenInAmount
|
||||
*/
|
||||
public async calcOutGivenIn(
|
||||
poolAddress: string,
|
||||
tokenInAddress: string,
|
||||
tokenOutAddress: string,
|
||||
tokenInAmount: string
|
||||
): Promise<string> {
|
||||
const result = await super.calcOutGivenIn(
|
||||
poolAddress,
|
||||
await super.getReserve(poolAddress, tokenInAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
|
||||
await super.getReserve(poolAddress, tokenOutAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
|
||||
tokenInAmount,
|
||||
await super.getSwapFee(poolAddress)
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns no of shares receved for adding a token to the pool
|
||||
* @param poolAddress
|
||||
* @param tokenInAddress
|
||||
* @param tokenInAmount
|
||||
*/
|
||||
public async calcPoolOutGivenSingleIn(
|
||||
poolAddress: string,
|
||||
tokenInAddress: string,
|
||||
tokenInAmount: string
|
||||
): Promise<string> {
|
||||
const result = super.calcPoolOutGivenSingleIn(
|
||||
poolAddress,
|
||||
await super.getReserve(poolAddress, tokenInAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
|
||||
await super.getPoolSharesTotalSupply(poolAddress),
|
||||
await super.getTotalDenormalizedWeight(poolAddress),
|
||||
tokenInAmount,
|
||||
await super.getSwapFee(poolAddress)
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns no of tokens required to get a specific no of poolShares
|
||||
* @param poolAddress
|
||||
* @param tokenInAddress
|
||||
* @param poolShares
|
||||
*/
|
||||
public async calcSingleInGivenPoolOut(
|
||||
poolAddress: string,
|
||||
tokenInAddress: string,
|
||||
poolShares: string
|
||||
): Promise<string> {
|
||||
const result = super.calcSingleInGivenPoolOut(
|
||||
poolAddress,
|
||||
await super.getReserve(poolAddress, tokenInAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenInAddress),
|
||||
await super.getPoolSharesTotalSupply(poolAddress),
|
||||
await super.getTotalDenormalizedWeight(poolAddress),
|
||||
poolShares,
|
||||
await super.getSwapFee(poolAddress)
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns no of tokens received for spending a specific no of poolShares
|
||||
* @param poolAddress
|
||||
* @param tokenOutAddress
|
||||
* @param poolShares
|
||||
*/
|
||||
public async calcSingleOutGivenPoolIn(
|
||||
poolAddress: string,
|
||||
tokenOutAddress: string,
|
||||
poolShares: string
|
||||
): Promise<string> {
|
||||
const result = super.calcSingleOutGivenPoolIn(
|
||||
poolAddress,
|
||||
await super.getReserve(poolAddress, tokenOutAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
|
||||
await super.getPoolSharesTotalSupply(poolAddress),
|
||||
await super.getTotalDenormalizedWeight(poolAddress),
|
||||
poolShares,
|
||||
await super.getSwapFee(poolAddress)
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns no of pool shares required to receive a specified amount of tokens
|
||||
* @param poolAddress
|
||||
* @param tokenOutAddress
|
||||
* @param tokenOutAmount
|
||||
*/
|
||||
public async calcPoolInGivenSingleOut(
|
||||
poolAddress: string,
|
||||
tokenOutAddress: string,
|
||||
tokenOutAmount: string
|
||||
): Promise<string> {
|
||||
const result = super.calcPoolInGivenSingleOut(
|
||||
poolAddress,
|
||||
await super.getReserve(poolAddress, tokenOutAddress),
|
||||
await super.getDenormalizedWeight(poolAddress, tokenOutAddress),
|
||||
await super.getPoolSharesTotalSupply(poolAddress),
|
||||
await super.getTotalDenormalizedWeight(poolAddress),
|
||||
tokenOutAmount,
|
||||
await super.getSwapFee(poolAddress)
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns no of pool shares required to receive specified amount of DT
|
||||
* @param poolAddress
|
||||
* @param dtAmount
|
||||
*/
|
||||
public async getPoolSharesRequiredToRemoveDT(
|
||||
poolAddress: string,
|
||||
dtAmount: string
|
||||
): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
return this.calcPoolInGivenSingleOut(poolAddress, dtAddress, dtAmount)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns DT amnount received after spending poolShares
|
||||
* @param poolAddress
|
||||
* @param poolShares
|
||||
*/
|
||||
public async getDTRemovedforPoolShares(
|
||||
poolAddress: string,
|
||||
poolShares: string
|
||||
): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
return this.calcSingleOutGivenPoolIn(poolAddress, dtAddress, poolShares)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns no of pool shares required to receive specified amount of DT
|
||||
* @param poolAddress
|
||||
* @param dtAmount
|
||||
*/
|
||||
public async getPoolSharesRequiredToRemoveOcean(
|
||||
poolAddress: string,
|
||||
oceanAmount: string
|
||||
): Promise<string> {
|
||||
return this.calcPoolInGivenSingleOut(poolAddress, this.oceanAddress, oceanAmount)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Ocean amnount received after spending poolShares
|
||||
* @param poolAddress
|
||||
* @param poolShares
|
||||
*/
|
||||
public async getOceanRemovedforPoolShares(
|
||||
poolAddress: string,
|
||||
poolShares: string
|
||||
): Promise<string> {
|
||||
return this.calcSingleOutGivenPoolIn(poolAddress, this.oceanAddress, poolShares)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max DT amount that you can add to the pool
|
||||
* @param poolAddress
|
||||
*/
|
||||
public async getDTMaxAddLiquidity(poolAddress: string): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
return this.getMaxAddLiquidity(poolAddress, dtAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max Ocean amount that you can add to the pool
|
||||
* @param poolAddress
|
||||
*/
|
||||
public async getOceanMaxAddLiquidity(poolAddress: string): Promise<string> {
|
||||
return this.getMaxAddLiquidity(poolAddress, this.oceanAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max amount of tokens that you can add to the pool
|
||||
* @param poolAddress
|
||||
* @param tokenAddress
|
||||
*/
|
||||
public async getMaxAddLiquidity(
|
||||
poolAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<string> {
|
||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||
if (parseFloat(balance) > 0) {
|
||||
const result = new BigNumber(this.web3.utils.toWei(balance))
|
||||
.dividedBy(3)
|
||||
.integerValue(BigNumber.ROUND_DOWN)
|
||||
.minus(1)
|
||||
return this.web3.utils.fromWei(result.toString())
|
||||
} else return '0'
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max amount of tokens that you can withdraw from the pool
|
||||
* @param poolAddress
|
||||
* @param tokenAddress
|
||||
*/
|
||||
public async getMaxRemoveLiquidity(
|
||||
poolAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<string> {
|
||||
const balance = await super.getReserve(poolAddress, tokenAddress)
|
||||
if (parseFloat(balance) > 0) {
|
||||
const result = new BigNumber(this.web3.utils.toWei(balance))
|
||||
.dividedBy(4)
|
||||
.integerValue(BigNumber.ROUND_DOWN)
|
||||
.minus(1)
|
||||
return this.web3.utils.fromWei(result.toString())
|
||||
} else return '0'
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max amount of DT that you can withdraw from the pool
|
||||
* @param poolAddress
|
||||
* @param tokenAddress
|
||||
*/
|
||||
public async getDTMaxRemoveLiquidity(poolAddress: string): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
return this.getMaxRemoveLiquidity(poolAddress, dtAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max amount of Ocean that you can withdraw from the pool
|
||||
* @param poolAddress
|
||||
* @param tokenAddress
|
||||
*/
|
||||
public async getOceanMaxRemoveLiquidity(poolAddress: string): Promise<string> {
|
||||
return this.getMaxRemoveLiquidity(poolAddress, this.oceanAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Buy datatoken from a pool
|
||||
* @param {String} account
|
||||
* @param {String} poolAddress
|
||||
* @param {String} amount Data Token amount
|
||||
* @param {String} amount datatoken amount
|
||||
* @param {String} oceanAmount Ocean Token amount payed
|
||||
* @param {String} maxPrice Maximum price to pay
|
||||
* @return {TransactionReceipt}
|
||||
@ -155,40 +471,54 @@ export class OceanPool extends Pool {
|
||||
public async buyDT(
|
||||
account: string,
|
||||
poolAddress: string,
|
||||
amount: string,
|
||||
oceanAmount: string,
|
||||
maxPrice: string
|
||||
dtAmountWanted: string,
|
||||
maxOceanAmount: string,
|
||||
maxPrice?: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if (this.oceanAddress == null) {
|
||||
console.error('oceanAddress is not defined')
|
||||
console.error('ERROR: undefined ocean token contract address')
|
||||
return null
|
||||
}
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
if (
|
||||
parseFloat(dtAmountWanted) > parseFloat(await this.getDTMaxBuyQuantity(poolAddress))
|
||||
) {
|
||||
console.error('ERROR: Buy quantity exceeds quantity allowed')
|
||||
return null
|
||||
}
|
||||
const calcInGivenOut = await this.getOceanNeeded(poolAddress, dtAmountWanted)
|
||||
|
||||
if (parseFloat(calcInGivenOut) > parseFloat(maxOceanAmount)) {
|
||||
console.error('ERROR: Not enough Ocean Tokens')
|
||||
return null
|
||||
}
|
||||
// TODO - check balances first
|
||||
await super.approve(
|
||||
const txid = await super.approve(
|
||||
account,
|
||||
this.oceanAddress,
|
||||
poolAddress,
|
||||
this.web3.utils.toWei(oceanAmount)
|
||||
this.web3.utils.toWei(maxOceanAmount)
|
||||
)
|
||||
|
||||
if (!txid) {
|
||||
console.error('ERROR: OCEAN approve failed')
|
||||
return null
|
||||
}
|
||||
return this.swapExactAmountOut(
|
||||
account,
|
||||
poolAddress,
|
||||
this.oceanAddress,
|
||||
oceanAmount,
|
||||
maxOceanAmount,
|
||||
dtAddress,
|
||||
amount,
|
||||
dtAmountWanted,
|
||||
maxPrice
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sell Data Token
|
||||
* Sell datatoken
|
||||
* @param {String} account
|
||||
* @param {String} poolAddress
|
||||
* @param {String} amount Data Token amount
|
||||
* @param {String} amount datatoken amount to be sold
|
||||
* @param {String} oceanAmount Ocean Token amount expected
|
||||
* @param {String} maxPrice Minimum price to sell
|
||||
* @return {TransactionReceipt}
|
||||
@ -196,31 +526,54 @@ export class OceanPool extends Pool {
|
||||
public async sellDT(
|
||||
account: string,
|
||||
poolAddress: string,
|
||||
amount: string,
|
||||
oceanAmount: string,
|
||||
minPrice: string
|
||||
dtAmount: string,
|
||||
oceanAmountWanted: string,
|
||||
maxPrice?: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if (this.oceanAddress == null) {
|
||||
console.error('oceanAddress is not defined')
|
||||
console.error('ERROR: oceanAddress is not defined')
|
||||
return null
|
||||
}
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
return this.swapExactAmountOut(
|
||||
if (
|
||||
parseFloat(oceanAmountWanted) >
|
||||
parseFloat(await this.getOceanMaxBuyQuantity(poolAddress))
|
||||
) {
|
||||
console.error('ERROR: Buy quantity exceeds quantity allowed')
|
||||
return null
|
||||
}
|
||||
const calcOutGivenIn = await this.getOceanReceived(poolAddress, dtAmount)
|
||||
|
||||
if (parseFloat(calcOutGivenIn) < parseFloat(oceanAmountWanted)) {
|
||||
console.error('ERROR: Not enough datatokens')
|
||||
return null
|
||||
}
|
||||
const txid = await super.approve(
|
||||
account,
|
||||
dtAddress,
|
||||
poolAddress,
|
||||
this.web3.utils.toWei(dtAmount)
|
||||
)
|
||||
if (!txid) {
|
||||
console.error('ERROR: DT approve failed')
|
||||
return null
|
||||
}
|
||||
return this.swapExactAmountIn(
|
||||
account,
|
||||
poolAddress,
|
||||
dtAddress,
|
||||
amount,
|
||||
dtAmount,
|
||||
this.oceanAddress,
|
||||
oceanAmount,
|
||||
minPrice
|
||||
oceanAmountWanted,
|
||||
maxPrice
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Data Token amount to pool liquidity
|
||||
* Add datatoken amount to pool liquidity
|
||||
* @param {String} account
|
||||
* @param {String} poolAddress
|
||||
* @param {String} amount Data Token amount
|
||||
* @param {String} amount datatoken amount
|
||||
* @return {TransactionReceipt}
|
||||
*/
|
||||
public async addDTLiquidity(
|
||||
@ -229,7 +582,21 @@ export class OceanPool extends Pool {
|
||||
amount: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
await super.approve(account, dtAddress, poolAddress, this.web3.utils.toWei(amount))
|
||||
const maxAmount = await this.getMaxAddLiquidity(poolAddress, dtAddress)
|
||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
||||
console.error('ERROR: Too much reserve to add')
|
||||
return null
|
||||
}
|
||||
const txid = await super.approve(
|
||||
account,
|
||||
dtAddress,
|
||||
poolAddress,
|
||||
this.web3.utils.toWei(amount)
|
||||
)
|
||||
if (!txid) {
|
||||
console.error('ERROR: DT approve failed')
|
||||
return null
|
||||
}
|
||||
const result = await super.joinswapExternAmountIn(
|
||||
account,
|
||||
poolAddress,
|
||||
@ -241,10 +608,10 @@ export class OceanPool extends Pool {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Data Token amount from pool liquidity
|
||||
* Remove datatoken amount from pool liquidity
|
||||
* @param {String} account
|
||||
* @param {String} poolAddress
|
||||
* @param {String} amount Data Token amount
|
||||
* @param {String} amount datatoken amount
|
||||
* @return {TransactionReceipt}
|
||||
*/
|
||||
public async removeDTLiquidity(
|
||||
@ -254,7 +621,23 @@ export class OceanPool extends Pool {
|
||||
maximumPoolShares: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
// TODO Check balance of PoolShares before doing exit
|
||||
const maxAmount = await this.getDTMaxRemoveLiquidity(poolAddress)
|
||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
||||
console.error('ERROR: Too much reserve to remove')
|
||||
return null
|
||||
}
|
||||
const usershares = await this.sharesBalance(account, poolAddress)
|
||||
if (parseFloat(usershares) < parseFloat(maximumPoolShares)) {
|
||||
console.error('ERROR: Not enough poolShares')
|
||||
return null
|
||||
}
|
||||
if (
|
||||
parseFloat(maximumPoolShares) <
|
||||
parseFloat(await this.getPoolSharesRequiredToRemoveDT(poolAddress, amount))
|
||||
) {
|
||||
console.error('ERROR: Not enough poolShares')
|
||||
return null
|
||||
}
|
||||
return this.exitswapExternAmountOut(
|
||||
account,
|
||||
poolAddress,
|
||||
@ -277,15 +660,24 @@ export class OceanPool extends Pool {
|
||||
amount: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if (this.oceanAddress == null) {
|
||||
console.error('oceanAddress is not defined')
|
||||
console.error('ERROR: oceanAddress is not defined')
|
||||
return null
|
||||
}
|
||||
await super.approve(
|
||||
const maxAmount = await this.getOceanMaxAddLiquidity(poolAddress)
|
||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
||||
console.error('ERROR: Too much reserve to add')
|
||||
return null
|
||||
}
|
||||
const txid = await super.approve(
|
||||
account,
|
||||
this.oceanAddress,
|
||||
poolAddress,
|
||||
this.web3.utils.toWei(amount)
|
||||
)
|
||||
if (!txid) {
|
||||
console.error('ERROR: OCEAN approve failed')
|
||||
return null
|
||||
}
|
||||
const result = await super.joinswapExternAmountIn(
|
||||
account,
|
||||
poolAddress,
|
||||
@ -303,17 +695,33 @@ export class OceanPool extends Pool {
|
||||
* @param {String} amount Ocean Token amount in OCEAN
|
||||
* @return {TransactionReceipt}
|
||||
*/
|
||||
public removeOceanLiquidity(
|
||||
public async removeOceanLiquidity(
|
||||
account: string,
|
||||
poolAddress: string,
|
||||
amount: string,
|
||||
maximumPoolShares: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if (this.oceanAddress == null) {
|
||||
console.error('oceanAddress is not defined')
|
||||
console.error('ERROR: oceanAddress is not defined')
|
||||
return null
|
||||
}
|
||||
const maxAmount = await this.getOceanMaxRemoveLiquidity(poolAddress)
|
||||
if (parseFloat(amount) > parseFloat(maxAmount)) {
|
||||
console.error('ERROR: Too much reserve to remove')
|
||||
return null
|
||||
}
|
||||
const usershares = await this.sharesBalance(account, poolAddress)
|
||||
if (parseFloat(usershares) < parseFloat(maximumPoolShares)) {
|
||||
console.error('ERROR: Not enough poolShares')
|
||||
return null
|
||||
}
|
||||
if (
|
||||
parseFloat(maximumPoolShares) <
|
||||
parseFloat(await this.getPoolSharesRequiredToRemoveOcean(poolAddress, amount))
|
||||
) {
|
||||
console.error('ERROR: Not enough poolShares')
|
||||
return null
|
||||
}
|
||||
// TODO Check balance of PoolShares before doing exit
|
||||
return super.exitswapExternAmountOut(
|
||||
account,
|
||||
poolAddress,
|
||||
@ -324,20 +732,45 @@ export class OceanPool extends Pool {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Data Token price from pool
|
||||
* Remove pool liquidity
|
||||
* @param {String} account
|
||||
* @param {String} poolAddress
|
||||
* @param {String} poolShares
|
||||
* @param {String} minDT Minimum DT expected (defaults 0)
|
||||
* @param {String} poolShares Minim Ocean expected (defaults 0)
|
||||
* @return {TransactionReceipt}
|
||||
*/
|
||||
public async removePoolLiquidity(
|
||||
account: string,
|
||||
poolAddress: string,
|
||||
poolShares: string,
|
||||
minDT = '0',
|
||||
minOcean = '0'
|
||||
): Promise<TransactionReceipt> {
|
||||
const usershares = await this.sharesBalance(account, poolAddress)
|
||||
if (parseFloat(usershares) < parseFloat(poolShares)) {
|
||||
console.error('ERROR: Not enough poolShares')
|
||||
return null
|
||||
}
|
||||
|
||||
return this.exitPool(account, poolAddress, poolShares, [minDT, minOcean])
|
||||
}
|
||||
|
||||
/**
|
||||
* Get datatoken price from pool
|
||||
* @param {String} poolAddress
|
||||
* @return {String}
|
||||
*/
|
||||
public async getDTPrice(poolAddress: string): Promise<string> {
|
||||
if (this.oceanAddress == null) {
|
||||
console.error('oceanAddress is not defined')
|
||||
console.error('ERROR: oceanAddress is not defined')
|
||||
return null
|
||||
}
|
||||
return this.getOceanNeeded(poolAddress, '1')
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all pools that have Data Token in their composition
|
||||
* Search all pools that have datatoken in their composition
|
||||
* @param {String} dtAddress
|
||||
* @return {String[]}
|
||||
*/
|
||||
@ -358,19 +791,17 @@ export class OceanPool extends Pool {
|
||||
|
||||
public async getOceanNeeded(poolAddress: string, dtRequired: string): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
const tokenBalanceIn = await this.getReserve(poolAddress, this.oceanAddress)
|
||||
const tokenWeightIn = await this.getDenormalizedWeight(poolAddress, this.oceanAddress)
|
||||
const tokenBalanceOut = await this.getReserve(poolAddress, dtAddress)
|
||||
const tokenWeightOut = await this.getDenormalizedWeight(poolAddress, dtAddress)
|
||||
const swapFee = await this.getSwapFee(poolAddress)
|
||||
return super.calcInGivenOut(
|
||||
tokenBalanceIn,
|
||||
tokenWeightIn,
|
||||
tokenBalanceOut,
|
||||
tokenWeightOut,
|
||||
dtRequired,
|
||||
swapFee
|
||||
)
|
||||
return this.calcInGivenOut(poolAddress, this.oceanAddress, dtAddress, dtRequired)
|
||||
}
|
||||
|
||||
public async getOceanReceived(poolAddress: string, dtSold: string): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
return this.calcOutGivenIn(poolAddress, dtAddress, this.oceanAddress, dtSold)
|
||||
}
|
||||
|
||||
public async getDTNeeded(poolAddress: string, OceanRequired: string): Promise<string> {
|
||||
const dtAddress = await this.getDTAddress(poolAddress)
|
||||
return this.calcInGivenOut(poolAddress, dtAddress, this.oceanAddress, OceanRequired)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,9 +2,13 @@ import Web3 from 'web3'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import Decimal from 'decimal.js'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import jsonpoolABI from '@oceanprotocol/contracts/artifacts/BPool.json'
|
||||
import { PoolFactory } from './PoolFactory'
|
||||
|
||||
const MaxUint256: BigNumber = new BigNumber(
|
||||
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
|
||||
)
|
||||
/**
|
||||
* Provides an interface to Balancer BPool & BFactory
|
||||
*/
|
||||
@ -270,6 +274,23 @@ export class Pool extends PoolFactory {
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total supply of pool shares
|
||||
* @param {String} poolAddress
|
||||
* @return {String}
|
||||
*/
|
||||
async getPoolSharesTotalSupply(poolAddress: string): Promise<string> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
|
||||
let amount = null
|
||||
try {
|
||||
const result = await pool.methods.totalSupply().call()
|
||||
amount = this.web3.utils.fromWei(result)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return amount
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tokens composing this pool
|
||||
* @param {String} poolAddress
|
||||
@ -483,7 +504,7 @@ export class Pool extends PoolFactory {
|
||||
tokenAmountIn: string,
|
||||
tokenOut: string,
|
||||
minAmountOut: string,
|
||||
maxPrice: string
|
||||
maxPrice?: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, {
|
||||
from: account
|
||||
@ -496,7 +517,7 @@ export class Pool extends PoolFactory {
|
||||
this.web3.utils.toWei(tokenAmountIn),
|
||||
tokenOut,
|
||||
this.web3.utils.toWei(minAmountOut),
|
||||
this.web3.utils.toWei(maxPrice)
|
||||
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
|
||||
)
|
||||
.send({ from: account, gas: this.GASLIMIT_DEFAULT })
|
||||
} catch (e) {
|
||||
@ -523,7 +544,7 @@ export class Pool extends PoolFactory {
|
||||
maxAmountIn: string,
|
||||
tokenOut: string,
|
||||
minAmountOut: string,
|
||||
maxPrice: string
|
||||
maxPrice?: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, {
|
||||
from: account
|
||||
@ -536,7 +557,7 @@ export class Pool extends PoolFactory {
|
||||
this.web3.utils.toWei(maxAmountIn),
|
||||
tokenOut,
|
||||
this.web3.utils.toWei(minAmountOut),
|
||||
this.web3.utils.toWei(maxPrice)
|
||||
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
|
||||
)
|
||||
.send({ from: account, gas: this.GASLIMIT_DEFAULT })
|
||||
} catch (e) {
|
||||
@ -594,7 +615,7 @@ export class Pool extends PoolFactory {
|
||||
account: string,
|
||||
poolAddress: string,
|
||||
poolAmountIn: string,
|
||||
minAmountsOut: string
|
||||
minAmountsOut: string[]
|
||||
): Promise<TransactionReceipt> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress, {
|
||||
from: account
|
||||
@ -799,6 +820,7 @@ export class Pool extends PoolFactory {
|
||||
}
|
||||
|
||||
public async calcInGivenOut(
|
||||
poolAddress: string,
|
||||
tokenBalanceIn: string,
|
||||
tokenWeightIn: string,
|
||||
tokenBalanceOut: string,
|
||||
@ -806,14 +828,168 @@ export class Pool extends PoolFactory {
|
||||
tokenAmountOut: string,
|
||||
swapFee: string
|
||||
): Promise<string> {
|
||||
const weightRatio = new Decimal(tokenWeightOut).div(new Decimal(tokenWeightIn))
|
||||
const diff = new Decimal(tokenBalanceOut).minus(tokenAmountOut)
|
||||
const y = new Decimal(tokenBalanceOut).div(diff)
|
||||
const foo = y.pow(weightRatio).minus(new Decimal(1))
|
||||
const tokenAmountIn = new Decimal(tokenBalanceIn)
|
||||
.times(foo)
|
||||
.div(new Decimal(1).minus(new Decimal(swapFee)))
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
|
||||
let amount = null
|
||||
try {
|
||||
const result = await pool.methods
|
||||
.calcInGivenOut(
|
||||
this.web3.utils.toWei(tokenBalanceIn),
|
||||
this.web3.utils.toWei(tokenWeightIn),
|
||||
this.web3.utils.toWei(tokenBalanceOut),
|
||||
this.web3.utils.toWei(tokenWeightOut),
|
||||
this.web3.utils.toWei(tokenAmountOut),
|
||||
this.web3.utils.toWei(swapFee)
|
||||
)
|
||||
.call()
|
||||
amount = this.web3.utils.fromWei(result)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return amount
|
||||
}
|
||||
|
||||
return tokenAmountIn.toString()
|
||||
public async calcOutGivenIn(
|
||||
poolAddress: string,
|
||||
tokenBalanceIn: string,
|
||||
tokenWeightIn: string,
|
||||
tokenBalanceOut: string,
|
||||
tokenWeightOut: string,
|
||||
tokenAmountIn: string,
|
||||
swapFee: string
|
||||
): Promise<string> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
|
||||
let amount = null
|
||||
try {
|
||||
const result = await pool.methods
|
||||
.calcOutGivenIn(
|
||||
this.web3.utils.toWei(tokenBalanceIn),
|
||||
this.web3.utils.toWei(tokenWeightIn),
|
||||
this.web3.utils.toWei(tokenBalanceOut),
|
||||
this.web3.utils.toWei(tokenWeightOut),
|
||||
this.web3.utils.toWei(tokenAmountIn),
|
||||
this.web3.utils.toWei(swapFee)
|
||||
)
|
||||
.call()
|
||||
amount = this.web3.utils.fromWei(result)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return amount
|
||||
}
|
||||
|
||||
public async calcPoolOutGivenSingleIn(
|
||||
poolAddress: string,
|
||||
tokenBalanceIn: string,
|
||||
tokenWeightIn: string,
|
||||
poolSupply: string,
|
||||
totalWeight: string,
|
||||
tokenAmountIn: string,
|
||||
swapFee: string
|
||||
): Promise<string> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
|
||||
let amount = null
|
||||
try {
|
||||
const result = await pool.methods
|
||||
.calcPoolOutGivenSingleIn(
|
||||
this.web3.utils.toWei(tokenBalanceIn),
|
||||
this.web3.utils.toWei(tokenWeightIn),
|
||||
this.web3.utils.toWei(poolSupply),
|
||||
this.web3.utils.toWei(totalWeight),
|
||||
this.web3.utils.toWei(tokenAmountIn),
|
||||
this.web3.utils.toWei(swapFee)
|
||||
)
|
||||
.call()
|
||||
amount = this.web3.utils.fromWei(result)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return amount
|
||||
}
|
||||
|
||||
public async calcSingleInGivenPoolOut(
|
||||
poolAddress: string,
|
||||
tokenBalanceIn: string,
|
||||
tokenWeightIn: string,
|
||||
poolSupply: string,
|
||||
totalWeight: string,
|
||||
poolAmountOut: string,
|
||||
swapFee: string
|
||||
): Promise<string> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
|
||||
let amount = null
|
||||
try {
|
||||
const result = await pool.methods
|
||||
.calcSingleInGivenPoolOut(
|
||||
this.web3.utils.toWei(tokenBalanceIn),
|
||||
this.web3.utils.toWei(tokenWeightIn),
|
||||
this.web3.utils.toWei(poolSupply),
|
||||
this.web3.utils.toWei(totalWeight),
|
||||
this.web3.utils.toWei(poolAmountOut),
|
||||
this.web3.utils.toWei(swapFee)
|
||||
)
|
||||
.call()
|
||||
amount = this.web3.utils.fromWei(result)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return amount
|
||||
}
|
||||
|
||||
public async calcSingleOutGivenPoolIn(
|
||||
poolAddress: string,
|
||||
tokenBalanceOut: string,
|
||||
tokenWeightOut: string,
|
||||
poolSupply: string,
|
||||
totalWeight: string,
|
||||
poolAmountIn: string,
|
||||
swapFee: string
|
||||
): Promise<string> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
|
||||
let amount = null
|
||||
try {
|
||||
const result = await pool.methods
|
||||
.calcSingleOutGivenPoolIn(
|
||||
this.web3.utils.toWei(tokenBalanceOut),
|
||||
this.web3.utils.toWei(tokenWeightOut),
|
||||
this.web3.utils.toWei(poolSupply),
|
||||
this.web3.utils.toWei(totalWeight),
|
||||
this.web3.utils.toWei(poolAmountIn),
|
||||
this.web3.utils.toWei(swapFee)
|
||||
)
|
||||
.call()
|
||||
amount = this.web3.utils.fromWei(result)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return amount
|
||||
}
|
||||
|
||||
public async calcPoolInGivenSingleOut(
|
||||
poolAddress: string,
|
||||
tokenBalanceOut: string,
|
||||
tokenWeightOut: string,
|
||||
poolSupply: string,
|
||||
totalWeight: string,
|
||||
tokenAmountOut: string,
|
||||
swapFee: string
|
||||
): Promise<string> {
|
||||
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
|
||||
let amount = null
|
||||
try {
|
||||
const result = await pool.methods
|
||||
.calcPoolInGivenSingleOut(
|
||||
this.web3.utils.toWei(tokenBalanceOut),
|
||||
this.web3.utils.toWei(tokenWeightOut),
|
||||
this.web3.utils.toWei(poolSupply),
|
||||
this.web3.utils.toWei(totalWeight),
|
||||
this.web3.utils.toWei(tokenAmountOut),
|
||||
this.web3.utils.toWei(swapFee)
|
||||
)
|
||||
.call()
|
||||
amount = this.web3.utils.fromWei(result)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
return amount
|
||||
}
|
||||
}
|
||||
|
@ -417,4 +417,13 @@ export class DataTokens {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
public getStartOrderEventSignature(): string {
|
||||
const abi = this.datatokensABI as AbiItem[]
|
||||
const eventdata = abi.find(function (o) {
|
||||
if (o.name === 'OrderStarted' && o.type === 'event') return o
|
||||
})
|
||||
const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)
|
||||
return topic
|
||||
}
|
||||
}
|
||||
|
@ -612,15 +612,12 @@ export class Assets extends Instantiable {
|
||||
): Promise<Order[]> {
|
||||
const results: Order[] = []
|
||||
const address = account.getId().toLowerCase()
|
||||
const { datatokens } = this.ocean
|
||||
const topic1 = '0x000000000000000000000000' + address.substring(2)
|
||||
const events = await this.web3.eth.getPastLogs({
|
||||
topics: [
|
||||
[
|
||||
'0xe1c4fa794edfa8f619b8257a077398950357b9c6398528f94480307352f9afcc',
|
||||
null,
|
||||
'0x000000000000000000000000' + address.substring(address.length - 40)
|
||||
]
|
||||
],
|
||||
fromBlock: fromBlock || 0
|
||||
topics: [[datatokens.getStartOrderEventSignature(), null, topic1]],
|
||||
fromBlock: fromBlock || 0,
|
||||
toBlock: 'latest'
|
||||
})
|
||||
for (let i = 0; i < events.length; i++) {
|
||||
const order: Order = {
|
||||
@ -631,18 +628,20 @@ export class Assets extends Instantiable {
|
||||
consumer: '0x' + events[i].topics[1].substring(events[i].topics[1].length - 40),
|
||||
payer: '0x' + events[i].topics[2].substring(events[i].topics[2].length - 40)
|
||||
}
|
||||
const params = this.web3.eth.abi.decodeParameters(
|
||||
['uint256', 'uint256', 'uint256', 'uint256'],
|
||||
events[i].data
|
||||
)
|
||||
order.serviceId = parseInt(params[1])
|
||||
order.timestamp = parseInt(params[2])
|
||||
order.amount = this.web3.utils.fromWei(params[0])
|
||||
order.did = didPrefixed(didNoZeroX(order.dtAddress))
|
||||
const service = await this.getServiceByIndex(order.did, order.serviceId)
|
||||
order.serviceType = service.type
|
||||
if (!serviceType || (serviceType && serviceType === service.type))
|
||||
results.push(order)
|
||||
try {
|
||||
const params = this.web3.eth.abi.decodeParameters(
|
||||
['uint256', 'uint256', 'uint256', 'uint256'],
|
||||
events[i].data
|
||||
)
|
||||
order.serviceId = parseInt(params[1])
|
||||
order.timestamp = parseInt(params[2])
|
||||
order.amount = this.web3.utils.fromWei(params[0])
|
||||
order.did = didPrefixed(didNoZeroX(order.dtAddress))
|
||||
const service = await this.getServiceByIndex(order.did, order.serviceId)
|
||||
order.serviceType = service.type
|
||||
if (!serviceType || (serviceType && serviceType === service.type))
|
||||
results.push(order)
|
||||
} catch (e) {}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ const configs: ConfigHelperConfig[] = [
|
||||
|
||||
export class ConfigHelper {
|
||||
/* Load contract addresses from env ADDRESS_FILE (generated by ocean-contracts) */
|
||||
public getAddressesFromEnv(): Partial<ConfigHelperConfig> {
|
||||
public getAddressesFromEnv(network: string): Partial<ConfigHelperConfig> {
|
||||
try {
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
@ -78,13 +78,14 @@ export class ConfigHelper {
|
||||
)
|
||||
)
|
||||
|
||||
const { DTFactory, BFactory, FixedRateExchange, Metadata } = data?.ganache
|
||||
const { DTFactory, BFactory, FixedRateExchange, Metadata, Ocean } = data[network]
|
||||
|
||||
const configAddresses: Partial<ConfigHelperConfig> = {
|
||||
factoryAddress: DTFactory,
|
||||
poolFactoryAddress: BFactory,
|
||||
fixedRateExchangeAddress: FixedRateExchange,
|
||||
metadataContractAddress: Metadata,
|
||||
oceanTokenAddress: Ocean,
|
||||
...(process.env.AQUARIUS_URI && { metadataStoreUri: process.env.AQUARIUS_URI })
|
||||
}
|
||||
|
||||
@ -107,10 +108,8 @@ export class ConfigHelper {
|
||||
return null
|
||||
}
|
||||
|
||||
if (network === 'development') {
|
||||
const contractAddressesConfig = this.getAddressesFromEnv()
|
||||
config = { ...config, ...contractAddressesConfig }
|
||||
}
|
||||
const contractAddressesConfig = this.getAddressesFromEnv(config.network)
|
||||
config = { ...config, ...contractAddressesConfig }
|
||||
|
||||
const nodeUri = infuraProjectId
|
||||
? `${config.nodeUri}/${infuraProjectId}`
|
||||
|
@ -283,7 +283,7 @@ describe('Compute flow', () => {
|
||||
tokenAddressAlgorithm
|
||||
)
|
||||
assert(algorithmAsset.dataToken === tokenAddressAlgorithm)
|
||||
await sleep(6000)
|
||||
await sleep(60000)
|
||||
})
|
||||
|
||||
it('Alice mints 100 DTs and tranfers them to the compute marketplace', async () => {
|
||||
@ -445,7 +445,7 @@ describe('Compute flow', () => {
|
||||
alice
|
||||
)
|
||||
assert(newDdo !== null)
|
||||
await sleep(6000)
|
||||
await sleep(60000)
|
||||
const metaData = await ocean.assets.getServiceByType(ddo.id, 'compute')
|
||||
assert.equal(
|
||||
metaData.attributes.main.privacy.allowRawAlgorithm,
|
||||
|
@ -112,7 +112,7 @@ describe('Marketplace flow', () => {
|
||||
)
|
||||
ddo = await ocean.assets.create(asset, alice, [service1], tokenAddress)
|
||||
assert(ddo.dataToken === tokenAddress)
|
||||
await sleep(6000)
|
||||
await sleep(60000)
|
||||
})
|
||||
|
||||
it('Alice mints 100 tokens', async () => {
|
||||
@ -212,7 +212,7 @@ describe('Marketplace flow', () => {
|
||||
}
|
||||
const newDdo = await ocean.assets.editMetadata(ddo.id, newMetaData, alice)
|
||||
assert(newDdo !== null)
|
||||
await sleep(6000)
|
||||
await sleep(60000)
|
||||
const metaData = await ocean.assets.getServiceByType(ddo.id, 'metadata')
|
||||
assert.equal(metaData.attributes.main.name, newMetaData.title)
|
||||
assert.equal(
|
||||
|
@ -27,7 +27,7 @@ describe('Balancer flow', () => {
|
||||
let contracts: TestContractHandler
|
||||
let datatoken: DataTokens
|
||||
let tokenAddress: string
|
||||
let consoleDebug: false
|
||||
let consoleDebug: true
|
||||
let greatPool: string
|
||||
const tokenAmount = '1000'
|
||||
const transferAmount = '200'
|
||||
@ -171,26 +171,55 @@ describe('Balancer flow', () => {
|
||||
const requiredOcean = await Pool.getOceanNeeded(alicePoolAddress, '1')
|
||||
assert(Number(requiredOcean) > 0)
|
||||
})
|
||||
it('Get amount of DT needed to buy 1 Ocean', async () => {
|
||||
const requiredOcean = await Pool.getDTNeeded(alicePoolAddress, '1')
|
||||
assert(Number(requiredOcean) > 0)
|
||||
})
|
||||
|
||||
it('Bob should search for pools with this DT', async () => {
|
||||
const pools = await Pool.searchPoolforDT(tokenAddress)
|
||||
assert(pools.length > 0)
|
||||
greatPool = pools[0]
|
||||
})
|
||||
it('Bob should buy a DT ', async () => {
|
||||
it('Bob should buy 2 DT ', async () => {
|
||||
const maxPrice = parseFloat(currentDtPrice) * 2
|
||||
await Pool.buyDT(bob, greatPool, '1', '2', String(maxPrice))
|
||||
await Pool.buyDT(bob, greatPool, '2', '4')
|
||||
const bobDtBalance = await datatoken.balance(tokenAddress, bob)
|
||||
const bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob)
|
||||
assert(Number(bobDtBalance) > 0)
|
||||
assert(Number(bobOceanBalance) > 0)
|
||||
})
|
||||
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 bobOceanBalance = await datatoken.balance(oceanTokenAddress, bob)
|
||||
assert(Number(bobDtBalance) === 1)
|
||||
assert(Number(bobOceanBalance) > 0)
|
||||
})
|
||||
it('Bob should get maximum DT liquidity that he can add to pool ', async () => {
|
||||
const maxDT = await Pool.getDTMaxAddLiquidity(greatPool)
|
||||
if (consoleDebug) console.error('maxDT:' + maxDT)
|
||||
assert(parseFloat(maxDT) > 0)
|
||||
})
|
||||
|
||||
it('Bob should fail to add more than maximum DT liquidity that he can add to pool ', async () => {
|
||||
const maxDT = await Pool.getDTMaxAddLiquidity(greatPool)
|
||||
const tx = await Pool.addDTLiquidity(bob, greatPool, String(parseFloat(maxDT) * 2))
|
||||
assert(tx === null)
|
||||
})
|
||||
it('Bob should add DT liquidity to pool ', async () => {
|
||||
const maxDT = await Pool.getDTMaxAddLiquidity(greatPool)
|
||||
if (consoleDebug) console.error('maxDT:' + maxDT)
|
||||
const currentDtReserve = await Pool.getDTReserve(greatPool)
|
||||
if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve)
|
||||
const bobDtBalance = await datatoken.balance(tokenAddress, bob)
|
||||
if (consoleDebug) console.log('BOB DT Balance:' + bobDtBalance)
|
||||
await Pool.addDTLiquidity(bob, greatPool, bobDtBalance)
|
||||
await Pool.addDTLiquidity(
|
||||
bob,
|
||||
greatPool,
|
||||
String(Math.min(parseFloat(maxDT), parseFloat(bobDtBalance)))
|
||||
)
|
||||
|
||||
const newbobDtBalance = await datatoken.balance(tokenAddress, bob)
|
||||
|
||||
@ -204,7 +233,37 @@ describe('Balancer flow', () => {
|
||||
assert(parseFloat(newDtReserve) > parseFloat(currentDtReserve))
|
||||
assert(parseFloat(sharesBalance) > 0)
|
||||
})
|
||||
it('Bob should get maximum DT liquidity that he can remove from pool ', async () => {
|
||||
const maxDT = await Pool.getDTMaxRemoveLiquidity(greatPool)
|
||||
if (consoleDebug) console.log('maxDT:' + maxDT)
|
||||
assert(parseFloat(maxDT) > 0)
|
||||
})
|
||||
it('Bob should know how many Pool Shares he needs to remove 1 DT ', async () => {
|
||||
const poolShares = await Pool.getPoolSharesRequiredToRemoveDT(greatPool, '1')
|
||||
if (consoleDebug) console.log('poolShares:' + poolShares)
|
||||
assert(parseFloat(poolShares) > 0)
|
||||
})
|
||||
it('Bob should know how many DT gets in exchange of his Pool Shares', async () => {
|
||||
const poolShares = await Pool.getDTRemovedforPoolShares(
|
||||
greatPool,
|
||||
await Pool.sharesBalance(bob, greatPool)
|
||||
)
|
||||
if (consoleDebug) console.log('poolShares:' + poolShares)
|
||||
assert(parseFloat(poolShares) > 0)
|
||||
})
|
||||
|
||||
it('Bob should fail to remove more than maximum DT liquidity that he can remove from the pool ', async () => {
|
||||
const maxDT = await Pool.getDTMaxRemoveLiquidity(greatPool)
|
||||
if (consoleDebug) console.log('maxDT:' + maxDT)
|
||||
const poolShares = await Pool.sharesBalance(bob, greatPool)
|
||||
const tx = await Pool.removeDTLiquidity(
|
||||
bob,
|
||||
greatPool,
|
||||
String(parseFloat(maxDT) * 2),
|
||||
poolShares
|
||||
)
|
||||
assert(tx === null)
|
||||
})
|
||||
it('Bob should remove DT liquidity from pool ', async () => {
|
||||
const currentDtReserve = await Pool.getDTReserve(greatPool)
|
||||
if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve)
|
||||
@ -212,7 +271,14 @@ describe('Balancer flow', () => {
|
||||
if (consoleDebug) console.log('bobDtBalance:' + bobDtBalance)
|
||||
const poolShares = await Pool.sharesBalance(bob, greatPool)
|
||||
if (consoleDebug) console.log('poolShares:' + poolShares)
|
||||
await Pool.removeDTLiquidity(bob, greatPool, '0.75', poolShares)
|
||||
const maxDT = await Pool.getMaxRemoveLiquidity(greatPool, tokenAddress)
|
||||
if (consoleDebug) console.log('maxDT:' + maxDT)
|
||||
await Pool.removeDTLiquidity(
|
||||
bob,
|
||||
greatPool,
|
||||
String(Math.min(parseFloat(maxDT), parseFloat('0.75'))),
|
||||
poolShares
|
||||
)
|
||||
|
||||
const newDtReserve = await Pool.getDTReserve(greatPool)
|
||||
if (consoleDebug) console.log('newDtReserve:' + newDtReserve)
|
||||
@ -225,13 +291,33 @@ describe('Balancer flow', () => {
|
||||
assert(parseFloat(poolShares) > parseFloat(newpoolShares))
|
||||
})
|
||||
|
||||
it('Bob should get maximum Ocean liquidity that he can add to pool ', async () => {
|
||||
const maxOcean = await Pool.getOceanMaxAddLiquidity(greatPool)
|
||||
assert(parseFloat(maxOcean) > 0)
|
||||
})
|
||||
|
||||
it('Bob should fail to add more than maximum Ocean liquidity that he can add to pool ', async () => {
|
||||
const maxOcean = await Pool.getOceanMaxAddLiquidity(greatPool)
|
||||
const tx = await Pool.addOceanLiquidity(
|
||||
bob,
|
||||
greatPool,
|
||||
String(parseFloat(maxOcean) * 2)
|
||||
)
|
||||
assert(tx === null)
|
||||
})
|
||||
|
||||
it('Bob should add Ocean liquidity to pool ', async () => {
|
||||
const currentDtReserve = await Pool.getOceanReserve(greatPool)
|
||||
const bobDtBalance = await datatoken.balance(oceanTokenAddress, bob)
|
||||
if (consoleDebug) console.log('currentDtReserve:' + currentDtReserve)
|
||||
if (consoleDebug) console.log('bobDtBalance:' + bobDtBalance)
|
||||
const maxOcean = await Pool.getOceanMaxAddLiquidity(greatPool)
|
||||
|
||||
await Pool.addOceanLiquidity(bob, greatPool, '1')
|
||||
await Pool.addOceanLiquidity(
|
||||
bob,
|
||||
greatPool,
|
||||
String(Math.min(parseFloat(maxOcean), parseFloat(bobDtBalance)))
|
||||
)
|
||||
|
||||
const newbobDtBalance = await datatoken.balance(oceanTokenAddress, bob)
|
||||
|
||||
@ -245,6 +331,34 @@ describe('Balancer flow', () => {
|
||||
assert(parseFloat(newDtReserve) > parseFloat(currentDtReserve))
|
||||
assert(parseFloat(sharesBalance) > 0)
|
||||
})
|
||||
it('Bob should get maximum Ocean liquidity that he can remove from pool ', async () => {
|
||||
const maxOcean = await Pool.getMaxRemoveLiquidity(greatPool, oceanTokenAddress)
|
||||
assert(parseFloat(maxOcean) > 0)
|
||||
})
|
||||
it('Bob should fail to remove more than maximum Ocean liquidity that he can remove from the pool ', async () => {
|
||||
const maxOcean = await Pool.getOceanMaxRemoveLiquidity(greatPool)
|
||||
const poolShares = await Pool.sharesBalance(bob, greatPool)
|
||||
const tx = await Pool.removeOceanLiquidity(
|
||||
bob,
|
||||
greatPool,
|
||||
String(parseFloat(maxOcean) * 2),
|
||||
poolShares
|
||||
)
|
||||
assert(tx === null)
|
||||
})
|
||||
it('Bob should know how many Pool Shares he needs to remove 1 OCEAN ', async () => {
|
||||
const poolShares = await Pool.getPoolSharesRequiredToRemoveOcean(greatPool, '1')
|
||||
if (consoleDebug) console.log('poolShares:' + poolShares)
|
||||
assert(parseFloat(poolShares) > 0)
|
||||
})
|
||||
it('Bob should know how many OCEAN gets in exchange of his Pool Shares', async () => {
|
||||
const poolShares = await Pool.getOceanRemovedforPoolShares(
|
||||
greatPool,
|
||||
await Pool.sharesBalance(bob, greatPool)
|
||||
)
|
||||
if (consoleDebug) console.log('poolShares:' + poolShares)
|
||||
assert(parseFloat(poolShares) > 0)
|
||||
})
|
||||
|
||||
it('Bob should remove Ocean liquidity from pool ', async () => {
|
||||
const currentDtReserve = await Pool.getOceanReserve(greatPool)
|
||||
@ -269,6 +383,18 @@ describe('Balancer flow', () => {
|
||||
assert(parseFloat(poolShares) > parseFloat(newpoolShares))
|
||||
})
|
||||
|
||||
it('ALice should remove all liquidity', async () => {
|
||||
const aliceShares = await Pool.sharesBalance(alice, greatPool)
|
||||
const aliceDtBalance = await datatoken.balance(tokenAddress, alice)
|
||||
const aliceOceanBalance = await datatoken.balance(oceanTokenAddress, alice)
|
||||
await Pool.removePoolLiquidity(alice, greatPool, aliceShares)
|
||||
const newAliceDtBalance = await datatoken.balance(tokenAddress, alice)
|
||||
const newAliceOceanBalance = await datatoken.balance(oceanTokenAddress, alice)
|
||||
const newAliceShares = await Pool.sharesBalance(alice, greatPool)
|
||||
assert(parseFloat(aliceDtBalance) < parseFloat(newAliceDtBalance))
|
||||
assert(parseFloat(aliceOceanBalance) < parseFloat(newAliceOceanBalance))
|
||||
assert(parseFloat(aliceShares) > parseFloat(newAliceShares))
|
||||
})
|
||||
it('ALice should get all the pools that she created', async () => {
|
||||
const alicePools = await Pool.getPoolsbyCreator(alice)
|
||||
assert(alicePools.length > 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user