1
0
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:
lacoop6tu 2021-10-26 15:42:09 -05:00
parent 9176170bb2
commit d9a149bd5c
6 changed files with 1355 additions and 117 deletions

View File

@ -24,7 +24,8 @@
"release": "release-it --non-interactive",
"changelog": "auto-changelog -p",
"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: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'",

View File

@ -122,10 +122,36 @@ export class Router {
return await this.router.methods.isPoolTemplate(address).call()
}
/**
* Estimate gas cost for addOceanToken
* @param {String} address
* @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
* @param {String} tokenAddress template address to add
* @param {String} address caller address
* @param {String} tokenAddress token address to add
* @return {Promise<TransactionReceipt>}
*/
public async addOceanToken(
@ -136,15 +162,9 @@ export class Router {
throw new Error(`Caller is not Router Owner`)
}
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await this.router.methods
.addOceanToken(tokenAddress)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
const estGas = await this.estGasAddOceanToken(address,tokenAddress)
// Invoke createToken function of the contract
const trxReceipt = await this.router.methods.addOceanToken(tokenAddress).send({
@ -156,6 +176,33 @@ export class Router {
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
* @param {String} address
@ -170,15 +217,8 @@ export class Router {
throw new Error(`Caller is not Router Owner`)
}
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await this.router.methods
.removeOceanToken(tokenAddress)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
const estGas = await this.estGasRemoveOceanToken(address,tokenAddress)
// Invoke createToken function of the contract
const trxReceipt = await this.router.methods.removeOceanToken(tokenAddress).send({

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
}
}

View 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)
})
})