mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
add initial Pool class and test
This commit is contained in:
parent
9176170bb2
commit
d9a149bd5c
@ -24,7 +24,8 @@
|
|||||||
"release": "release-it --non-interactive",
|
"release": "release-it --non-interactive",
|
||||||
"changelog": "auto-changelog -p",
|
"changelog": "auto-changelog -p",
|
||||||
"prepublishOnly": "npm run build",
|
"prepublishOnly": "npm run build",
|
||||||
"test:pool": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/Router.test.ts'",
|
"test:pool": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/balancer/Pool.test.ts'",
|
||||||
|
"test:router": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/Router.test.ts'",
|
||||||
"test:unit": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/**/*.test.ts'",
|
"test:unit": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/**/*.test.ts'",
|
||||||
"test:unit:cover": "nyc --report-dir coverage/unit npm run test:unit",
|
"test:unit:cover": "nyc --report-dir coverage/unit npm run test:unit",
|
||||||
"test:integration": "mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/**/*.test.ts'",
|
"test:integration": "mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/**/*.test.ts'",
|
||||||
|
@ -123,9 +123,35 @@ export class Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new token to oceanTokens list, pools with basetoken in this list have NO opf Fee
|
* Estimate gas cost for addOceanToken
|
||||||
* @param {String} address
|
* @param {String} address
|
||||||
* @param {String} tokenAddress template address to add
|
* @param {String} tokenAddress token address we want to add
|
||||||
|
* @param {Contract} routerContract optional contract instance
|
||||||
|
* @return {Promise<any>}
|
||||||
|
*/
|
||||||
|
public async estGasAddOceanToken(
|
||||||
|
address: string,
|
||||||
|
tokenAddress: string,
|
||||||
|
contractInstance?: Contract
|
||||||
|
) {
|
||||||
|
const routerContract =
|
||||||
|
contractInstance || this.router
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await routerContract.methods
|
||||||
|
.addOceanToken(tokenAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
return estGas
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Add a new token to oceanTokens list, pools with basetoken in this list have NO opf Fee
|
||||||
|
* @param {String} address caller address
|
||||||
|
* @param {String} tokenAddress token address to add
|
||||||
* @return {Promise<TransactionReceipt>}
|
* @return {Promise<TransactionReceipt>}
|
||||||
*/
|
*/
|
||||||
public async addOceanToken(
|
public async addOceanToken(
|
||||||
@ -136,15 +162,9 @@ export class Router {
|
|||||||
throw new Error(`Caller is not Router Owner`)
|
throw new Error(`Caller is not Router Owner`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
|
||||||
let estGas
|
const estGas = await this.estGasAddOceanToken(address,tokenAddress)
|
||||||
try {
|
|
||||||
estGas = await this.router.methods
|
|
||||||
.addOceanToken(tokenAddress)
|
|
||||||
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
|
||||||
} catch (e) {
|
|
||||||
estGas = gasLimitDefault
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke createToken function of the contract
|
// Invoke createToken function of the contract
|
||||||
const trxReceipt = await this.router.methods.addOceanToken(tokenAddress).send({
|
const trxReceipt = await this.router.methods.addOceanToken(tokenAddress).send({
|
||||||
@ -156,6 +176,33 @@ export class Router {
|
|||||||
return trxReceipt
|
return trxReceipt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimate gas cost for removeOceanToken
|
||||||
|
* @param {String} address caller address
|
||||||
|
* @param {String} tokenAddress token address we want to add
|
||||||
|
* @param {Contract} routerContract optional contract instance
|
||||||
|
* @return {Promise<any>}
|
||||||
|
*/
|
||||||
|
public async estGasRemoveOceanToken(
|
||||||
|
address: string,
|
||||||
|
tokenAddress: string,
|
||||||
|
contractInstance?: Contract
|
||||||
|
) {
|
||||||
|
const routerContract =
|
||||||
|
contractInstance || this.router
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await routerContract.methods
|
||||||
|
.removeOceanToken(tokenAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
return estGas
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a token from oceanTokens list, pools without basetoken in this list have a opf Fee
|
* Remove a token from oceanTokens list, pools without basetoken in this list have a opf Fee
|
||||||
* @param {String} address
|
* @param {String} address
|
||||||
@ -170,15 +217,8 @@ export class Router {
|
|||||||
throw new Error(`Caller is not Router Owner`)
|
throw new Error(`Caller is not Router Owner`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
const estGas = await this.estGasRemoveOceanToken(address,tokenAddress)
|
||||||
let estGas
|
|
||||||
try {
|
|
||||||
estGas = await this.router.methods
|
|
||||||
.removeOceanToken(tokenAddress)
|
|
||||||
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
|
||||||
} catch (e) {
|
|
||||||
estGas = gasLimitDefault
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke createToken function of the contract
|
// Invoke createToken function of the contract
|
||||||
const trxReceipt = await this.router.methods.removeOceanToken(tokenAddress).send({
|
const trxReceipt = await this.router.methods.removeOceanToken(tokenAddress).send({
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
import Web3 from 'web3'
|
|
||||||
import { AbiItem } from 'web3-utils'
|
|
||||||
import { Contract } from 'web3-eth-contract'
|
|
||||||
import defaultPoolABI from '@oceanprotocol/contracts/artifacts/contracts/interfaces/IPool.sol/IPool.json'
|
|
||||||
import defaultERC20ABI from '@oceanprotocol/contracts/artifacts/contracts/interfaces/IERC20.sol/IERC20.json'
|
|
||||||
import { PoolFactory } from './PoolFactory'
|
|
||||||
import { Logger } from '../../utils'
|
|
||||||
|
|
||||||
export class OceanPool extends PoolFactory {
|
|
||||||
public oceanAddress: string = null
|
|
||||||
public dtAddress: string = null
|
|
||||||
public startBlock: number
|
|
||||||
public vaultABI: AbiItem | AbiItem[]
|
|
||||||
public vaultAddress: string
|
|
||||||
public vault: Contract
|
|
||||||
public poolABI: AbiItem | AbiItem[]
|
|
||||||
public erc20ABI: AbiItem | AbiItem[]
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
web3: Web3,
|
|
||||||
logger: Logger,
|
|
||||||
routerAddress: string = null,
|
|
||||||
oceanAddress: string = null,
|
|
||||||
startBlock?: number
|
|
||||||
) {
|
|
||||||
super(web3, logger, routerAddress)
|
|
||||||
|
|
||||||
this.poolABI = defaultPoolABI.abi as AbiItem[]
|
|
||||||
this.erc20ABI = defaultERC20ABI.abi as AbiItem[]
|
|
||||||
this.vault = new this.web3.eth.Contract(this.vaultABI, this.vaultAddress)
|
|
||||||
|
|
||||||
// if (oceanAddress) {
|
|
||||||
// this.oceanAddress = oceanAddress
|
|
||||||
// }
|
|
||||||
if (startBlock) this.startBlock = startBlock
|
|
||||||
else this.startBlock = 0
|
|
||||||
}
|
|
||||||
}
|
|
1133
src/pools/balancer/Pool.ts
Normal file
1133
src/pools/balancer/Pool.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,58 +0,0 @@
|
|||||||
import Web3 from 'web3'
|
|
||||||
import { AbiItem } from 'web3-utils'
|
|
||||||
import { Contract } from 'web3-eth-contract'
|
|
||||||
import defaultRouterABI from '@oceanprotocol/contracts/artifacts/contracts/interfaces/IFactoryRouter.sol/IFactoryRouter.json'
|
|
||||||
import { Logger } from '../../utils'
|
|
||||||
import { TransactionReceipt } from 'web3-eth'
|
|
||||||
|
|
||||||
export class PoolFactory {
|
|
||||||
public GASLIMIT_DEFAULT = 1000000
|
|
||||||
public web3: Web3 = null
|
|
||||||
public routerABI: AbiItem | AbiItem[]
|
|
||||||
|
|
||||||
public routerAddress: string
|
|
||||||
|
|
||||||
public logger: Logger
|
|
||||||
public router: Contract
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiate PoolFactory.
|
|
||||||
* @param {String} routerAddress
|
|
||||||
* @param {AbiItem | AbiItem[]} routerABI
|
|
||||||
* @param {Web3} web3
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
web3: Web3,
|
|
||||||
logger: Logger,
|
|
||||||
routerAddress: string,
|
|
||||||
routerABI?: AbiItem | AbiItem[]
|
|
||||||
) {
|
|
||||||
this.web3 = web3
|
|
||||||
this.routerAddress = routerAddress
|
|
||||||
this.routerABI = routerABI || (defaultRouterABI.abi as AbiItem[])
|
|
||||||
this.logger = logger
|
|
||||||
this.router = new this.web3.eth.Contract(this.routerABI, this.routerAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async deployPool(
|
|
||||||
account: string,
|
|
||||||
tokens: string[],
|
|
||||||
weightsInWei: string[],
|
|
||||||
swapFeePercentage: number,
|
|
||||||
swapMarketFee: number,
|
|
||||||
owner: string
|
|
||||||
): Promise<TransactionReceipt> {
|
|
||||||
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
|
||||||
let estGas
|
|
||||||
try {
|
|
||||||
estGas = await this.router.methods
|
|
||||||
.deployPool(tokens, weightsInWei, swapFeePercentage, swapMarketFee, owner)
|
|
||||||
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.log('Error estimate gas deployPool')
|
|
||||||
this.logger.log(e)
|
|
||||||
estGas = gasLimitDefault
|
|
||||||
}
|
|
||||||
return estGas
|
|
||||||
}
|
|
||||||
}
|
|
160
test/unit/pools/balancer/Pool.test.ts
Normal file
160
test/unit/pools/balancer/Pool.test.ts
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import { assert, expect } from 'chai'
|
||||||
|
import { AbiItem } from 'web3-utils/types'
|
||||||
|
import { TestContractHandler } from '../../../TestContractHandler'
|
||||||
|
import Web3 from 'web3'
|
||||||
|
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
|
||||||
|
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
|
||||||
|
import SideStaking from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
|
||||||
|
import FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
|
||||||
|
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||||
|
import Dispenser from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
|
||||||
|
import FixedRate from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'
|
||||||
|
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
||||||
|
import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
|
||||||
|
import { LoggerInstance } from '../../../../src/utils'
|
||||||
|
import { NFTFactory } from '../../../../src/factories/NFTFactory'
|
||||||
|
import { Pool } from '../../../../src/pools/balancer/Pool'
|
||||||
|
const { keccak256 } = require('@ethersproject/keccak256')
|
||||||
|
const web3 = new Web3('http://127.0.0.1:8545')
|
||||||
|
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
|
||||||
|
|
||||||
|
describe('Pool unit test', () => {
|
||||||
|
let factoryOwner: string
|
||||||
|
let nftOwner: string
|
||||||
|
let user1: string
|
||||||
|
let user2: string
|
||||||
|
let user3: string
|
||||||
|
let contracts: TestContractHandler
|
||||||
|
let pool: Pool
|
||||||
|
let dtAddress: string
|
||||||
|
let dtAddress2: string
|
||||||
|
let poolAddress: string
|
||||||
|
let erc20Token: string
|
||||||
|
|
||||||
|
it('should deploy contracts', async () => {
|
||||||
|
contracts = new TestContractHandler(
|
||||||
|
web3,
|
||||||
|
ERC721Template.abi as AbiItem[],
|
||||||
|
ERC20Template.abi as AbiItem[],
|
||||||
|
PoolTemplate.abi as AbiItem[],
|
||||||
|
ERC721Factory.abi as AbiItem[],
|
||||||
|
FactoryRouter.abi as AbiItem[],
|
||||||
|
SideStaking.abi as AbiItem[],
|
||||||
|
FixedRate.abi as AbiItem[],
|
||||||
|
Dispenser.abi as AbiItem[],
|
||||||
|
|
||||||
|
ERC721Template.bytecode,
|
||||||
|
ERC20Template.bytecode,
|
||||||
|
PoolTemplate.bytecode,
|
||||||
|
ERC721Factory.bytecode,
|
||||||
|
FactoryRouter.bytecode,
|
||||||
|
SideStaking.bytecode,
|
||||||
|
FixedRate.bytecode,
|
||||||
|
Dispenser.bytecode
|
||||||
|
)
|
||||||
|
await contracts.getAccounts()
|
||||||
|
factoryOwner = contracts.accounts[0]
|
||||||
|
nftOwner = contracts.accounts[1]
|
||||||
|
user1 = contracts.accounts[2]
|
||||||
|
user2 = contracts.accounts[3]
|
||||||
|
user3 = contracts.accounts[4]
|
||||||
|
|
||||||
|
await contracts.deployContracts(factoryOwner, FactoryRouter.abi as AbiItem[])
|
||||||
|
|
||||||
|
const daiContract = new web3.eth.Contract(
|
||||||
|
contracts.MockERC20.options.jsonInterface,
|
||||||
|
contracts.daiAddress
|
||||||
|
)
|
||||||
|
await daiContract.methods
|
||||||
|
.approve(contracts.factory721Address, web3.utils.toWei('10000'))
|
||||||
|
.send({ from: contracts.accounts[0] })
|
||||||
|
|
||||||
|
expect(await daiContract.methods.balanceOf(contracts.accounts[0]).call()).to.equal(
|
||||||
|
web3.utils.toWei('100000')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should initiate Pool instance', async () => {
|
||||||
|
pool = new Pool(web3, LoggerInstance,PoolTemplate.abi as AbiItem[])
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
it('#create a pool', async () => {
|
||||||
|
// CREATE A POOL
|
||||||
|
// we prepare transaction parameters objects
|
||||||
|
const nftData = {
|
||||||
|
name: '72120Bundle',
|
||||||
|
symbol: '72Bundle',
|
||||||
|
templateIndex: 1,
|
||||||
|
baseURI: 'https://oceanprotocol.com/nft/'
|
||||||
|
}
|
||||||
|
const ercData = {
|
||||||
|
templateIndex: 1,
|
||||||
|
strings: ['ERC20B1', 'ERC20DT1Symbol'],
|
||||||
|
addresses: [
|
||||||
|
contracts.accounts[0],
|
||||||
|
user3,
|
||||||
|
contracts.accounts[0],
|
||||||
|
'0x0000000000000000000000000000000000000000'
|
||||||
|
],
|
||||||
|
uints: [web3.utils.toWei('1000000'), 0],
|
||||||
|
bytess: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const poolData = {
|
||||||
|
addresses: [
|
||||||
|
contracts.sideStakingAddress,
|
||||||
|
contracts.daiAddress,
|
||||||
|
contracts.factory721Address,
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.poolTemplateAddress
|
||||||
|
],
|
||||||
|
ssParams: [
|
||||||
|
web3.utils.toWei('1'), // rate
|
||||||
|
18, // basetokenDecimals
|
||||||
|
web3.utils.toWei('10000'),
|
||||||
|
2500000, // vested blocks
|
||||||
|
web3.utils.toWei('2000') // baseToken initial pool liquidity
|
||||||
|
],
|
||||||
|
swapFees: [
|
||||||
|
1e15, //
|
||||||
|
1e15
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const nftFactory = new NFTFactory(contracts.factory721Address, web3, LoggerInstance)
|
||||||
|
|
||||||
|
const txReceipt = await nftFactory.createNftErcWithPool(
|
||||||
|
contracts.accounts[0],
|
||||||
|
nftData,
|
||||||
|
ercData,
|
||||||
|
poolData
|
||||||
|
)
|
||||||
|
|
||||||
|
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
|
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const 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('#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)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user