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:
parent
6e135231d3
commit
5d54e41d8e
28130
package-lock.json
generated
28130
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
}
|
||||
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
@ -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')
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user