From 5072bdbb5a756ddc2e55e60015805f9e45076d80 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Fri, 29 Oct 2021 12:54:35 +0300 Subject: [PATCH 1/9] integrated dispenser class, added some unit tests --- src/pools/dispenser/Dispenser.ts | 406 ++++++++++++++++++++++++++++++ test/unit/pools/Dispenser.test.ts | 129 ++++++++++ 2 files changed, 535 insertions(+) create mode 100644 test/unit/pools/Dispenser.test.ts diff --git a/src/pools/dispenser/Dispenser.ts b/src/pools/dispenser/Dispenser.ts index 0c982d3f..094519f6 100644 --- a/src/pools/dispenser/Dispenser.ts +++ b/src/pools/dispenser/Dispenser.ts @@ -1,6 +1,412 @@ import Web3 from 'web3' +import { AbiItem } from 'web3-utils' +import { Contract } from 'web3-eth-contract' +import { TransactionReceipt } from 'web3-eth' +import defaultDispenserABI from '@oceanprotocol/contracts/pools/dispenser/Dispenser.json' +import { LoggerInstance as logger, getFairGasPrice } from '../../utils/' + +export interface DispenserToken { + active: boolean + owner: string + maxTokens: string + maxBalance: string + balance: string + minterApproved: boolean + isTrueMinter: boolean + allowedSwapper: string +} export class Dispenser { public GASLIMIT_DEFAULT = 1000000 public web3: Web3 = null + public dispenserAddress: string + public startBlock: number + public dispenserABI: AbiItem | AbiItem[] + public dispenserContract: Contract + + /** + * Instantiate Dispenser + * @param {any} web3 + * @param {String} dispenserAddress + * @param {any} dispenserABI + */ + constructor( + web3: Web3, + dispenserAddress: string = null, + dispenserABI: AbiItem | AbiItem[] = null, + startBlock?: number + ) { + this.web3 = web3 + this.dispenserAddress = dispenserAddress + if (startBlock) this.startBlock = startBlock + else this.startBlock = 0 + this.dispenserABI = dispenserABI || (defaultDispenserABI.abi as AbiItem[]) + if (web3) + this.dispenserContract = new this.web3.eth.Contract( + this.dispenserABI, + this.dispenserAddress + ) + } + + /** + * Get information about a datatoken dispenser + * @param {String} dtAddress + * @return {Promise} Exchange details + */ + public async status(dtAdress: string): Promise { + try { + const result: DispenserToken = await this.dispenserContract.methods + .status(dtAdress) + .call() + result.maxTokens = this.web3.utils.fromWei(result.maxTokens) + result.maxBalance = this.web3.utils.fromWei(result.maxBalance) + result.balance = this.web3.utils.fromWei(result.balance) + return result + } catch (e) { + logger.warn(`No dispenser available for data token: ${dtAdress}`) + } + return null + } + + /** + * Estimate gas cost for create method + * @param {String} dtAddress Datatoken address + * @param {String} address Owner address + * @param {String} maxTokens max tokens to dispense + * @param {String} maxBalance max balance of requester + * @param {String} allowedSwapper if !=0, only this address can request DTs + * @return {Promise} + */ + public async estGasCreate( + dtAddress: string, + address: string, + maxTokens: string, + maxBalance: string, + allowedSwapper: string + ): Promise { + const gasLimitDefault = this.GASLIMIT_DEFAULT + let estGas + try { + estGas = await this.dispenserContract.methods + .create( + dtAddress, + this.web3.utils.toWei(maxTokens), + this.web3.utils.toWei(maxBalance), + address, + allowedSwapper + ) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + + return estGas + } + + /** + * Creates a new Dispenser + * @param {String} dtAddress Datatoken address + * @param {String} address Owner address + * @param {String} maxTokens max tokens to dispense + * @param {String} maxBalance max balance of requester + * @param {String} allowedSwapper only account that can ask tokens. set address(0) if not required + * @return {Promise} transactionId + */ + public async create( + dtAddress: string, + address: string, + maxTokens: string, + maxBalance: string, + allowedSwapper: string + ): Promise { + const estGas = await this.estGasCreateDispenser( + dtAddress, + address, + maxTokens, + maxBalance, + allowedSwapper + ) + + // Call createFixedRate contract method + const trxReceipt = await this.dispenserContract.methods + .create( + dtAddress, + this.web3.utils.toWei(maxTokens), + this.web3.utils.toWei(maxBalance), + address, + allowedSwapper + ) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) + return trxReceipt + } + + /** + * Estimate gas for activate method + * @param {String} dtAddress + * @param {Number} maxTokens max amount of tokens to dispense + * @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected + * @param {String} address User address (must be owner of the dataToken) + * @return {Promise} + */ + public async estGasActivate( + dtAddress: string, + maxTokens: string, + maxBalance: string, + address: string + ): Promise { + let estGas + const gasLimitDefault = this.GASLIMIT_DEFAULT + try { + estGas = await this.dispenserContract.methods + .activate( + dtAddress, + this.web3.utils.toWei(maxTokens), + this.web3.utils.toWei(maxBalance) + ) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + return estGas + } + + /** + * Activates a new dispener. + * @param {String} dtAddress refers to datatoken address. + * @param {Number} maxTokens max amount of tokens to dispense + * @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected + * @param {String} address User address (must be owner of the dataToken) + * @return {Promise} TransactionReceipt + */ + public async activate( + dtAddress: string, + maxTokens: string, + maxBalance: string, + address: string + ): Promise { + try { + const estGas = await this.estGasActivate(dtAddress, maxTokens, maxBalance, address) + const trxReceipt = await this.dispenserContract.methods + .activate( + dtAddress, + this.web3.utils.toWei(maxTokens), + this.web3.utils.toWei(maxBalance) + ) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) + return trxReceipt + } catch (e) { + logger.error(`ERROR: Failed to activate dispenser: ${e.message}`) + } + return null + } + + /** + * Estimate gas for deactivate method + * @param {String} dtAddress + * @param {String} address User address (must be owner of the dataToken) + * @return {Promise} + */ + public async estGasDeactivate(dtAddress: string, address: string): Promise { + let estGas + const gasLimitDefault = this.GASLIMIT_DEFAULT + try { + estGas = await this.dispenserContract.methods + .deactivate(dtAddress) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + return estGas + } + + /** + * Deactivate an existing dispenser. + * @param {String} dtAddress refers to datatoken address. + * @param {String} address User address (must be owner of the dataToken) + * @return {Promise} TransactionReceipt + */ + public async deactivate( + dtAddress: string, + address: string + ): Promise { + try { + const estGas = await this.estGasDeactivate(dtAddress, address) + const trxReceipt = await this.dispenserContract.methods.deactivate(dtAddress).send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) + return trxReceipt + } catch (e) { + logger.error(`ERROR: Failed to activate dispenser: ${e.message}`) + } + return null + } + + /** + * Estimate gas for setAllowedSwapper method + * @param {String} dtAddress refers to datatoken address. + * @param {String} address User address (must be owner of the dataToken) + * @param {String} newAllowedSwapper refers to the new allowedSwapper + * @return {Promise} + */ + public async estGasSetAllowedSwapper( + dtAddress: string, + address: string, + newAllowedSwapper: string + ): Promise { + let estGas + const gasLimitDefault = this.GASLIMIT_DEFAULT + try { + estGas = await this.dispenserContract.methods + .setAllowedSwapper(dtAddress, newAllowedSwapper) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + return estGas + } + + /** + * Sets a new allowedSwapper. + * @param {String} dtAddress refers to datatoken address. + * @param {String} address User address (must be owner of the dataToken) + * @param {String} newAllowedSwapper refers to the new allowedSwapper + * @return {Promise} TransactionReceipt + */ + public async setAllowedSwapper( + dtAddress: string, + address: string, + newAllowedSwapper: string + ): Promise { + try { + const estGas = await this.estGasSetAllowedSwapper( + dtAddress, + address, + newAllowedSwapper + ) + const trxReceipt = await this.dispenserContract.methods + .setAllowedSwapper(dtAddress, newAllowedSwapper) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) + return trxReceipt + } catch (e) { + logger.error(`ERROR: Failed to activate dispenser: ${e.message}`) + } + return null + } + + /** + * Estimate gas for dispense method + * @param {String} dtAddress refers to datatoken address. + * @param {String} address User address (must be owner of the dataToken) + * @param {String} newAllowedSwapper refers to the new allowedSwapper + * @return {Promise} + */ + public async estGasDispense( + dtAddress: string, + address: string, + amount: string = '1', + destination: string + ): Promise { + let estGas + const gasLimitDefault = this.GASLIMIT_DEFAULT + try { + estGas = await this.dispenserContract.methods + .dispense(dtAddress, this.web3.utils.toWei(amount), destination) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + return estGas + } + + /** + * Dispense datatokens to caller. + * The dispenser must be active, hold enough DT (or be able to mint more) + * and respect maxTokens/maxBalance requirements + * @param {String} dtAddress refers to datatoken address. + * @param {String} address User address + * @param {String} amount amount of datatokens required. + * @param {String} destination who will receive the tokens + * @return {Promise} TransactionReceipt + */ + public async dispense( + dtAddress: string, + address: string, + amount: string = '1', + destination: string + ): Promise { + const estGas = await this.estGasDispense(dtAddress, address, amount, destination) + try { + const trxReceipt = await this.dispenserContract.methods + .dispense(dtAddress, this.web3.utils.toWei(amount), destination) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) + return trxReceipt + } catch (e) { + logger.error(`ERROR: Failed to dispense tokens: ${e.message}`) + } + return null + } + + /** + * Estimate gas for ownerWithdraw method + * @param {String} dtAddress refers to datatoken address. + * @param {String} address User address (must be owner of the dataToken) + * @param {String} newAllowedSwapper refers to the new allowedSwapper + * @return {Promise} + */ + public async estGasOwnerWithdraw(dtAddress: string, address: string): Promise { + let estGas + const gasLimitDefault = this.GASLIMIT_DEFAULT + try { + estGas = await this.dispenserContract.methods + .ownerWithdraw(dtAddress) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + return estGas + } + + /** + * Withdraw all tokens from the dispenser + * @param {String} dtAddress refers to datatoken address. + * @param {String} address User address (must be owner of the dispenser) + * @return {Promise} TransactionReceipt + */ + public async ownerWithdraw( + dtAddress: string, + address: string + ): Promise { + const estGas = await this.estGasOwnerWithdraw(dtAddress, address) + try { + const trxReceipt = await this.dispenserContract.methods + .ownerWithdraw(dtAddress) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) + return trxReceipt + } catch (e) { + logger.error(`ERROR: Failed to withdraw tokens: ${e.message}`) + } + return null + } } diff --git a/test/unit/pools/Dispenser.test.ts b/test/unit/pools/Dispenser.test.ts new file mode 100644 index 00000000..0d3ac239 --- /dev/null +++ b/test/unit/pools/Dispenser.test.ts @@ -0,0 +1,129 @@ +import Web3 from 'web3' +import { AbiItem, AbiInput } from 'web3-utils' +import { assert, expect } from 'chai' +import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' +import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json' +import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json' +import FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json' +import DispenserTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json' +import { LoggerInstance } from '.../../../src/utils' +import { Dispenser } from '.../../../src/pools/dispenser/' +import { NFTFactory } from '.../../../src/factories/' +import { Datatoken } from '.../../../src/datatokens/' +import { TestContractHandler } from '../../TestContractHandler' + +const web3 = new Web3('http://127.0.0.1:8545') + +describe('Dispenser flow', () => { + let factoryOwner: string + let nftOwner: string + let user1: string + let user2: string + let user3: string + let contracts: TestContractHandler + let DispenserAddress: string + let DispenserClass: Dispenser + let nftFactory: NFTFactory + let datatoken: Datatoken + let nftAddress: string + let dtAddress: string + + it('should deploy contracts', async () => { + contracts = new TestContractHandler( + web3, + ERC721Template.abi as AbiItem, + ERC20Template.abi as AbiItem, + null, + ERC721Factory.abi as AbiItem, + null, + null, + null, + DispenserTemplate.abi as AbiItem, + ERC721Template.bytecode, + ERC20Template.bytecode, + null, + ERC721Factory.bytecode, + FactoryRouter.bytecode, + null, + null, + DispenserTemplate.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[]) + }) + + it('should initialize Dispenser class', async () => { + DispenserClass = new Dispenser( + web3, + DispenserAddress, + DispenserTemplate.abi as AbiItem[] + ) + assert(DispenserClass !== null) + }) + + it('#createNftwithErc - should create an NFT and a Datatoken ', async () => { + nftFactory = new NFTFactory(contracts.factory721Address, web3, LoggerInstance) + + 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, + user2, + '0x0000000000000000000000000000000000000000' + ], + uints: [web3.utils.toWei('10000'), 0], + bytess: [] + } + + const txReceipt = await nftFactory.createNftWithErc( + contracts.accounts[0], + nftData, + ercData + ) + + expect(txReceipt.events.NFTCreated.event === 'NFTCreated') + expect(txReceipt.events.TokenCreated.event === 'TokenCreated') + + nftAddress = txReceipt.events.NFTCreated.returnValues.newTokenAddress + dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress + }) + + it('Make user2 minter', async () => { + datatoken = new Datatoken(web3, ERC20Template.abi as AbiItem) + await datatoken.addMinter(dtAddress, nftOwner, user2) + assert((await datatoken.getDTPermissions(dtAddress, user2)).minter === true) + }) + + it('user2 creates a dispenser', async () => { + const tx = await DispenserClass.activate(dtAddress, '1', '1', user2) + assert(tx, 'Cannot activate dispenser') + }) + + it('user2 gets the dispenser status', async () => { + const status = await DispenserClass.status(dtAddress) + assert(status.active === true, 'Dispenser not active') + assert(status.owner === user2, 'Dispenser owner is not alice') + assert(status.minterApproved === true, 'Dispenser is not a minter') + }) + + it('user2 deactivates the dispenser', async () => { + const tx = await DispenserClass.deactivate(dtAddress, user2) + assert(tx, 'Cannot deactivate dispenser') + const status = await DispenserClass.status(dtAddress) + assert(status.active === false, 'Dispenser is still active') + }) +}) From 80426fd2310dbdc06982faa9041f4a76d066bf9d Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Fri, 29 Oct 2021 16:16:55 +0300 Subject: [PATCH 2/9] added more tests and isDispensable method --- src/pools/dispenser/Dispenser.ts | 33 ++++++++++++++++++++++++++++++- test/unit/pools/Dispenser.test.ts | 26 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/pools/dispenser/Dispenser.ts b/src/pools/dispenser/Dispenser.ts index 094519f6..e09a7786 100644 --- a/src/pools/dispenser/Dispenser.ts +++ b/src/pools/dispenser/Dispenser.ts @@ -2,8 +2,10 @@ import Web3 from 'web3' import { AbiItem } from 'web3-utils' import { Contract } from 'web3-eth-contract' import { TransactionReceipt } from 'web3-eth' +import Decimal from 'decimal.js' import defaultDispenserABI from '@oceanprotocol/contracts/pools/dispenser/Dispenser.json' import { LoggerInstance as logger, getFairGasPrice } from '../../utils/' +import { Datatoken } from '.../../../src/datatokens/' export interface DispenserToken { active: boolean @@ -119,7 +121,7 @@ export class Dispenser { maxBalance: string, allowedSwapper: string ): Promise { - const estGas = await this.estGasCreateDispenser( + const estGas = await this.estGasCreate( dtAddress, address, maxTokens, @@ -409,4 +411,33 @@ export class Dispenser { } return null } + + /** + * Check if tokens can be dispensed + * @param {String} dtAddress + * @param {String} address User address that will receive datatokens + * @param {String} amount amount of datatokens required. + * @return {Promise} + */ + public async isDispensable( + dtAddress: string, + dataToken: Datatoken, + address: string, + amount: string = '1' + ): Promise { + const status = await this.status(dtAddress) + if (!status) return false + // check active + if (status.active === false) return false + // check maxBalance + const userBalance = new Decimal(await dataToken.balance(dataToken, address)) + if (userBalance.greaterThanOrEqualTo(status.maxBalance)) return false + // check maxAmount + if (new Decimal(String(amount)).greaterThan(status.maxTokens)) return false + // check dispenser balance + const contractBalance = new Decimal(status.balance) + if (contractBalance.greaterThanOrEqualTo(amount) || status.isTrueMinter === true) + return true + return false + } } diff --git a/test/unit/pools/Dispenser.test.ts b/test/unit/pools/Dispenser.test.ts index 0d3ac239..ae7f4f00 100644 --- a/test/unit/pools/Dispenser.test.ts +++ b/test/unit/pools/Dispenser.test.ts @@ -126,4 +126,30 @@ describe('Dispenser flow', () => { const status = await DispenserClass.status(dtAddress) assert(status.active === false, 'Dispenser is still active') }) + + it('user2 sets user3 as an AllowedSwapper for the dispenser', async () => { + const tx = await DispenserClass.setAllowedSwapper(dtAddress, user2, user3) + assert(tx, 'Cannot deactivate dispenser') + const status = await DispenserClass.status(dtAddress) + assert(status.allowedSwapper === user3, 'Dispenser is still active') + }) + + it('User3 requests datatokens', async () => { + const check = await DispenserClass.isDispensable(dtAddress, datatoken, user3, '1') + assert(check === true, 'isDispensable should return true') + const tx = await DispenserClass.dispense(dtAddress, user3, '1', user3) + assert(tx, 'user3 failed to get 1DT') + }) + + it('tries to withdraw all datatokens', async () => { + const tx = await DispenserClass.ownerWithdraw(dtAddress, user3) + assert(tx === null, 'Request should fail') + }) + + it('user2 withdraws all datatokens', async () => { + const tx = await DispenserClass.ownerWithdraw(dtAddress, user2) + assert(tx, 'user2 failed to withdraw all her tokens') + const status = await DispenserClass.status(dtAddress) + assert(status.balance === '0', 'Balance > 0') + }) }) From 304bcd28b42af4053d1dd59498fc565763325360 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Tue, 9 Nov 2021 14:43:09 +0200 Subject: [PATCH 3/9] fixed lint --- src/pools/dispenser/Dispenser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pools/dispenser/Dispenser.ts b/src/pools/dispenser/Dispenser.ts index e09a7786..e14516b9 100644 --- a/src/pools/dispenser/Dispenser.ts +++ b/src/pools/dispenser/Dispenser.ts @@ -3,7 +3,7 @@ import { AbiItem } from 'web3-utils' import { Contract } from 'web3-eth-contract' import { TransactionReceipt } from 'web3-eth' import Decimal from 'decimal.js' -import defaultDispenserABI from '@oceanprotocol/contracts/pools/dispenser/Dispenser.json' +import defaultDispenserABI from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json' import { LoggerInstance as logger, getFairGasPrice } from '../../utils/' import { Datatoken } from '.../../../src/datatokens/' @@ -430,7 +430,7 @@ export class Dispenser { // check active if (status.active === false) return false // check maxBalance - const userBalance = new Decimal(await dataToken.balance(dataToken, address)) + const userBalance = new Decimal(await dataToken.balance(dtAddress, address)) if (userBalance.greaterThanOrEqualTo(status.maxBalance)) return false // check maxAmount if (new Decimal(String(amount)).greaterThan(status.maxTokens)) return false From 86a996184f7b6dfe3eb9b8afaacff3aa9b3052f0 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 11 Nov 2021 14:36:01 +0200 Subject: [PATCH 4/9] test unit test updates --- package.json | 1 + .../pools/{ => dispenser}/Dispenser.test.ts | 91 +++++++++++-------- 2 files changed, 56 insertions(+), 36 deletions(-) rename test/unit/pools/{ => dispenser}/Dispenser.test.ts (67%) diff --git a/package.json b/package.json index a5c64089..632a4014 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "test:ss": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/ssContracts/SideStaking.test.ts'", "test:fixed": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/fixedRate/FixedRateExchange.test.ts'", "test:pool": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/balancer/Pool.test.ts'", + "test:dispenser": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/dispenser/Dispenser.test.ts'", "test:dt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/Datatoken.test.ts'", "test:nftDt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/NFTDatatoken.test.ts'", "test:router": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/Router.test.ts'", diff --git a/test/unit/pools/Dispenser.test.ts b/test/unit/pools/dispenser/Dispenser.test.ts similarity index 67% rename from test/unit/pools/Dispenser.test.ts rename to test/unit/pools/dispenser/Dispenser.test.ts index ae7f4f00..e8dd013a 100644 --- a/test/unit/pools/Dispenser.test.ts +++ b/test/unit/pools/dispenser/Dispenser.test.ts @@ -3,14 +3,19 @@ import { AbiItem, AbiInput } from 'web3-utils' import { assert, expect } from 'chai' import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json' -import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.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 DispenserTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json' -import { LoggerInstance } from '.../../../src/utils' -import { Dispenser } from '.../../../src/pools/dispenser/' -import { NFTFactory } from '.../../../src/factories/' -import { Datatoken } from '.../../../src/datatokens/' -import { TestContractHandler } from '../../TestContractHandler' +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 { NFTFactory, NFTCreateData } from '../../../../src/factories/' +import { Datatoken } from '../../../../src/datatokens/' +import { Dispenser } from '../../../../src/pools/dispenser/' +import { TestContractHandler } from '../../../TestContractHandler' +import { Erc20CreateParams } from '../../../../src/interfaces' const web3 = new Web3('http://127.0.0.1:8545') @@ -31,22 +36,25 @@ describe('Dispenser flow', () => { it('should deploy contracts', async () => { contracts = new TestContractHandler( web3, - ERC721Template.abi as AbiItem, - ERC20Template.abi as AbiItem, - null, - ERC721Factory.abi as AbiItem, - null, - null, - null, - DispenserTemplate.abi as AbiItem, + 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[], + DispenserTemplate.abi as AbiItem[], + OPFCollector.abi as AbiItem[], + ERC721Template.bytecode, ERC20Template.bytecode, - null, + PoolTemplate.bytecode, ERC721Factory.bytecode, FactoryRouter.bytecode, - null, - null, - DispenserTemplate.bytecode + SideStaking.bytecode, + FixedRate.bytecode, + DispenserTemplate.bytecode, + OPFCollector.bytecode ) await contracts.getAccounts() factoryOwner = contracts.accounts[0] @@ -61,38 +69,38 @@ describe('Dispenser flow', () => { it('should initialize Dispenser class', async () => { DispenserClass = new Dispenser( web3, - DispenserAddress, + contracts.dispenserAddress, DispenserTemplate.abi as AbiItem[] ) assert(DispenserClass !== null) }) it('#createNftwithErc - should create an NFT and a Datatoken ', async () => { - nftFactory = new NFTFactory(contracts.factory721Address, web3, LoggerInstance) + nftFactory = new NFTFactory(contracts.factory721Address, web3) - const nftData = { + const nftData: NFTCreateData = { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, baseURI: 'https://oceanprotocol.com/nft/' } - const ercData = { + + const ercParams: Erc20CreateParams = { templateIndex: 1, - strings: ['ERC20B1', 'ERC20DT1Symbol'], - addresses: [ - contracts.accounts[0], - user3, - user2, - '0x0000000000000000000000000000000000000000' - ], - uints: [web3.utils.toWei('10000'), 0], - bytess: [] + minter: contracts.accounts[0], + feeManager: user3, + mpFeeAddress: user2, + feeToken: '0x0000000000000000000000000000000000000000', + cap: '10000', + feeAmount: '0', + name: 'ERC20B1', + symbol: 'ERC20DT1Symbol' } const txReceipt = await nftFactory.createNftWithErc( contracts.accounts[0], nftData, - ercData + ercParams ) expect(txReceipt.events.NFTCreated.event === 'NFTCreated') @@ -103,13 +111,24 @@ describe('Dispenser flow', () => { }) it('Make user2 minter', async () => { - datatoken = new Datatoken(web3, ERC20Template.abi as AbiItem) - await datatoken.addMinter(dtAddress, nftOwner, user2) + datatoken = new Datatoken(web3, ERC20Template.abi as AbiItem[]) + await datatoken.addMinter(dtAddress, contracts.accounts[0], user2) assert((await datatoken.getDTPermissions(dtAddress, user2)).minter === true) }) - it('user2 creates a dispenser', async () => { - const tx = await DispenserClass.activate(dtAddress, '1', '1', user2) + it('Create dispenser', async () => { + const tx = await DispenserClass.create( + dtAddress, + contracts.accounts[0], + '1', + '1', + '0x0000000000000000000000000000000000000000' + ) + assert(tx, 'Cannot create dispenser') + }) + + it('Activate dispenser', async () => { + const tx = await DispenserClass.activate(dtAddress, '1', '1', contracts.accounts[0]) assert(tx, 'Cannot activate dispenser') }) From 54e198c30aa2c530e948615814ae387902e7a977 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Wed, 24 Nov 2021 18:18:21 +0200 Subject: [PATCH 5/9] fixed dispenser create unit test wip updated contracts --- package-lock.json | 345 ++++++++---------- package.json | 3 +- src/datatokens/Datatoken.ts | 40 +- src/factories/NFTFactory.ts | 6 +- src/interfaces/PoolInterface.ts | 5 + src/pools/balancer/Pool.ts | 29 ++ test/unit/Datatoken.test.ts | 11 +- test/unit/NFTDatatoken.test.ts | 6 +- test/unit/NFTFactory.test.ts | 6 +- test/unit/pools/Router.test.ts | 4 +- test/unit/pools/balancer/Pool.test.ts | 22 +- test/unit/pools/dispenser/Dispenser.test.ts | 74 ++-- .../pools/fixedRate/FixedRateExchange.test.ts | 4 +- .../pools/ssContracts/SideStaking.test.ts | 4 +- 14 files changed, 292 insertions(+), 267 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3a4988fd..b9c16576 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@ethereum-navigator/navigator": "^0.5.3", - "@oceanprotocol/contracts": "github:oceanprotocol/contracts#v4main", + "@oceanprotocol/contracts": "github:oceanprotocol/contracts#v4main_postaudit", "cross-fetch": "^3.1.4", "crypto-js": "^4.0.0", "decimal.js": "^10.2.1", @@ -2102,9 +2102,9 @@ } }, "node_modules/@ethereumjs/blockchain": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.0.tgz", - "integrity": "sha512-879YVmWbM8OUKLVj+OuEZ+sZFkQOnXYGeak5oi7O1hOjaRv//je+fK2axGP04cbttu7sPCp41zy7O6xw4cut8A==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz", + "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==", "peer": true, "dependencies": { "@ethereumjs/block": "^3.6.0", @@ -3051,7 +3051,7 @@ "node_modules/@oceanprotocol/contracts": { "name": "hardhat-project", "version": "v1.0.0-alpha.1", - "resolved": "git+ssh://git@github.com/oceanprotocol/contracts.git#c1bea5033dfc9071105a11b63ce86d8e8f612b7b", + "resolved": "git+ssh://git@github.com/oceanprotocol/contracts.git#f72642e81064777242625f7a1b31af92a925f292", "dependencies": { "@balancer-labs/v2-pool-utils": "^1.0.0", "@openzeppelin/contracts": "^4.2.0", @@ -3217,9 +3217,9 @@ } }, "node_modules/@openzeppelin/contracts": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.3.2.tgz", - "integrity": "sha512-AybF1cesONZStg5kWf6ao9OlqTZuPqddvprc0ky7lrUVOjXeKpmQ2Y9FK+6ygxasb+4aic4O5pneFBfwVsRRRg==" + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.3.3.tgz", + "integrity": "sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g==" }, "node_modules/@openzeppelin/test-helpers": { "version": "0.5.15", @@ -3550,9 +3550,9 @@ "integrity": "sha512-BFo/nyxwhoHqPrqBQA1EAmSxeNnspGLiOCMa9pAL7WYSjyNBlrHaqCMO/F2O87G+NUK/u06E70DiSP2BFP0ZZw==" }, "node_modules/@truffle/codec": { - "version": "0.11.18", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.18.tgz", - "integrity": "sha512-OCsKQHOBAmjr+9DypTkTxWYqHmCd388astUvC+ycwlmAqGKIYy2GzpOIX4pX7YX0q/g2iuixEMCTlF440YiNMA==", + "version": "0.11.19", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.19.tgz", + "integrity": "sha512-ZxsfRWBE4wcQ01NCpMWH6VRJ/q3mGTl3ku8ln+WJ2P6McIMsS37imO3d8N9NWiQ49klc9kJfT3mKnOVMLTJhIg==", "dependencies": { "@truffle/abi-utils": "^0.2.4", "@truffle/compile-common": "^0.7.22", @@ -3651,14 +3651,14 @@ } }, "node_modules/@truffle/contract": { - "version": "4.3.39", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.39.tgz", - "integrity": "sha512-ZBCrFUWaTtOvKlJw2J2bDwaBghGDvb5AeVU1WxHvwLnzGqCHzIE6dhZixItdFQgbuZ2gJAxzFQVT38miiK7ufA==", + "version": "4.3.42", + "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.42.tgz", + "integrity": "sha512-CWbKz3L6ldAoh0JX14nNzOyXxWsLiGX5PYpswrwOy0Uk4JYpbVtpSzoQxJbnDTfLUciowfCdG/4QMZ+zo2WVqA==", "dependencies": { "@ensdomains/ensjs": "^2.0.1", "@truffle/blockchain-utils": "^0.0.31", "@truffle/contract-schema": "^3.4.3", - "@truffle/debug-utils": "^5.1.19", + "@truffle/debug-utils": "^6.0.0", "@truffle/error": "^0.0.14", "@truffle/interface-adapter": "^0.5.8", "bignumber.js": "^7.2.1", @@ -4146,16 +4146,16 @@ } }, "node_modules/@truffle/debug-utils": { - "version": "5.1.19", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.19.tgz", - "integrity": "sha512-MWk2DszA6Alme1r4SrWu7BZgz7RNf1TsxdJuSToSltGiJE7DDwV+qsfQ+AGY/PoLKPTQ2xW/sd23BQheA+W9qA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.0.tgz", + "integrity": "sha512-MoN8aQQX2DLLEMMlfF+8ZFtjh0FJsPYwuI4NDcn7upoORe/QoRHeypIhQgaepOXBKwIXW0mplBkAk/nm+cQp8A==", "dependencies": { - "@truffle/codec": "^0.11.18", + "@truffle/codec": "^0.11.19", "@trufflesuite/chromafi": "^2.2.2", "bn.js": "^5.1.3", "chalk": "^2.4.2", "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.1" + "highlightjs-solidity": "^2.0.2" } }, "node_modules/@truffle/debug-utils/node_modules/bn.js": { @@ -7175,7 +7175,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -7186,7 +7185,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -7195,7 +7193,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11284,104 +11281,7 @@ "bundleDependencies": [ "source-map-support", "yargs", - "ethereumjs-util", - "@types/bn.js", - "@types/node", - "@types/pbkdf2", - "@types/secp256k1", - "ansi-regex", - "ansi-styles", - "base-x", - "blakejs", - "bn.js", - "brorand", - "browserify-aes", - "bs58", - "bs58check", - "buffer-from", - "buffer-xor", - "camelcase", - "cipher-base", - "cliui", - "color-convert", - "color-name", - "create-hash", - "create-hmac", - "cross-spawn", - "decamelize", - "elliptic", - "emoji-regex", - "end-of-stream", - "ethereum-cryptography", - "ethjs-util", - "evp_bytestokey", - "execa", - "find-up", - "get-caller-file", - "get-stream", - "hash-base", - "hash.js", - "hmac-drbg", - "inherits", - "invert-kv", - "is-fullwidth-code-point", - "is-hex-prefixed", - "is-stream", - "isexe", - "keccak", - "lcid", - "locate-path", - "map-age-cleaner", - "md5.js", - "mem", - "mimic-fn", - "minimalistic-assert", - "minimalistic-crypto-utils", - "nice-try", - "node-addon-api", - "node-gyp-build", - "npm-run-path", - "once", - "os-locale", - "p-defer", - "p-finally", - "p-is-promise", - "p-limit", - "p-locate", - "p-try", - "path-exists", - "path-key", - "pbkdf2", - "pump", - "randombytes", - "readable-stream", - "require-directory", - "require-main-filename", - "ripemd160", - "rlp", - "safe-buffer", - "scrypt-js", - "secp256k1", - "semver", - "set-blocking", - "setimmediate", - "sha.js", - "shebang-command", - "shebang-regex", - "signal-exit", - "source-map", - "string_decoder", - "string-width", - "strip-ansi", - "strip-eof", - "strip-hex-prefix", - "util-deprecate", - "which", - "which-module", - "wrap-ansi", - "wrappy", - "y18n", - "yargs-parser" + "ethereumjs-util" ], "dependencies": { "ethereumjs-util": "6.2.1", @@ -12787,6 +12687,7 @@ "version": "2.5.4", "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.4.tgz", "integrity": "sha512-aCMBwp8q/4wrW4QLsF/HYBOSA7TpLKmkVwP3pYQNkEEseW2Rr8Z5Uxc9/h6HX+OG3tuHo+2bINVSihIeBfym6A==", + "deprecated": "Deprecated in favor of '@metamask/eth-sig-util'", "peer": true, "dependencies": { "ethereumjs-abi": "0.6.8", @@ -13384,9 +13285,9 @@ } }, "node_modules/hardhat/node_modules/ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", "peer": true, "engines": { "node": ">=8.3.0" @@ -17633,9 +17534,9 @@ } }, "node_modules/obliterator": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.0.tgz", - "integrity": "sha512-DJaXYKqe9Rs7c2+Xu08Knkt8P60rTeByyy7IWoXLqyc6ln9ph9NAo6ZbiylDpAshsygzBr81pZL5q6/dqi0RtQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz", + "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==", "peer": true }, "node_modules/oboe": { @@ -19426,13 +19327,13 @@ } }, "node_modules/raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "peer": true, "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.3", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -19440,6 +19341,46 @@ "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "peer": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body/node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "peer": true + }, + "node_modules/raw-body/node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "peer": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -21396,9 +21337,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==" + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" }, "node_modules/split-on-first": { "version": "1.1.0", @@ -25449,7 +25390,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -25466,7 +25406,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -25475,7 +25414,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -25490,7 +25428,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -25501,14 +25438,12 @@ "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -25654,7 +25589,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -25685,7 +25619,6 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -25703,7 +25636,6 @@ "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, "engines": { "node": ">=10" } @@ -27240,9 +27172,9 @@ } }, "@ethereumjs/blockchain": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.0.tgz", - "integrity": "sha512-879YVmWbM8OUKLVj+OuEZ+sZFkQOnXYGeak5oi7O1hOjaRv//je+fK2axGP04cbttu7sPCp41zy7O6xw4cut8A==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz", + "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==", "peer": true, "requires": { "@ethereumjs/block": "^3.6.0", @@ -27855,8 +27787,8 @@ } }, "@oceanprotocol/contracts": { - "version": "git+ssh://git@github.com/oceanprotocol/contracts.git#c1bea5033dfc9071105a11b63ce86d8e8f612b7b", - "from": "@oceanprotocol/contracts@github:oceanprotocol/contracts#v4main", + "version": "git+ssh://git@github.com/oceanprotocol/contracts.git#f72642e81064777242625f7a1b31af92a925f292", + "from": "@oceanprotocol/contracts@github:oceanprotocol/contracts#v4main_postaudit", "requires": { "@balancer-labs/v2-pool-utils": "^1.0.0", "@openzeppelin/contracts": "^4.2.0", @@ -28013,9 +27945,9 @@ } }, "@openzeppelin/contracts": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.3.2.tgz", - "integrity": "sha512-AybF1cesONZStg5kWf6ao9OlqTZuPqddvprc0ky7lrUVOjXeKpmQ2Y9FK+6ygxasb+4aic4O5pneFBfwVsRRRg==" + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.3.3.tgz", + "integrity": "sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g==" }, "@openzeppelin/test-helpers": { "version": "0.5.15", @@ -28290,9 +28222,9 @@ "integrity": "sha512-BFo/nyxwhoHqPrqBQA1EAmSxeNnspGLiOCMa9pAL7WYSjyNBlrHaqCMO/F2O87G+NUK/u06E70DiSP2BFP0ZZw==" }, "@truffle/codec": { - "version": "0.11.18", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.18.tgz", - "integrity": "sha512-OCsKQHOBAmjr+9DypTkTxWYqHmCd388astUvC+ycwlmAqGKIYy2GzpOIX4pX7YX0q/g2iuixEMCTlF440YiNMA==", + "version": "0.11.19", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.11.19.tgz", + "integrity": "sha512-ZxsfRWBE4wcQ01NCpMWH6VRJ/q3mGTl3ku8ln+WJ2P6McIMsS37imO3d8N9NWiQ49klc9kJfT3mKnOVMLTJhIg==", "requires": { "@truffle/abi-utils": "^0.2.4", "@truffle/compile-common": "^0.7.22", @@ -28385,14 +28317,14 @@ } }, "@truffle/contract": { - "version": "4.3.39", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.39.tgz", - "integrity": "sha512-ZBCrFUWaTtOvKlJw2J2bDwaBghGDvb5AeVU1WxHvwLnzGqCHzIE6dhZixItdFQgbuZ2gJAxzFQVT38miiK7ufA==", + "version": "4.3.42", + "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.3.42.tgz", + "integrity": "sha512-CWbKz3L6ldAoh0JX14nNzOyXxWsLiGX5PYpswrwOy0Uk4JYpbVtpSzoQxJbnDTfLUciowfCdG/4QMZ+zo2WVqA==", "requires": { "@ensdomains/ensjs": "^2.0.1", "@truffle/blockchain-utils": "^0.0.31", "@truffle/contract-schema": "^3.4.3", - "@truffle/debug-utils": "^5.1.19", + "@truffle/debug-utils": "^6.0.0", "@truffle/error": "^0.0.14", "@truffle/interface-adapter": "^0.5.8", "bignumber.js": "^7.2.1", @@ -28793,16 +28725,16 @@ } }, "@truffle/debug-utils": { - "version": "5.1.19", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-5.1.19.tgz", - "integrity": "sha512-MWk2DszA6Alme1r4SrWu7BZgz7RNf1TsxdJuSToSltGiJE7DDwV+qsfQ+AGY/PoLKPTQ2xW/sd23BQheA+W9qA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.0.tgz", + "integrity": "sha512-MoN8aQQX2DLLEMMlfF+8ZFtjh0FJsPYwuI4NDcn7upoORe/QoRHeypIhQgaepOXBKwIXW0mplBkAk/nm+cQp8A==", "requires": { - "@truffle/codec": "^0.11.18", + "@truffle/codec": "^0.11.19", "@trufflesuite/chromafi": "^2.2.2", "bn.js": "^5.1.3", "chalk": "^2.4.2", "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.1" + "highlightjs-solidity": "^2.0.2" }, "dependencies": { "bn.js": { @@ -31248,7 +31180,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -31258,14 +31189,12 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -36039,9 +35968,9 @@ } }, "ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", "peer": true, "requires": {} }, @@ -39361,9 +39290,9 @@ } }, "obliterator": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.0.tgz", - "integrity": "sha512-DJaXYKqe9Rs7c2+Xu08Knkt8P60rTeByyy7IWoXLqyc6ln9ph9NAo6ZbiylDpAshsygzBr81pZL5q6/dqi0RtQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz", + "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==", "peer": true }, "oboe": { @@ -40641,15 +40570,48 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "peer": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.3", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "peer": true + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "peer": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "peer": true + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "peer": true + } } }, "rc": { @@ -42219,9 +42181,9 @@ } }, "spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==" + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" }, "split-on-first": { "version": "1.1.0", @@ -45474,7 +45436,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -45484,14 +45445,12 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -45500,7 +45459,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -45508,14 +45466,12 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -45642,8 +45598,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yaeti": { "version": "0.0.6", @@ -45665,7 +45620,6 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -45679,8 +45633,7 @@ "yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" }, "yargs-unparser": { "version": "2.0.0", diff --git a/package.json b/package.json index 632a4014..10327777 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "test:dispenser": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/dispenser/Dispenser.test.ts'", "test:dt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/Datatoken.test.ts'", "test:nftDt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/NFTDatatoken.test.ts'", + "test:factory": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/NFTFactory.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", @@ -52,7 +53,7 @@ }, "dependencies": { "@ethereum-navigator/navigator": "^0.5.3", - "@oceanprotocol/contracts": "github:oceanprotocol/contracts#v4main", + "@oceanprotocol/contracts": "github:oceanprotocol/contracts#v4main_postaudit", "cross-fetch": "^3.1.4", "crypto-js": "^4.0.0", "decimal.js": "^10.2.1", diff --git a/src/datatokens/Datatoken.ts b/src/datatokens/Datatoken.ts index ece65944..9149ea44 100644 --- a/src/datatokens/Datatoken.ts +++ b/src/datatokens/Datatoken.ts @@ -13,7 +13,7 @@ import { FreOrderParams, FreCreationParams } from '../interfaces' */ interface Roles { minter: boolean - feeManager: boolean + paymentManager: boolean } export interface OrderParams { @@ -338,6 +338,8 @@ export class Datatoken { dtContract ) + console.log('dispenserParams', dispenserParams) + // Call createFixedRate contract method const trxReceipt = await dtContract.methods .createDispenser( @@ -526,14 +528,14 @@ export class Datatoken { * Estimate gas for addFeeManager method * @param {String} dtAddress Datatoken address * @param {String} address User address - * @param {String} feeManager User which is going to be a Minter + * @param {String} paymentManager User which is going to be a Minter * @param {Contract} contractInstance optional contract instance * @return {Promise} */ - public async estGasAddFeeManager( + public async estGasAddPaymentManager( dtAddress: string, address: string, - feeManager: string, + paymentManager: string, contractInstance?: Contract ): Promise { const dtContract = @@ -544,7 +546,7 @@ export class Datatoken { let estGas try { estGas = await dtContract.methods - .addFeeManager(feeManager) + .addFeeManager(paymentManager) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) } catch (e) { estGas = gasLimitDefault @@ -554,31 +556,31 @@ export class Datatoken { } /** - * Add FeeManager for an ERC20 datatoken + * Add addPaymentManager for an ERC20 datatoken * only ERC20Deployer can succeed * @param {String} dtAddress Datatoken address * @param {String} address User address - * @param {String} feeManager User which is going to be a Minter + * @param {String} paymentManager User which is going to be a Minter * @return {Promise} transactionId */ - public async addFeeManager( + public async addPaymentManager( dtAddress: string, address: string, - feeManager: string + paymentManager: string ): Promise { const dtContract = new this.web3.eth.Contract(this.datatokensABI, dtAddress) // should check ERC20Deployer role using erc721 level .. - const estGas = await this.estGasAddFeeManager( + const estGas = await this.estGasAddPaymentManager( dtAddress, address, - feeManager, + paymentManager, dtContract ) - // Call addFeeManager function of the contract - const trxReceipt = await dtContract.methods.addFeeManager(feeManager).send({ + // Call addPaymentManager function of the contract + const trxReceipt = await dtContract.methods.addPaymentManager(paymentManager).send({ from: address, gas: estGas + 1, gasPrice: await getFairGasPrice(this.web3) @@ -692,7 +694,7 @@ export class Datatoken { feeCollector: string ): Promise { const dtContract = new this.web3.eth.Contract(this.datatokensABI, dtAddress) - if ((await this.getDTPermissions(dtAddress, address)).feeManager !== true) { + if ((await this.getDTPermissions(dtAddress, address)).paymentManager !== true) { throw new Error(`Caller is not Fee Manager`) } @@ -1187,6 +1189,16 @@ export class Datatoken { return decimals } + /** It returns the token decimals, how many supported decimal points + * @param {String} dtAddress Datatoken adress + * @return {Promise} + */ + public async getNFTAddress(dtAddress: string): Promise { + const dtContract = new this.web3.eth.Contract(this.datatokensABI, dtAddress) + const nftAddress = await dtContract.methods.getERC721Address().call() + return nftAddress + } + /** * Get Address Balance for datatoken * @param {String} dtAddress Datatoken adress diff --git a/src/factories/NFTFactory.ts b/src/factories/NFTFactory.ts index fbd4d215..7ab20af5 100644 --- a/src/factories/NFTFactory.ts +++ b/src/factories/NFTFactory.ts @@ -32,7 +32,7 @@ export interface NFTCreateData { name: string symbol: string templateIndex: number - baseURI: string + tokenURI: string } /** @@ -84,7 +84,7 @@ export class NFTFactory { nftData.symbol, nftData.templateIndex, '0x0000000000000000000000000000000000000000', - nftData.baseURI + nftData.tokenURI ) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) } catch (e) { @@ -117,7 +117,7 @@ export class NFTFactory { nftData.symbol, nftData.templateIndex, '0x0000000000000000000000000000000000000000', - nftData.baseURI + nftData.tokenURI ) .send({ from: address, diff --git a/src/interfaces/PoolInterface.ts b/src/interfaces/PoolInterface.ts index 22b12fa3..2fda2dfc 100644 --- a/src/interfaces/PoolInterface.ts +++ b/src/interfaces/PoolInterface.ts @@ -13,3 +13,8 @@ export interface PoolCreationParams { swapFeeLiquidityProvider: number swapFeeMarketPlaceRunner: number } + +export interface CurrentFees { + tokens: string[] + amounts: string[] +} diff --git a/src/pools/balancer/Pool.ts b/src/pools/balancer/Pool.ts index 25baa7a4..4ee6564b 100644 --- a/src/pools/balancer/Pool.ts +++ b/src/pools/balancer/Pool.ts @@ -8,6 +8,7 @@ import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/bal import defaultPool from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json' import defaultERC20ABI from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json' import Decimal from 'decimal.js' +import { CurrentFees } from '../../interfaces' const BN = require('bn.js') const MaxUint256 = @@ -511,6 +512,34 @@ export class Pool { return weight } + /** + * Get Community Get the current amount of fees which can be withdrawned by the Market + * @return {CurrentFees} + */ + async getCurrentMarketFees(poolAddress: string): Promise { + const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) + try { + const currentMarketFees = await pool.methods.getCurrentOPFFees().call() + return currentMarketFees + } catch (e) { + this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`) + } + } + + /** + * Get getCurrentOPFFees Get the current amount of fees which can be withdrawned by OPF + * @return {CurrentFees} + */ + async getCurrentOPFFees(poolAddress: string): Promise { + const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) + try { + const currentMarketFees = await pool.methods.getCurrentOPFFees().call() + return currentMarketFees + } catch (e) { + this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`) + } + } + /** * Get Community Fees available to be collected for a specific token * @param {String} poolAddress diff --git a/test/unit/Datatoken.test.ts b/test/unit/Datatoken.test.ts index a9b08b0e..0a088d37 100644 --- a/test/unit/Datatoken.test.ts +++ b/test/unit/Datatoken.test.ts @@ -13,7 +13,7 @@ import OPFCollector from '@oceanprotocol/contracts/artifacts/contracts/community import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json' import { TestContractHandler } from '../TestContractHandler' -import { NFTFactory } from '../../src/factories/NFTFactory' +import { NFTFactory, NFTCreateData } from '../../src/factories/NFTFactory' import { Datatoken, NFTDatatoken, @@ -88,11 +88,11 @@ describe('Datatoken', () => { web3, ERC721Factory.abi as AbiItem[] ) - const nftData = { + const nftData: NFTCreateData = { name: nftName, symbol: nftSymbol, templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } nftAddress = await nftFactory.createNFT(nftOwner, nftData) @@ -336,6 +336,11 @@ describe('Datatoken', () => { ) }) + it('#getERC721Address - should succeed to get the parent ERC721 address', async () => { + const address = await datatoken.getNFTAddress(datatokenAddress) + assert(address, 'Not able to get the parent ERC721 address') + }) + it('#setData - should set a value into 725Y standard, if nftDatatoken has ERC20Deployer permission', async () => { const data = web3.utils.asciiToHex('SomeData') diff --git a/test/unit/NFTDatatoken.test.ts b/test/unit/NFTDatatoken.test.ts index 43a24c6f..734c9926 100644 --- a/test/unit/NFTDatatoken.test.ts +++ b/test/unit/NFTDatatoken.test.ts @@ -13,7 +13,7 @@ import OPFCollector from '@oceanprotocol/contracts/artifacts/contracts/community import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json' import { TestContractHandler } from '../TestContractHandler' -import { NFTFactory } from '../../src/factories/NFTFactory' +import { NFTFactory, NFTCreateData } from '../../src/factories/NFTFactory' import { NFTDatatoken } from '../../src/datatokens/NFTDatatoken' import { AbiItem } from 'web3-utils' import { LoggerInstance } from '../../src/utils' @@ -72,11 +72,11 @@ describe('NFTDatatoken', () => { web3, ERC721Factory.abi as AbiItem[] ) - const nftData = { + const nftData: NFTCreateData = { name: nftName, symbol: nftSymbol, templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } nftAddress = await nftFactory.createNFT(nftOwner, nftData) diff --git a/test/unit/NFTFactory.test.ts b/test/unit/NFTFactory.test.ts index f6c432ab..21430e7c 100644 --- a/test/unit/NFTFactory.test.ts +++ b/test/unit/NFTFactory.test.ts @@ -178,7 +178,7 @@ describe('NFT Factory test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -214,7 +214,7 @@ describe('NFT Factory test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -264,7 +264,7 @@ describe('NFT Factory test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { diff --git a/test/unit/pools/Router.test.ts b/test/unit/pools/Router.test.ts index 26fe74e1..480f0116 100644 --- a/test/unit/pools/Router.test.ts +++ b/test/unit/pools/Router.test.ts @@ -178,7 +178,7 @@ describe('Router unit test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -231,7 +231,7 @@ describe('Router unit test', () => { name: '72120Bundle2', symbol: '72Bundle2', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft2/' + tokenURI: 'https://oceanprotocol.com/nft2/' } const ercParams2: Erc20CreateParams = { diff --git a/test/unit/pools/balancer/Pool.test.ts b/test/unit/pools/balancer/Pool.test.ts index 26446660..f2d3d7bd 100644 --- a/test/unit/pools/balancer/Pool.test.ts +++ b/test/unit/pools/balancer/Pool.test.ts @@ -17,7 +17,11 @@ import OPFCollector from '@oceanprotocol/contracts/artifacts/contracts/community import { LoggerInstance } from '../../../../src/utils' import { NFTFactory, NFTCreateData } from '../../../../src/factories/NFTFactory' import { Pool } from '../../../../src/pools/balancer/Pool' -import { PoolCreationParams, Erc20CreateParams } from '../../../../src/interfaces' +import { + PoolCreationParams, + Erc20CreateParams, + CurrentFees +} from '../../../../src/interfaces' const { keccak256 } = require('@ethersproject/keccak256') const web3 = new Web3('http://127.0.0.1:8545') const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75' @@ -136,7 +140,7 @@ describe('Pool unit test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -579,7 +583,7 @@ describe('Pool unit test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -1052,6 +1056,18 @@ describe('Pool unit test', () => { assert((await pool.getOPFCollector(poolAddress)) === contracts.opfCollectorAddress) }) + it('#getCurrentMarketFees- should get curent market fees for each token', async () => { + const currentMarketFees: CurrentFees = await pool.getCurrentMarketFees(poolAddress) + console.log('currentMarketFees == ', currentMarketFees) + assert(currentMarketFees !== null) + }) + + it('#getCurrentOPFFees- should get curent market fees for each token', async () => { + const curentOPFFees: CurrentFees = await pool.getCurrentOPFFees(poolAddress) + console.log('curentOPFFees == ', curentOPFFees) + assert(curentOPFFees !== null) + }) + it('#collectCommunityFee- should get community fees for each token', async () => { const spotPriceBefore = await pool.getSpotPrice( poolAddress, diff --git a/test/unit/pools/dispenser/Dispenser.test.ts b/test/unit/pools/dispenser/Dispenser.test.ts index e8dd013a..43d8cb5b 100644 --- a/test/unit/pools/dispenser/Dispenser.test.ts +++ b/test/unit/pools/dispenser/Dispenser.test.ts @@ -12,7 +12,7 @@ import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/M 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 { NFTFactory, NFTCreateData } from '../../../../src/factories/' -import { Datatoken } from '../../../../src/datatokens/' +import { Datatoken, DispenserParams } from '../../../../src/datatokens/' import { Dispenser } from '../../../../src/pools/dispenser/' import { TestContractHandler } from '../../../TestContractHandler' import { Erc20CreateParams } from '../../../../src/interfaces' @@ -82,7 +82,7 @@ describe('Dispenser flow', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -117,12 +117,16 @@ describe('Dispenser flow', () => { }) it('Create dispenser', async () => { - const tx = await DispenserClass.create( + const dispenserParams: DispenserParams = { + maxTokens: '1', + maxBalance: '1', + withMint: true + } + const tx = await datatoken.createDispenser( dtAddress, contracts.accounts[0], - '1', - '1', - '0x0000000000000000000000000000000000000000' + contracts.dispenserAddress, + dispenserParams ) assert(tx, 'Cannot create dispenser') }) @@ -135,40 +139,40 @@ describe('Dispenser flow', () => { it('user2 gets the dispenser status', async () => { const status = await DispenserClass.status(dtAddress) assert(status.active === true, 'Dispenser not active') - assert(status.owner === user2, 'Dispenser owner is not alice') + assert(status.owner === contracts.accounts[0], 'Dispenser owner is not alice') assert(status.minterApproved === true, 'Dispenser is not a minter') }) - it('user2 deactivates the dispenser', async () => { - const tx = await DispenserClass.deactivate(dtAddress, user2) - assert(tx, 'Cannot deactivate dispenser') - const status = await DispenserClass.status(dtAddress) - assert(status.active === false, 'Dispenser is still active') - }) + // it('user2 deactivates the dispenser', async () => { + // const tx = await DispenserClass.deactivate(dtAddress, user2) + // assert(tx, 'Cannot deactivate dispenser') + // const status = await DispenserClass.status(dtAddress) + // assert(status.active === false, 'Dispenser is still active') + // }) - it('user2 sets user3 as an AllowedSwapper for the dispenser', async () => { - const tx = await DispenserClass.setAllowedSwapper(dtAddress, user2, user3) - assert(tx, 'Cannot deactivate dispenser') - const status = await DispenserClass.status(dtAddress) - assert(status.allowedSwapper === user3, 'Dispenser is still active') - }) + // it('user2 sets user3 as an AllowedSwapper for the dispenser', async () => { + // const tx = await DispenserClass.setAllowedSwapper(dtAddress, user2, user3) + // assert(tx, 'Cannot deactivate dispenser') + // const status = await DispenserClass.status(dtAddress) + // assert(status.allowedSwapper === user3, 'Dispenser is still active') + // }) - it('User3 requests datatokens', async () => { - const check = await DispenserClass.isDispensable(dtAddress, datatoken, user3, '1') - assert(check === true, 'isDispensable should return true') - const tx = await DispenserClass.dispense(dtAddress, user3, '1', user3) - assert(tx, 'user3 failed to get 1DT') - }) + // it('User3 requests datatokens', async () => { + // const check = await DispenserClass.isDispensable(dtAddress, datatoken, user3, '1') + // assert(check === true, 'isDispensable should return true') + // const tx = await DispenserClass.dispense(dtAddress, user3, '1', user3) + // assert(tx, 'user3 failed to get 1DT') + // }) - it('tries to withdraw all datatokens', async () => { - const tx = await DispenserClass.ownerWithdraw(dtAddress, user3) - assert(tx === null, 'Request should fail') - }) + // it('tries to withdraw all datatokens', async () => { + // const tx = await DispenserClass.ownerWithdraw(dtAddress, user3) + // assert(tx === null, 'Request should fail') + // }) - it('user2 withdraws all datatokens', async () => { - const tx = await DispenserClass.ownerWithdraw(dtAddress, user2) - assert(tx, 'user2 failed to withdraw all her tokens') - const status = await DispenserClass.status(dtAddress) - assert(status.balance === '0', 'Balance > 0') - }) + // it('user2 withdraws all datatokens', async () => { + // const tx = await DispenserClass.ownerWithdraw(dtAddress, user2) + // assert(tx, 'user2 failed to withdraw all her tokens') + // const status = await DispenserClass.status(dtAddress) + // assert(status.balance === '0', 'Balance > 0') + // }) }) diff --git a/test/unit/pools/fixedRate/FixedRateExchange.test.ts b/test/unit/pools/fixedRate/FixedRateExchange.test.ts index dd8ab5e3..0562ff42 100644 --- a/test/unit/pools/fixedRate/FixedRateExchange.test.ts +++ b/test/unit/pools/fixedRate/FixedRateExchange.test.ts @@ -111,7 +111,7 @@ describe('Fixed Rate unit test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -439,7 +439,7 @@ describe('Fixed Rate unit test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { diff --git a/test/unit/pools/ssContracts/SideStaking.test.ts b/test/unit/pools/ssContracts/SideStaking.test.ts index 46c6803f..9385ec03 100644 --- a/test/unit/pools/ssContracts/SideStaking.test.ts +++ b/test/unit/pools/ssContracts/SideStaking.test.ts @@ -141,7 +141,7 @@ describe('SideStaking unit test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { @@ -420,7 +420,7 @@ describe('SideStaking unit test', () => { name: '72120Bundle', symbol: '72Bundle', templateIndex: 1, - baseURI: 'https://oceanprotocol.com/nft/' + tokenURI: 'https://oceanprotocol.com/nft/' } const ercParams: Erc20CreateParams = { From aa9c02af3fd5967230605fb97ab2f5393f4d218d Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Wed, 24 Nov 2021 23:34:52 +0200 Subject: [PATCH 6/9] fixed rest of dispenser unit tests --- src/datatokens/Datatoken.ts | 2 - src/pools/dispenser/Dispenser.ts | 5 +- test/unit/pools/dispenser/Dispenser.test.ts | 68 ++++++++++++--------- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/datatokens/Datatoken.ts b/src/datatokens/Datatoken.ts index 9149ea44..e7d1c2cd 100644 --- a/src/datatokens/Datatoken.ts +++ b/src/datatokens/Datatoken.ts @@ -338,8 +338,6 @@ export class Datatoken { dtContract ) - console.log('dispenserParams', dispenserParams) - // Call createFixedRate contract method const trxReceipt = await dtContract.methods .createDispenser( diff --git a/src/pools/dispenser/Dispenser.ts b/src/pools/dispenser/Dispenser.ts index e14516b9..7275e151 100644 --- a/src/pools/dispenser/Dispenser.ts +++ b/src/pools/dispenser/Dispenser.ts @@ -13,8 +13,7 @@ export interface DispenserToken { maxTokens: string maxBalance: string balance: string - minterApproved: boolean - isTrueMinter: boolean + isMinter: boolean allowedSwapper: string } @@ -436,7 +435,7 @@ export class Dispenser { if (new Decimal(String(amount)).greaterThan(status.maxTokens)) return false // check dispenser balance const contractBalance = new Decimal(status.balance) - if (contractBalance.greaterThanOrEqualTo(amount) || status.isTrueMinter === true) + if (contractBalance.greaterThanOrEqualTo(amount) || status.isMinter === true) return true return false } diff --git a/test/unit/pools/dispenser/Dispenser.test.ts b/test/unit/pools/dispenser/Dispenser.test.ts index 43d8cb5b..959406cc 100644 --- a/test/unit/pools/dispenser/Dispenser.test.ts +++ b/test/unit/pools/dispenser/Dispenser.test.ts @@ -140,39 +140,49 @@ describe('Dispenser flow', () => { const status = await DispenserClass.status(dtAddress) assert(status.active === true, 'Dispenser not active') assert(status.owner === contracts.accounts[0], 'Dispenser owner is not alice') - assert(status.minterApproved === true, 'Dispenser is not a minter') + assert(status.isMinter === true, 'Dispenser is not a minter') }) - // it('user2 deactivates the dispenser', async () => { - // const tx = await DispenserClass.deactivate(dtAddress, user2) - // assert(tx, 'Cannot deactivate dispenser') - // const status = await DispenserClass.status(dtAddress) - // assert(status.active === false, 'Dispenser is still active') - // }) + it('user2 deactivates the dispenser', async () => { + const tx = await DispenserClass.deactivate(dtAddress, contracts.accounts[0]) + assert(tx, 'Cannot deactivate dispenser') + const status = await DispenserClass.status(dtAddress) + assert(status.active === false, 'Dispenser is still active') + }) - // it('user2 sets user3 as an AllowedSwapper for the dispenser', async () => { - // const tx = await DispenserClass.setAllowedSwapper(dtAddress, user2, user3) - // assert(tx, 'Cannot deactivate dispenser') - // const status = await DispenserClass.status(dtAddress) - // assert(status.allowedSwapper === user3, 'Dispenser is still active') - // }) + it('user2 sets user3 as an AllowedSwapper for the dispenser', async () => { + const tx = await DispenserClass.setAllowedSwapper( + dtAddress, + contracts.accounts[0], + user3 + ) + assert(tx, 'Cannot set Allowed Swapper') + const status = await DispenserClass.status(dtAddress) + assert(status.allowedSwapper === user3, 'user3 is Allowed Swapper') + }) - // it('User3 requests datatokens', async () => { - // const check = await DispenserClass.isDispensable(dtAddress, datatoken, user3, '1') - // assert(check === true, 'isDispensable should return true') - // const tx = await DispenserClass.dispense(dtAddress, user3, '1', user3) - // assert(tx, 'user3 failed to get 1DT') - // }) + it('User3 requests datatokens', async () => { + const activate = await DispenserClass.activate( + dtAddress, + '10', + '10', + contracts.accounts[0] + ) + const check = await DispenserClass.isDispensable(dtAddress, datatoken, user3, '1') + assert(check === true, 'isDispensable should return true') + const tx = await DispenserClass.dispense(dtAddress, user3, '1', user3) + assert(tx, 'user3 failed to get 1DT') + }) - // it('tries to withdraw all datatokens', async () => { - // const tx = await DispenserClass.ownerWithdraw(dtAddress, user3) - // assert(tx === null, 'Request should fail') - // }) + it('tries to withdraw all datatokens', async () => { + const tx = await DispenserClass.ownerWithdraw(dtAddress, user3) + assert(tx === null, 'Request should fail') + }) - // it('user2 withdraws all datatokens', async () => { - // const tx = await DispenserClass.ownerWithdraw(dtAddress, user2) - // assert(tx, 'user2 failed to withdraw all her tokens') - // const status = await DispenserClass.status(dtAddress) - // assert(status.balance === '0', 'Balance > 0') - // }) + it('user2 withdraws all datatokens', async () => { + const tx = await DispenserClass.ownerWithdraw(dtAddress, contracts.accounts[0]) + assert(tx, 'user2 failed to withdraw all her tokens') + const status = await DispenserClass.status(dtAddress) + assert(status.balance === '0', 'Balance > 0') + }) }) From fa2e44d82b1c6eb88e7dfd68e0545fc402b7fd71 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 25 Nov 2021 00:17:56 +0200 Subject: [PATCH 7/9] update erc20 datatoken and tests --- package-lock.json | 32 ++++--------- src/datatokens/Datatoken.ts | 89 ++++++++++++++++++++----------------- test/unit/Datatoken.test.ts | 44 +++++++++--------- 3 files changed, 77 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index b9c16576..2b78419e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12552,9 +12552,9 @@ } }, "node_modules/hardhat": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.6.8.tgz", - "integrity": "sha512-iRVd5DgcIVV3rNXMlogOfwlXAhHp7Wy/OjjFiUhTey8Unvo6oq5+Is5ANiKVN+Iw07Pcb/HpkGt7jCB6a4ITgg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.7.0.tgz", + "integrity": "sha512-DqweY3KH5gwExoZ8EtsAfioj0Hk0NBXWXT3fMXWkiQNfyYBoZLrqdPNkbJ/E2LD4mZ+BKF7v/1chYR9ZCn2Z+g==", "peer": true, "dependencies": { "@ethereumjs/block": "^3.4.0", @@ -12602,7 +12602,7 @@ "stacktrace-parser": "^0.1.10", "true-case-path": "^2.2.1", "tsort": "0.0.1", - "uuid": "^3.3.2", + "uuid": "^8.3.2", "ws": "^7.4.6" }, "bin": { @@ -13248,16 +13248,6 @@ "node": ">=6" } }, - "node_modules/hardhat/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "peer": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/hardhat/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -35400,9 +35390,9 @@ } }, "hardhat": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.6.8.tgz", - "integrity": "sha512-iRVd5DgcIVV3rNXMlogOfwlXAhHp7Wy/OjjFiUhTey8Unvo6oq5+Is5ANiKVN+Iw07Pcb/HpkGt7jCB6a4ITgg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.7.0.tgz", + "integrity": "sha512-DqweY3KH5gwExoZ8EtsAfioj0Hk0NBXWXT3fMXWkiQNfyYBoZLrqdPNkbJ/E2LD4mZ+BKF7v/1chYR9ZCn2Z+g==", "peer": true, "requires": { "@ethereumjs/block": "^3.4.0", @@ -35450,7 +35440,7 @@ "stacktrace-parser": "^0.1.10", "true-case-path": "^2.2.1", "tsort": "0.0.1", - "uuid": "^3.3.2", + "uuid": "^8.3.2", "ws": "^7.4.6" }, "dependencies": { @@ -35941,12 +35931,6 @@ "has-flag": "^3.0.0" } }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "peer": true - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/src/datatokens/Datatoken.ts b/src/datatokens/Datatoken.ts index e7d1c2cd..30228567 100644 --- a/src/datatokens/Datatoken.ts +++ b/src/datatokens/Datatoken.ts @@ -523,7 +523,7 @@ export class Datatoken { } /** - * Estimate gas for addFeeManager method + * Estimate gas for addPaymentManager method * @param {String} dtAddress Datatoken address * @param {String} address User address * @param {String} paymentManager User which is going to be a Minter @@ -544,7 +544,7 @@ export class Datatoken { let estGas try { estGas = await dtContract.methods - .addFeeManager(paymentManager) + .addPaymentManager(paymentManager) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) } catch (e) { estGas = gasLimitDefault @@ -554,7 +554,7 @@ export class Datatoken { } /** - * Add addPaymentManager for an ERC20 datatoken + * Add addPaymentManager (can set who's going to collect fee when consuming orders) * only ERC20Deployer can succeed * @param {String} dtAddress Datatoken address * @param {String} address User address @@ -588,17 +588,17 @@ export class Datatoken { } /** - * Estimate gas for removeFeeManager method + * Estimate gas for removePaymentManager method * @param {String} dtAddress Datatoken address * @param {String} address User address - * @param {String} feeManager User which will be removed from FeeManager permission + * @param {String} paymentManager User which will be removed from paymentManager permission * @param {Contract} contractInstance optional contract instance * @return {Promise} */ - public async estGasRemoveFeeManager( + public async estGasRemovePaymentManager( dtAddress: string, address: string, - feeManager: string, + paymentManager: string, contractInstance?: Contract ): Promise { const dtContract = @@ -608,7 +608,7 @@ export class Datatoken { let estGas try { estGas = await dtContract.methods - .removeFeeManager(feeManager) + .removePaymentManager(paymentManager) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) } catch (e) { estGas = gasLimitDefault @@ -617,50 +617,52 @@ export class Datatoken { } /** - * Revoke FeeManager permission for an ERC20 datatoken + * Revoke paymentManager permission for an ERC20 datatoken * only ERC20Deployer can succeed * @param {String} dtAddress Datatoken address * @param {String} address User address - * @param {String} feeManager User which will be removed from FeeManager permission + * @param {String} paymentManager User which will be removed from paymentManager permission * @return {Promise} trxReceipt */ - public async removeFeeManager( + public async removePaymentManager( dtAddress: string, address: string, - feeManager: string + paymentManager: string ): Promise { const dtContract = new this.web3.eth.Contract(this.datatokensABI, dtAddress) // should check ERC20Deployer role using erc721 level .. - const estGas = await this.estGasRemoveFeeManager( + const estGas = await this.estGasRemovePaymentManager( dtAddress, address, - feeManager, + paymentManager, dtContract ) // Call removeFeeManager function of the contract - const trxReceipt = await dtContract.methods.removeFeeManager(feeManager).send({ - from: address, - gas: estGas + 1, - gasPrice: await getFairGasPrice(this.web3) - }) + const trxReceipt = await dtContract.methods + .removePaymentManager(paymentManager) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) return trxReceipt } /** - * Estimate gas for setFeeCollector method - * @param dtAddress datatoken address where we want to clean permissions address + * Estimate gas for setPaymentCollector method + * @param dtAddress datatoken address * @param address Caller address - * @param feeCollector User to be set as new fee collector + * @param paymentCollector User to be set as new payment collector * @param {Contract} contractInstance optional contract instance * @return {Promise} */ - public async estGasSetFeeCollector( + public async estGasSetPaymentCollector( dtAddress: string, address: string, - feeCollector: string, + paymentCollector: string, contractInstance?: Contract ): Promise { const dtContract = @@ -670,7 +672,7 @@ export class Datatoken { let estGas try { estGas = await dtContract.methods - .setFeeCollector(feeCollector) + .setPaymentCollector(paymentCollector) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) } catch (e) { estGas = gasLimitDefault @@ -679,48 +681,51 @@ export class Datatoken { } /** - * Set a new fee Collector, if feeCollector is address(0), feeCollector is NFT Owner + * This function allows to set a new PaymentCollector (receives DT when consuming) + * If not set the paymentCollector is the NFT Owner * only NFT owner can call - * @param dtAddress datatoken address where we want to clean permissions address + * @param dtAddress datatoken address * @param address Caller address - * @param feeCollector User to be set as new fee collector + * @param paymentCollector User to be set as new payment collector * @return {Promise} trxReceipt */ - public async setFeeCollector( + public async setPaymentCollector( dtAddress: string, address: string, - feeCollector: string + paymentCollector: string ): Promise { const dtContract = new this.web3.eth.Contract(this.datatokensABI, dtAddress) if ((await this.getDTPermissions(dtAddress, address)).paymentManager !== true) { throw new Error(`Caller is not Fee Manager`) } - const estGas = await this.estGasSetFeeCollector( + const estGas = await this.estGasSetPaymentCollector( dtAddress, address, - feeCollector, + paymentCollector, dtContract ) // Call setFeeCollector method of the contract - const trxReceipt = await dtContract.methods.setFeeCollector(feeCollector).send({ - from: address, - gas: estGas + 1, - gasPrice: await getFairGasPrice(this.web3) - }) + const trxReceipt = await dtContract.methods + .setPaymentCollector(paymentCollector) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) return trxReceipt } - /** Get Fee Collector + /** getPaymentCollector - It returns the current paymentCollector * @param dtAddress datatoken address * @return {Promise} */ - public async getFeeCollector(dtAddress: string): Promise { + public async getPaymentCollector(dtAddress: string): Promise { const dtContract = new this.web3.eth.Contract(this.datatokensABI, dtAddress) - const feeCollector = await dtContract.methods.getFeeCollector().call() - return feeCollector + const paymentCollector = await dtContract.methods.getPaymentCollector().call() + return paymentCollector } /** @@ -1132,7 +1137,7 @@ export class Datatoken { } /** - * Clean erc20level Permissions (minters, feeManagers and reset the feeCollector) for an ERC20 datatoken + * Clean erc20level Permissions (minters, paymentManager and reset the paymentCollector) for an ERC20 datatoken * Only NFT Owner (at 721 level) can call it. * @param dtAddress Datatoken address where we want to clean permissions * @param address User adress diff --git a/test/unit/Datatoken.test.ts b/test/unit/Datatoken.test.ts index 0a088d37..0ed44792 100644 --- a/test/unit/Datatoken.test.ts +++ b/test/unit/Datatoken.test.ts @@ -191,54 +191,54 @@ describe('Datatoken', () => { assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false) }) - it('#addFeeManager - should add user2 as feeManager, if nftDatatoken has ERC20Deployer permission', async () => { + it('#addPaymentManager - should add user2 as paymentManager, if nftDatatoken has ERC20Deployer permission', async () => { assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true) assert( - (await datatoken.getDTPermissions(datatokenAddress, user2)).feeManager === false + (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false ) - await datatoken.addFeeManager(datatokenAddress, nftOwner, user2) + await datatoken.addPaymentManager(datatokenAddress, nftOwner, user2) assert( - (await datatoken.getDTPermissions(datatokenAddress, user2)).feeManager === true + (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true ) }) - it('#removeFeeManager - should remove user2 as feeManager, if nftDatatoken has ERC20Deployer permission', async () => { + it('#removePaymentManager - should remove user2 as paymentManager, if nftDatatoken has ERC20Deployer permission', async () => { assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true) assert( - (await datatoken.getDTPermissions(datatokenAddress, user2)).feeManager === true + (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true ) - await datatoken.removeFeeManager(datatokenAddress, nftOwner, user2) + await datatoken.removePaymentManager(datatokenAddress, nftOwner, user2) assert( - (await datatoken.getDTPermissions(datatokenAddress, user2)).feeManager === false + (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false ) }) - it('#setFeeCollector - should fail to set a new feeCollector, if NOT Fee Manager', async () => { - await datatoken.removeFeeManager(datatokenAddress, nftOwner, user2) + it('#setPaymentCollector - should fail to set a new feeCollector, if NOT Fee Manager', async () => { + await datatoken.removePaymentManager(datatokenAddress, nftOwner, user2) assert( - (await datatoken.getDTPermissions(datatokenAddress, user2)).feeManager === false + (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false ) try { - await datatoken.setFeeCollector(datatokenAddress, user1, user2) + await datatoken.setPaymentCollector(datatokenAddress, user1, user2) } catch (e) { assert(e.message === 'Caller is not Fee Manager') } }) - it('#setFeeCollector - should set a new feeCollector, if FEE MANAGER', async () => { - assert((await datatoken.getFeeCollector(datatokenAddress)) === user2) + it('#setPaymentCollector - should set a new feeCollector, if FEE MANAGER', async () => { + assert((await datatoken.getPaymentCollector(datatokenAddress)) === user2) assert( - (await datatoken.getDTPermissions(datatokenAddress, user1)).feeManager === true + (await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true ) - await datatoken.setFeeCollector(datatokenAddress, user1, user3) - assert((await datatoken.getFeeCollector(datatokenAddress)) === user3) + await datatoken.setPaymentCollector(datatokenAddress, user1, user3) + assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3) }) it('#startOrder- user2 should create an order for DT ', async () => { @@ -270,7 +270,7 @@ describe('Datatoken', () => { assert( (await datatoken.balance( datatokenAddress, - await datatoken.getFeeCollector(datatokenAddress) + await datatoken.getPaymentCollector(datatokenAddress) )) === '1', 'Invalid publisher reward, we should have 1 DT' ) @@ -317,22 +317,22 @@ describe('Datatoken', () => { it('#cleanPermissions - should clean permissions at ERC20 level', async () => { assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true) - assert((await datatoken.getFeeCollector(datatokenAddress)) === user3) + assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3) assert( - (await datatoken.getDTPermissions(datatokenAddress, user1)).feeManager === true + (await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true ) await datatoken.cleanPermissions(datatokenAddress, nftOwner) - assert((await datatoken.getFeeCollector(datatokenAddress)) === nftOwner) + assert((await datatoken.getPaymentCollector(datatokenAddress)) === nftOwner) assert( (await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === false ) assert( - (await datatoken.getDTPermissions(datatokenAddress, user1)).feeManager === false + (await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === false ) }) From 5f5b3ee1dc2eaa6e7192087353cb1a668ab1432e Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 25 Nov 2021 11:55:04 +0200 Subject: [PATCH 8/9] fixed erc20 unit test --- src/pools/balancer/Pool.ts | 12 +++++------- test/unit/Datatoken.test.ts | 10 ++++++---- test/unit/pools/balancer/Pool.test.ts | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/pools/balancer/Pool.ts b/src/pools/balancer/Pool.ts index 4ee6564b..b21bfd04 100644 --- a/src/pools/balancer/Pool.ts +++ b/src/pools/balancer/Pool.ts @@ -620,7 +620,6 @@ export class Pool { public async estCollectMarketFee( address: string, poolAddress: string, - to: string, contractInstance?: Contract ): Promise { const poolContract = @@ -631,7 +630,7 @@ export class Pool { let estGas try { estGas = await poolContract.methods - .collectMarketFee(to) + .collectMarketFee() .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) } catch (e) { estGas = gasLimitDefault @@ -648,18 +647,17 @@ export class Pool { */ async collectMarketFee( address: string, - poolAddress: string, - to: string + poolAddress: string ): Promise { if ((await this.getMarketFeeCollector(poolAddress)) !== address) { throw new Error(`Caller is not MarketFeeCollector`) } const pool = new this.web3.eth.Contract(this.poolABI, poolAddress) let result = null - const estGas = await this.estCollectMarketFee(address, poolAddress, to) + const estGas = await this.estCollectMarketFee(address, poolAddress) try { - result = await pool.methods.collectMarketFee(to).send({ + result = await pool.methods.collectMarketFee().send({ from: address, gas: estGas + 1, gasPrice: await getFairGasPrice(this.web3) @@ -671,7 +669,7 @@ export class Pool { } /** - * Estimate gas cost for collectMarketFee + * Estimate gas cost for updateMarketFeeCollector * @param {String} address * @param {String} poolAddress * @param {String} newCollector new market fee collector address diff --git a/test/unit/Datatoken.test.ts b/test/unit/Datatoken.test.ts index 0ed44792..ac52e4e5 100644 --- a/test/unit/Datatoken.test.ts +++ b/test/unit/Datatoken.test.ts @@ -217,8 +217,7 @@ describe('Datatoken', () => { ) }) - it('#setPaymentCollector - should fail to set a new feeCollector, if NOT Fee Manager', async () => { - await datatoken.removePaymentManager(datatokenAddress, nftOwner, user2) + it('#setPaymentCollector - should fail to set a new paymentCollector, if NOT PAYMENT Manager', async () => { assert( (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false ) @@ -230,14 +229,17 @@ describe('Datatoken', () => { } }) - it('#setPaymentCollector - should set a new feeCollector, if FEE MANAGER', async () => { - assert((await datatoken.getPaymentCollector(datatokenAddress)) === user2) + it('#setPaymentCollector - should set a new paymentCollector, if PAYMENT MANAGER', async () => { + assert((await datatoken.getPaymentCollector(datatokenAddress)) === user1) + + await datatoken.addPaymentManager(datatokenAddress, nftOwner, user1) assert( (await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true ) await datatoken.setPaymentCollector(datatokenAddress, user1, user3) + assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3) }) diff --git a/test/unit/pools/balancer/Pool.test.ts b/test/unit/pools/balancer/Pool.test.ts index f2d3d7bd..0577fb44 100644 --- a/test/unit/pools/balancer/Pool.test.ts +++ b/test/unit/pools/balancer/Pool.test.ts @@ -516,7 +516,7 @@ describe('Pool unit test', () => { // 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) + await pool.collectMarketFee(contracts.accounts[0], poolAddress) // DAI fees have been collected assert((await pool.getMarketFees(poolAddress, contracts.daiAddress)) === '0') // user3 got DAI @@ -1035,7 +1035,7 @@ describe('Pool unit test', () => { // user3 has no USDC (we are going to send USDC fee to him) assert((await usdcContract.methods.balanceOf(user3).call()) === '0') // only marketFeeCollector can call this, set user3 as receiver - await pool.collectMarketFee(contracts.accounts[0], poolAddress, user3) + await pool.collectMarketFee(contracts.accounts[0], poolAddress) // USDC fees have been collected assert((await pool.getMarketFees(poolAddress, contracts.usdcAddress)) === '0') // user3 got USDC From 2e9bd8c4196f5d098bb9216a586937c3ebc5ae01 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 25 Nov 2021 14:26:45 +0200 Subject: [PATCH 9/9] fixed pool unit tests --- test/unit/pools/balancer/Pool.test.ts | 30 +++------------------------ 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/test/unit/pools/balancer/Pool.test.ts b/test/unit/pools/balancer/Pool.test.ts index 0577fb44..cf670a67 100644 --- a/test/unit/pools/balancer/Pool.test.ts +++ b/test/unit/pools/balancer/Pool.test.ts @@ -99,13 +99,6 @@ describe('Pool unit test', () => { contracts.factory721Address, '10000' ) - console.log( - await pool.allowance( - contracts.daiAddress, - contracts.accounts[0], - contracts.factory721Address - ) - ) expect( await pool.allowance( contracts.daiAddress, @@ -124,11 +117,6 @@ describe('Pool unit test', () => { web3.utils.toWei('100000') ) - console.log( - await usdcContract.methods.decimals().call(), - 'USDC DECIMALS IN THIS TEST' - ) - await pool.amountToUnits(contracts.usdcAddress, '20') }) @@ -469,14 +457,11 @@ describe('Pool unit test', () => { assert(amountOut != null) - console.log(amountOut) - const spotPrice = await pool.getSpotPrice( poolAddress, contracts.daiAddress, erc20Token ) - console.log(spotPrice) // amount of DAI received will be slightly less than spotPrice assert(amountOut < spotPrice) }) @@ -511,6 +496,7 @@ describe('Pool unit test', () => { erc20Token, contracts.daiAddress ) + // 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) @@ -519,8 +505,7 @@ describe('Pool unit test', () => { await pool.collectMarketFee(contracts.accounts[0], poolAddress) // DAI fees have been collected assert((await pool.getMarketFees(poolAddress, contracts.daiAddress)) === '0') - // user3 got DAI - assert((await daiContract.methods.balanceOf(user3).call()) > '0') + // Spot price hasn't changed after fee collection assert( (await pool.getSpotPrice(poolAddress, erc20Token, contracts.daiAddress)) === @@ -964,14 +949,11 @@ describe('Pool unit test', () => { assert(amountIn != null) - console.log(amountIn.toString()) - const spotPrice = await pool.getSpotPrice( poolAddress, erc20Token, contracts.usdcAddress ) - console.log(spotPrice.toString(), 'spotPrice') // amount of USDC In will be slightly bigger than spotPrice assert(amountIn > spotPrice) }) @@ -988,14 +970,11 @@ describe('Pool unit test', () => { assert(amountOut != null) - console.log(amountOut) - const spotPrice = await pool.getSpotPrice( poolAddress, contracts.usdcAddress, erc20Token ) - console.log(spotPrice, 'spotPrice') // amount of USDC received will be slightly less than spotPrice assert(amountOut < spotPrice) }) @@ -1038,8 +1017,7 @@ describe('Pool unit test', () => { await pool.collectMarketFee(contracts.accounts[0], poolAddress) // USDC fees have been collected assert((await pool.getMarketFees(poolAddress, contracts.usdcAddress)) === '0') - // user3 got USDC - assert((await usdcContract.methods.balanceOf(user3).call()) > '0') + // Spot price hasn't changed after fee collection assert( (await pool.getSpotPrice(poolAddress, erc20Token, contracts.usdcAddress)) === @@ -1058,13 +1036,11 @@ describe('Pool unit test', () => { it('#getCurrentMarketFees- should get curent market fees for each token', async () => { const currentMarketFees: CurrentFees = await pool.getCurrentMarketFees(poolAddress) - console.log('currentMarketFees == ', currentMarketFees) assert(currentMarketFees !== null) }) it('#getCurrentOPFFees- should get curent market fees for each token', async () => { const curentOPFFees: CurrentFees = await pool.getCurrentOPFFees(poolAddress) - console.log('curentOPFFees == ', curentOPFFees) assert(curentOPFFees !== null) })