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

add more Pool methods and tests

This commit is contained in:
lacoop6tu 2021-10-28 12:42:55 -05:00
parent 6e135231d3
commit 5d54e41d8e
4 changed files with 1934 additions and 26562 deletions

28130
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -247,6 +247,38 @@ export class Pool {
return result
}
/**
* Get marketFeeCollector of this pool
* @param {String} poolAddress
* @return {String}
*/
async getMarketFeeCollector(poolAddress: string): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null
try {
result = await pool.methods._marketCollector().call()
} catch (e) {
this.logger.error(`ERROR: Failed to get marketFeeCollector address: ${e.message}`)
}
return result
}
/**
* Get OPF Collector of this pool
* @param {String} poolAddress
* @return {String}
*/
async getOPFCollector(poolAddress: string): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null
try {
result = await pool.methods._opfCollector().call()
} catch (e) {
this.logger.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)
}
return result
}
/**
* Get if a token is bounded to a pool
* @param {String} poolAddress
@ -370,6 +402,167 @@ export class Pool {
return weight
}
/**
* Get Market Fees available to be collected for a specific token
* @param {String} poolAddress
* @param {String} token token we want to check fees
* @return {String}
*/
async getMarketFees(poolAddress: string, token: string): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let weight = null
try {
const result = await pool.methods.marketFees(token).call()
weight = this.web3.utils.fromWei(result)
} catch (e) {
this.logger.error(`ERROR: Failed to get market fees for a token: ${e.message}`)
}
return weight
}
/**
* Get Community Fees available to be collected for a specific token
* @param {String} poolAddress
* @param {String} token token we want to check fees
* @return {String}
*/
async getCommunityFees(poolAddress: string, token: string): Promise<string> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let weight = null
try {
const result = await pool.methods.communityFees(token).call()
weight = this.web3.utils.fromWei(result)
} catch (e) {
this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`)
}
return weight
}
/**
* Estimate gas cost for collectOPF
* @param {String} address
* @param {String} poolAddress
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estCollectOPF(
address: string,
poolAddress: string,
contractInstance?: Contract
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.collectOPF()
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* collectOPF - collect opf fee - can be called by anyone
* @param {String} address
* @param {String} poolAddress
* @return {TransactionReceipt}
*/
async collectOPF(
address: string,
poolAddress: string
): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null
const estGas = await this.estCollectOPF(
address,
poolAddress
)
try {
result = await pool.methods
.collectOPF()
.send({
from: address,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
} catch (e) {
this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)
}
return result
}
/**
* Estimate gas cost for collectMarketFee
* @param {String} address
* @param {String} poolAddress
* @param {String} to address that will receive fees
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estCollectMarketFee(
address: string,
poolAddress: string,
to:string,
contractInstance?: Contract
) :Promise<number>{
const poolContract =
contractInstance ||
new this.web3.eth.Contract(this.poolABI as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.collectMarketFee(to)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* collectOPF - collect market fees - can be called by the marketFeeCollector
* @param {String} address
* @param {String} poolAddress
* @param {String} to address that will receive fees
* @return {TransactionReceipt}
*/
async collectMarketFee(
address: string,
poolAddress: string,
to: string
): Promise<TransactionReceipt> {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null
const estGas = await this.estCollectMarketFee(
address,
poolAddress,
to
)
try {
result = await pool.methods
.collectMarketFee(to)
.send({
from: address,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
} catch (e) {
this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)
}
return result
}
/**
* Estimate gas cost for swapExactAmountIn
* @param {String} address
@ -1089,7 +1282,7 @@ export class Pool {
// if (new Decimal(tokenAmountOut).gte(tokenBalanceOut)) return null
try {
const result = await pool.methods
.getAmountInExactOut(tokenIn, tokenOut, tokenAmountOut)
.getAmountInExactOut(tokenIn, tokenOut,this.web3.utils.toWei(tokenAmountOut))
.call()
amount = this.web3.utils.fromWei(result)
} catch (e) {
@ -1124,10 +1317,12 @@ export class Pool {
amountInFormatted = parseInt(tokenAmountIn) * 10 ** tokenInDecimals
}
let amount = null
console.log(amountInFormatted)
try {
const result = await pool.methods
.getAmountOutExactIn(tokenIn, tokenOut, amountInFormatted)
.call()
console.log(result)
if (tokenInDecimals == 18){
amount = this.web3.utils.fromWei(result)
}

View File

@ -2,8 +2,8 @@ import Web3 from 'web3'
import { Contract } from 'web3-eth-contract'
import { AbiItem } from 'web3-utils/types'
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
// TODO: add OPF deployment
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
const oceanAddress = '0x967da4048cd07ab37855c090aaf366e4ce1b9f48'
export class TestContractHandler {
public accounts: string[]
@ -29,6 +29,8 @@ export class TestContractHandler {
public PoolTemplateBytecode: string
public OPFCollectorBytecode: string
public MockERC20Bytecode: string
public OPFBytecode: string
public factory721Address: string
public template721Address: string
@ -54,6 +56,7 @@ export class TestContractHandler {
SideStakingABI?: AbiItem | AbiItem[],
FixedRateABI?: AbiItem | AbiItem[],
DispenserABI?: AbiItem | AbiItem[],
OPFABI?: AbiItem | AbiItem[],
template721Bytecode?: string,
template20Bytecode?: string,
@ -62,7 +65,8 @@ export class TestContractHandler {
routerBytecode?: string,
sideStakingBytecode?: string,
fixedRateBytecode?: string,
dispenserBytecode?: string
dispenserBytecode?: string,
opfBytecode?:string
) {
this.web3 = web3
this.ERC721Template = new this.web3.eth.Contract(ERC721TemplateABI)
@ -74,6 +78,7 @@ export class TestContractHandler {
this.FixedRate = new this.web3.eth.Contract(FixedRateABI)
this.Dispenser = new this.web3.eth.Contract(DispenserABI)
this.MockERC20 = new this.web3.eth.Contract(MockERC20.abi as AbiItem[])
this.OPFCollector = new this.web3.eth.Contract(OPFABI)
this.ERC721FactoryBytecode = factory721Bytecode
this.ERC20TemplateBytecode = template20Bytecode
@ -84,6 +89,7 @@ export class TestContractHandler {
this.FixedRateBytecode = fixedRateBytecode
this.DispenserBytecode = dispenserBytecode
this.MockERC20Bytecode = MockERC20.bytecode
this.OPFBytecode = opfBytecode
}
public async getAccounts(): Promise<string[]> {
@ -94,6 +100,30 @@ export class TestContractHandler {
public async deployContracts(owner: string, routerABI?: AbiItem | AbiItem[]) {
let estGas
// DEPLOY OPF Fee Collector
// get est gascost
estGas = await this.OPFCollector.deploy({
data: this.OPFBytecode,
arguments: [owner,owner]
}).estimateGas(function (err, estGas) {
if (err) console.log('DeployContracts: ' + err)
return estGas
})
// deploy the contract and get it's address
this.opfCollectorAddress = await this.OPFCollector.deploy({
data: this.OPFBytecode,
arguments: [owner,owner]
})
.send({
from: owner,
gas: estGas + 1,
gasPrice: '3000000000'
})
.then(function (contract) {
return contract.options.address
})
// DEPLOY POOL TEMPLATE
// get est gascost
estGas = await this.PoolTemplate.deploy({
@ -193,7 +223,7 @@ export class TestContractHandler {
owner,
this.oceanAddress,
this.poolTemplateAddress,
communityCollector,
this.opfCollectorAddress,
[]
]
}).estimateGas(function (err, estGas) {
@ -207,7 +237,7 @@ export class TestContractHandler {
owner,
this.oceanAddress,
this.poolTemplateAddress,
communityCollector,
this.opfCollectorAddress,
[]
]
})
@ -245,7 +275,7 @@ export class TestContractHandler {
// DEPLOY FIXED RATE
estGas = await this.FixedRate.deploy({
data: this.FixedRateBytecode,
arguments: [this.routerAddress, communityCollector]
arguments: [this.routerAddress, this.opfCollectorAddress]
}).estimateGas(function (err, estGas) {
if (err) console.log('DeployContracts: ' + err)
return estGas
@ -253,7 +283,7 @@ export class TestContractHandler {
// deploy the contract and get it's address
this.fixedRateAddress = await this.FixedRate.deploy({
data: this.FixedRateBytecode,
arguments: [this.routerAddress, communityCollector]
arguments: [this.routerAddress, this.opfCollectorAddress]
})
.send({
from: owner,
@ -292,7 +322,7 @@ export class TestContractHandler {
arguments: [
this.template721Address,
this.template20Address,
communityCollector,
this.opfCollectorAddress,
this.routerAddress
]
}).estimateGas(function (err, estGas) {
@ -305,7 +335,7 @@ export class TestContractHandler {
arguments: [
this.template721Address,
this.template20Address,
communityCollector,
this.opfCollectorAddress,
this.routerAddress
]
})
@ -378,7 +408,7 @@ export class TestContractHandler {
.send({ from: owner })
// TODO: add OPF deployment
// await RouterContract.methods
// .changeRouterOwner(communityCollector)
// .changeRouterOwner(this.opfCollectorAddress)
// .send({ from: owner })
}
}

View File

@ -12,9 +12,11 @@ import Dispenser from '@oceanprotocol/contracts/artifacts/contracts/pools/dispen
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 OPFCollector from '@oceanprotocol/contracts/artifacts/contracts/communityFee/OPFCommunityFeeCollector.sol/OPFCommunityFeeCollector.json'
import { LoggerInstance } from '../../../../src/utils'
import { NFTFactory } from '../../../../src/factories/NFTFactory'
import { Pool } from '../../../../src/pools/balancer/Pool'
import { CONNREFUSED } from 'dns'
const { keccak256 } = require('@ethersproject/keccak256')
const web3 = new Web3('http://127.0.0.1:8545')
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
@ -45,6 +47,7 @@ describe('Pool unit test', () => {
SideStaking.abi as AbiItem[],
FixedRate.abi as AbiItem[],
Dispenser.abi as AbiItem[],
OPFCollector.abi as AbiItem[],
ERC721Template.bytecode,
ERC20Template.bytecode,
@ -53,7 +56,8 @@ describe('Pool unit test', () => {
FactoryRouter.bytecode,
SideStaking.bytecode,
FixedRate.bytecode,
Dispenser.bytecode
Dispenser.bytecode,
OPFCollector.bytecode
)
await contracts.getAccounts()
factoryOwner = contracts.accounts[0]
@ -79,6 +83,7 @@ describe('Pool unit test', () => {
it('should initiate Pool instance', async () => {
pool = new Pool(web3, LoggerInstance, PoolTemplate.abi as AbiItem[])
})
it('#create a pool', async () => {
@ -371,4 +376,116 @@ describe('Pool unit test', () => {
// 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('#getAmountInExactOut- should get the amount in for exact out', async () => {
const maxBTPIn = "0.5"
const exactDAIOut = "1"
const tx = await pool.getAmountInExactOut(
poolAddress,
erc20Token,
contracts.daiAddress,
exactDAIOut
)
assert(tx != null)
console.log(tx)
const tx2 = await pool.getSpotPrice(poolAddress,erc20Token,contracts.daiAddress)
console.log(tx2)
})
it('#getAmountOutExactIn- should get the amount out for exact In', async () => {
const maxBTPIn = "0.5"
const exactDTIn= "1"
const tx = await pool.getAmountOutExactIn(
poolAddress,
erc20Token,
contracts.daiAddress,
exactDTIn
)
assert(tx != null)
console.log(tx)
const tx2 = await pool.getSpotPrice(poolAddress,erc20Token,contracts.daiAddress)
console.log(tx2)
})
it('#getSpotPrice- should get the sport price', async () => {
assert(await pool.getSpotPrice(poolAddress,erc20Token,contracts.daiAddress) != null)
assert(await pool.getSpotPrice(poolAddress,contracts.daiAddress,erc20Token) != null)
})
it('#getMarketFees- should get market fees for each token', async () => {
// we haven't performed any swap DT => DAI so there's no fee in erc20Token
// but there's a fee in DAI
assert(await pool.getMarketFees(poolAddress,erc20Token) == '0')
assert(await pool.getMarketFees(poolAddress,contracts.daiAddress) > '0')
})
it('#getCommunityFees- should get community fees for each token', async () => {
// we haven't performed any swap DT => DAI so there's no fee in erc20Token
// but there's a fee in DAI
assert(await pool.getCommunityFees(poolAddress,erc20Token) == '0')
assert(await pool.getCommunityFees(poolAddress,contracts.daiAddress) > '0')
})
it('#collectMarketFee- should get market fees for each token', async () => {
// contracts.accounts[0] is the marketFeeCollector
assert(await pool.getMarketFeeCollector(poolAddress) == contracts.accounts[0])
// user3 has no DAI (we are going to send DAI fee to him)
assert(await daiContract.methods.balanceOf(user3).call() == '0')
// only marketFeeCollector can call this, set user3 as receiver
await pool.collectMarketFee(contracts.accounts[0],poolAddress,user3)
// DAI fees have been collected
assert(await pool.getMarketFees(poolAddress,contracts.daiAddress) == '0')
// user3 got DAI
assert(await daiContract.methods.balanceOf(user3).call() > '0')
})
it('#getMarketFeeCollector- should get market fees for each token', async () => {
// contracts.accounts[0] is the marketFeeCollector
assert(await pool.getMarketFeeCollector(poolAddress) == contracts.accounts[0])
})
it('#getOPFCollector- should get market fees for each token', async () => {
// contracts.accounts[0] is the opfCollectorCollector
assert(await pool.getOPFCollector(poolAddress) == contracts.opfCollectorAddress)
})
it('#collectCommunityFee- should get community fees for each token', async () => {
// contracts.accounts[0] is the marketFeeCollector
// some fee are available in DAI
assert(await pool.getCommunityFees(poolAddress,contracts.daiAddress) > '0')
// opf collector has no DAI
assert(await daiContract.methods.balanceOf(contracts.opfCollectorAddress).call() == '0')
// anyone can call callectOPF
await pool.collectOPF(contracts.accounts[0],poolAddress)
// DAI fees have been collected
assert(await pool.getCommunityFees(poolAddress,contracts.daiAddress) == '0')
// OPF collector got DAI
assert(await daiContract.methods.balanceOf(contracts.opfCollectorAddress).call() > '0')
})
})