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

Merge pull request #1159 from oceanprotocol/functionChecks

Function checks & provider fee updates
This commit is contained in:
Bogdan Fazakas 2021-12-22 17:53:09 +02:00 committed by GitHub
commit f42673ef5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1093 additions and 707 deletions

994
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -28,8 +28,8 @@
"test:fixed": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/fixedRate/FixedRateExchange.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: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: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:dt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/tokens/Datatoken.test.ts'",
"test:nftDt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/NFT.test.ts'", "test:nftDt": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/Nft.test.ts'",
"test:factory": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/NftFactory.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:router": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/pools/Router.test.ts'",
"test:unit": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/**/*.test.ts'", "test:unit": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/**/*.test.ts'",
@ -57,13 +57,14 @@
"cross-fetch": "^3.1.4", "cross-fetch": "^3.1.4",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"decimal.js": "^10.2.1", "decimal.js": "^10.2.1",
"ethereumjs-util": "^7.1.3",
"fs": "0.0.1-security", "fs": "0.0.1-security",
"lzma": "^2.3.2", "lzma": "^2.3.2",
"node-abort-controller": "^2.0.0", "node-abort-controller": "^2.0.0",
"save-file": "^2.3.1", "save-file": "^2.3.1",
"underscore": "^1.13.1", "underscore": "^1.13.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"web3": "^1.6.1", "web3": ">=1.3.5",
"web3-core": "^1.6.1", "web3-core": "^1.6.1",
"web3-eth-contract": "^1.6.1" "web3-eth-contract": "^1.6.1"
}, },

View File

@ -26,11 +26,14 @@ interface Template {
export interface TokenOrder { export interface TokenOrder {
tokenAddress: string tokenAddress: string
consumer: string consumer: string
amount: string | number
serviceIndex: number serviceIndex: number
providerFeeAddress: string providerFeeAddress: string
providerFeeToken: string providerFeeToken: string
providerFeeAmount: string providerFeeAmount: string
v: number // v of provider signed message
r: string // r of provider signed message
s: string // s of provider signed message
providerData: string // data encoded by provider
} }
export interface NftCreateData { export interface NftCreateData {
@ -40,6 +43,7 @@ export interface NftCreateData {
tokenURI: string tokenURI: string
} }
const addressZERO = '0x0000000000000000000000000000000000000000'
/** /**
* Provides an interface for NFT Factory contract * Provides an interface for NFT Factory contract
*/ */
@ -88,7 +92,7 @@ export class NftFactory {
nftData.name, nftData.name,
nftData.symbol, nftData.symbol,
nftData.templateIndex, nftData.templateIndex,
'0x0000000000000000000000000000000000000000', addressZERO,
nftData.tokenURI nftData.tokenURI
) )
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
@ -112,7 +116,16 @@ export class NftFactory {
nftData.name = name nftData.name = name
nftData.symbol = symbol nftData.symbol = symbol
} }
if (nftData.templateIndex > (await this.getCurrentNFTTemplateCount())) {
throw new Error(`Template index doesnt exist`)
}
if (nftData.templateIndex === 0) {
throw new Error(`Template index cannot be ZERO`)
}
if ((await this.getNFTTemplate(nftData.templateIndex)).isActive === false) {
throw new Error(`Template is not active`)
}
const estGas = await this.estGasCreateNFT(address, nftData) const estGas = await this.estGasCreateNFT(address, nftData)
// Invoke createToken function of the contract // Invoke createToken function of the contract
@ -121,7 +134,7 @@ export class NftFactory {
nftData.name, nftData.name,
nftData.symbol, nftData.symbol,
nftData.templateIndex, nftData.templateIndex,
'0x0000000000000000000000000000000000000000', addressZERO,
nftData.tokenURI nftData.tokenURI
) )
.send({ .send({
@ -184,6 +197,13 @@ export class NftFactory {
* @return {Promise<Template>} Number of Template added to this factory * @return {Promise<Template>} Number of Template added to this factory
*/ */
public async getNFTTemplate(index: number): Promise<Template> { public async getNFTTemplate(index: number): Promise<Template> {
if (index > (await this.getCurrentNFTTemplateCount())) {
throw new Error(`Template index doesnt exist`)
}
if (index === 0) {
throw new Error(`Template index cannot be ZERO`)
}
const template = await this.factory721.methods.getNFTTemplate(index).call() const template = await this.factory721.methods.getNFTTemplate(index).call()
return template return template
} }
@ -250,6 +270,9 @@ export class NftFactory {
if ((await this.getOwner()) !== address) { if ((await this.getOwner()) !== address) {
throw new Error(`Caller is not Factory Owner`) throw new Error(`Caller is not Factory Owner`)
} }
if (templateAddress === addressZERO) {
throw new Error(`Template cannot be ZERO address`)
}
const estGas = await this.estGasAddNFTTemplate(address, templateAddress) const estGas = await this.estGasAddNFTTemplate(address, templateAddress)
@ -300,7 +323,13 @@ export class NftFactory {
if ((await this.getOwner()) !== address) { if ((await this.getOwner()) !== address) {
throw new Error(`Caller is not Factory Owner`) throw new Error(`Caller is not Factory Owner`)
} }
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
throw new Error(`Template index doesnt exist`)
}
if (templateIndex === 0) {
throw new Error(`Template index cannot be ZERO`)
}
const estGas = await this.estGasDisableNFTTemplate(address, templateIndex) const estGas = await this.estGasDisableNFTTemplate(address, templateIndex)
// Invoke createToken function of the contract // Invoke createToken function of the contract
@ -350,6 +379,13 @@ export class NftFactory {
if ((await this.getOwner()) !== address) { if ((await this.getOwner()) !== address) {
throw new Error(`Caller is not Factory Owner`) throw new Error(`Caller is not Factory Owner`)
} }
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
throw new Error(`Template index doesnt exist`)
}
if (templateIndex === 0) {
throw new Error(`Template index cannot be ZERO`)
}
const estGas = await this.estGasReactivateNFTTemplate(address, templateIndex) const estGas = await this.estGasReactivateNFTTemplate(address, templateIndex)
@ -401,6 +437,9 @@ export class NftFactory {
if ((await this.getOwner()) !== address) { if ((await this.getOwner()) !== address) {
throw new Error(`Caller is not Factory Owner`) throw new Error(`Caller is not Factory Owner`)
} }
if (templateAddress === addressZERO) {
throw new Error(`Template cannot be address ZERO`)
}
const estGas = await this.estGasAddTokenTemplate(address, templateAddress) const estGas = await this.estGasAddTokenTemplate(address, templateAddress)
@ -451,7 +490,16 @@ export class NftFactory {
if ((await this.getOwner()) !== address) { if ((await this.getOwner()) !== address) {
throw new Error(`Caller is not Factory Owner`) throw new Error(`Caller is not Factory Owner`)
} }
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
throw new Error(`Template index doesnt exist`)
}
if (templateIndex === 0) {
throw new Error(`Template index cannot be ZERO`)
}
if ((await this.getNFTTemplate(templateIndex)).isActive === false) {
throw new Error(`Template is already disabled`)
}
const estGas = await this.estGasDisableTokenTemplate(address, templateIndex) const estGas = await this.estGasDisableTokenTemplate(address, templateIndex)
// Invoke createToken function of the contract // Invoke createToken function of the contract
@ -501,6 +549,16 @@ export class NftFactory {
if ((await this.getOwner()) !== address) { if ((await this.getOwner()) !== address) {
throw new Error(`Caller is not Factory Owner`) throw new Error(`Caller is not Factory Owner`)
} }
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
throw new Error(`Template index doesnt exist`)
}
if (templateIndex === 0) {
throw new Error(`Template index cannot be ZERO`)
}
if ((await this.getTokenTemplate(templateIndex)).isActive === true) {
throw new Error(`Template is already active`)
}
const estGas = await this.estGasReactivateTokenTemplate(address, templateIndex) const estGas = await this.estGasReactivateTokenTemplate(address, templateIndex)
@ -553,6 +611,10 @@ export class NftFactory {
address: string, address: string,
orders: TokenOrder[] orders: TokenOrder[]
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
if (orders.length > 50) {
throw new Error(`Too many orders`)
}
const estGas = await this.estGasStartMultipleTokenOrder(address, orders) const estGas = await this.estGasStartMultipleTokenOrder(address, orders)
// Invoke createToken function of the contract // Invoke createToken function of the contract

View File

@ -203,7 +203,7 @@ export class Provider {
serviceType: string, serviceType: string,
consumerAddress: string, consumerAddress: string,
providerUri: string, providerUri: string,
fetchMethod: any, getMethod: any,
userCustomParameters?: UserCustomParameters userCustomParameters?: UserCustomParameters
): Promise<string> { ): Promise<string> {
const providerEndpoints = await this.getEndpoints(providerUri) const providerEndpoints = await this.getEndpoints(providerUri)
@ -224,8 +224,8 @@ export class Provider {
if (userCustomParameters) if (userCustomParameters)
initializeUrl += '&userdata=' + encodeURI(JSON.stringify(userCustomParameters)) initializeUrl += '&userdata=' + encodeURI(JSON.stringify(userCustomParameters))
try { try {
const response = await fetchMethod(initializeUrl) const response = await getMethod(initializeUrl)
return await response.text() return await response
} catch (e) { } catch (e) {
LoggerInstance.error(e) LoggerInstance.error(e)
throw new Error('Asset URL not found or not available.') throw new Error('Asset URL not found or not available.')

View File

@ -7,7 +7,7 @@ import defaultDatatokensAbi from '@oceanprotocol/contracts/artifacts/contracts/t
import defaultDatatokensEnterpriseAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json' import defaultDatatokensEnterpriseAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json'
import { LoggerInstance, getFairGasPrice } from '../utils' import { LoggerInstance, getFairGasPrice } from '../utils'
import { FreOrderParams, FreCreationParams } from '../interfaces' import { FreOrderParams, FreCreationParams } from '../interfaces'
import { Nft } from './NFT'
/** /**
* ERC20 ROLES * ERC20 ROLES
*/ */
@ -18,11 +18,14 @@ interface Roles {
export interface OrderParams { export interface OrderParams {
consumer: string consumer: string
amount: string
serviceIndex: number serviceIndex: number
providerFeeAddress: string providerFeeAddress: string
providerFeeToken: string providerFeeToken: string
providerFeeAmount: string providerFeeAmount: string
v: number // v of provider signed message
r: string // r of provider signed message
s: string // s of provider signed message
providerData: string // data encoded by provider
} }
export interface DispenserParams { export interface DispenserParams {
@ -40,6 +43,7 @@ export class Datatoken {
public datatokensEnterpriseAbi: AbiItem | AbiItem[] public datatokensEnterpriseAbi: AbiItem | AbiItem[]
public web3: Web3 public web3: Web3
public startBlock: number public startBlock: number
public nft: Nft
/** /**
* Instantiate ERC20 DataTokens * Instantiate ERC20 DataTokens
@ -57,6 +61,7 @@ export class Datatoken {
this.datatokensEnterpriseAbi = this.datatokensEnterpriseAbi =
datatokensEnterpriseAbi || (defaultDatatokensEnterpriseAbi.abi as AbiItem[]) datatokensEnterpriseAbi || (defaultDatatokensEnterpriseAbi.abi as AbiItem[])
this.startBlock = startBlock || 0 this.startBlock = startBlock || 0
this.nft = new Nft(this.web3)
} }
/** /**
@ -223,7 +228,9 @@ export class Datatoken {
fixedRateParams: FreCreationParams fixedRateParams: FreCreationParams
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
if (!(await this.isERC20Deployer(dtAddress, address))) {
throw new Error(`User is not ERC20 Deployer`)
}
if (!fixedRateParams.allowedConsumer) if (!fixedRateParams.allowedConsumer)
fixedRateParams.allowedConsumer = '0x0000000000000000000000000000000000000000' fixedRateParams.allowedConsumer = '0x0000000000000000000000000000000000000000'
@ -321,6 +328,10 @@ export class Datatoken {
dispenserAddress: string, dispenserAddress: string,
dispenserParams: DispenserParams dispenserParams: DispenserParams
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
if (!(await this.isERC20Deployer(dtAddress, address))) {
throw new Error(`User is not ERC20 Deployer`)
}
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
if (!dispenserParams.allowedSwapper) if (!dispenserParams.allowedSwapper)
@ -444,8 +455,9 @@ export class Datatoken {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
// should check ERC20Deployer role using erc721 level .. if ((await this.isERC20Deployer(dtAddress, address)) !== true) {
throw new Error(`Caller is not ERC20Deployer`)
}
// Estimate gas cost for addMinter method // Estimate gas cost for addMinter method
const estGas = await this.estGasAddMinter(dtAddress, address, minter, dtContract) const estGas = await this.estGasAddMinter(dtAddress, address, minter, dtContract)
@ -508,7 +520,9 @@ export class Datatoken {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
// should check ERC20Deployer role using erc721 level .. if ((await this.isERC20Deployer(dtAddress, address)) !== true) {
throw new Error(`Caller is not ERC20Deployer`)
}
const estGas = await this.estGasRemoveMinter(dtAddress, address, minter, dtContract) const estGas = await this.estGasRemoveMinter(dtAddress, address, minter, dtContract)
@ -568,7 +582,9 @@ export class Datatoken {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
// should check ERC20Deployer role using erc721 level .. if ((await this.isERC20Deployer(dtAddress, address)) !== true) {
throw new Error(`Caller is not ERC20Deployer`)
}
const estGas = await this.estGasAddPaymentManager( const estGas = await this.estGasAddPaymentManager(
dtAddress, dtAddress,
@ -631,7 +647,10 @@ export class Datatoken {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
// should check ERC20Deployer role using erc721 level .. if ((await this.isERC20Deployer(dtAddress, address)) !== true) {
throw new Error(`Caller is not ERC20Deployer`)
}
const estGas = await this.estGasRemovePaymentManager( const estGas = await this.estGasRemovePaymentManager(
dtAddress, dtAddress,
address, address,
@ -817,11 +836,14 @@ export class Datatoken {
* @param {String} dtAddress Datatoken address * @param {String} dtAddress Datatoken address
* @param {String} address User address which calls * @param {String} address User address which calls
* @param {String} consumer Consumer Address * @param {String} consumer Consumer Address
* @param {String} amount Amount of tokens that is going to be transfered
* @param {Number} serviceIndex Service index in the metadata * @param {Number} serviceIndex Service index in the metadata
* @param {String} providerFeeAddress Consume marketplace fee address * @param {String} providerFeeAddress Consume marketplace fee address
* @param {String} providerFeeToken address of the token marketplace wants to add fee on top * @param {String} providerFeeToken address of the token marketplace wants to add fee on top
* @param {String} providerFeeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI * @param {String} providerFeeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI
* @param {String} v // v of provider signed message
* @param {String} r // r of provider signed message
* @param {String} s // s of provider signed message
* @param {String} providerData // data encoded by provider
* @param {Contract} contractInstance optional contract instance * @param {Contract} contractInstance optional contract instance
* @return {Promise<any>} * @return {Promise<any>}
*/ */
@ -829,11 +851,14 @@ export class Datatoken {
dtAddress: string, dtAddress: string,
address: string, address: string,
consumer: string, consumer: string,
amount: string,
serviceIndex: number, serviceIndex: number,
providerFeeAddress: string, providerFeeAddress: string,
providerFeeToken: string, providerFeeToken: string,
providerFeeAmount: string, providerFeeAmount: string,
v: number,
r: string,
s: string,
providerDatas: string,
contractInstance?: Contract contractInstance?: Contract
): Promise<any> { ): Promise<any> {
const dtContract = const dtContract =
@ -846,11 +871,14 @@ export class Datatoken {
estGas = await dtContract.methods estGas = await dtContract.methods
.startOrder( .startOrder(
consumer, consumer,
this.web3.utils.toWei(amount),
serviceIndex, serviceIndex,
providerFeeAddress, providerFeeAddress,
providerFeeToken, providerFeeToken,
this.web3.utils.toWei(providerFeeAmount) this.web3.utils.toWei(providerFeeAmount),
v,
r,
s,
providerDatas
) )
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) { } catch (e) {
@ -863,23 +891,28 @@ export class Datatoken {
* @param {String} dtAddress Datatoken address * @param {String} dtAddress Datatoken address
* @param {String} address User address which calls * @param {String} address User address which calls
* @param {String} consumer Consumer Address * @param {String} consumer Consumer Address
* @param {String} amount Amount of tokens that is going to be transfered
* @param {Number} serviceIndex Service index in the metadata * @param {Number} serviceIndex Service index in the metadata
* @param {String} providerFeeAddress Consume marketplace fee address * @param {String} providerFeeAddress Consume marketplace fee address
* @param {String} providerFeeToken address of the token marketplace wants to add fee on top * @param {String} providerFeeToken address of the token marketplace wants to add fee on top
* @param {String} providerFeeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI * @param {String} providerFeeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI
* @param {String} v // v of provider signed message
* @param {String} r // r of provider signed message
* @param {String} s // s of provider signed message
* @param {String} providerData // data encoded by provider
* @return {Promise<TransactionReceipt>} string * @return {Promise<TransactionReceipt>} string
*/ */
public async startOrder( public async startOrder(
dtAddress: string, dtAddress: string,
address: string, address: string,
consumer: string, consumer: string,
amount: string,
serviceIndex: number, serviceIndex: number,
providerFeeAddress: string, providerFeeAddress: string,
providerFeeToken: string, providerFeeToken: string,
providerFeeAmount: string providerFeeAmount: string,
v: number,
r: string,
s: string,
providerDatas: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
if (!providerFeeAddress) if (!providerFeeAddress)
@ -890,22 +923,28 @@ export class Datatoken {
dtAddress, dtAddress,
address, address,
consumer, consumer,
amount,
serviceIndex, serviceIndex,
providerFeeAddress, providerFeeAddress,
providerFeeToken, providerFeeToken,
providerFeeAmount, providerFeeAmount,
v,
r,
s,
providerDatas,
dtContract dtContract
) )
const trxReceipt = await dtContract.methods const trxReceipt = await dtContract.methods
.startOrder( .startOrder(
consumer, consumer,
this.web3.utils.toWei(amount),
serviceIndex, serviceIndex,
providerFeeAddress, providerFeeAddress,
providerFeeToken, providerFeeToken,
this.web3.utils.toWei(providerFeeAmount) this.web3.utils.toWei(providerFeeAmount),
v,
r,
s,
providerDatas
) )
.send({ .send({
from: address, from: address,
@ -1098,6 +1137,10 @@ export class Datatoken {
address: string, address: string,
value: string value: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
if (!(await this.isERC20Deployer(dtAddress, address))) {
throw new Error(`User is not ERC20 Deployer`)
}
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
const estGas = await this.estGasSetData(dtAddress, address, value, dtContract) const estGas = await this.estGasSetData(dtAddress, address, value, dtContract)
@ -1150,6 +1193,9 @@ export class Datatoken {
dtAddress: string, dtAddress: string,
address: string address: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
if ((await this.nft.getNftOwner(await this.getNFTAddress(dtAddress))) !== address) {
throw new Error('Caller is NOT Nft Owner')
}
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
const estGas = await this.estGasCleanPermissions(dtAddress, address, dtContract) const estGas = await this.estGasCleanPermissions(dtAddress, address, dtContract)
@ -1208,11 +1254,11 @@ export class Datatoken {
/** Returns true if address has deployERC20 role /** Returns true if address has deployERC20 role
* @param {String} dtAddress Datatoken adress * @param {String} dtAddress Datatoken adress
* @param {String} dtAddress Datatoken adress * @param {String} dtAddress Datatoken adress
* @return {Promise<number>} * @return {Promise<boolean>}
*/ */
public async isERC20Deployer(dtAddress: string, adddress: string): Promise<string> { public async isERC20Deployer(dtAddress: string, address: string): Promise<boolean> {
const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress) const dtContract = new this.web3.eth.Contract(this.datatokensAbi, dtAddress)
const isERC20Deployer = await dtContract.methods.isERC20Deployer(adddress).call() const isERC20Deployer = await dtContract.methods.isERC20Deployer(address).call()
return isERC20Deployer return isERC20Deployer
} }

View File

@ -10,7 +10,7 @@ import { Contract } from 'web3-eth-contract'
*/ */
interface Roles { interface Roles {
manager: boolean manager: boolean
deployErc20: boolean deployERC20: boolean
updateMetadata: boolean updateMetadata: boolean
store: boolean store: boolean
} }
@ -107,6 +107,9 @@ export class Nft {
symbol?: string, symbol?: string,
templateIndex?: number templateIndex?: number
): Promise<string> { ): Promise<string> {
if ((await this.getNftPermissions(nftAddress, address)).deployERC20 !== true) {
throw new Error(`Caller is not ERC20Deployer`)
}
if (!templateIndex) templateIndex = 1 if (!templateIndex) templateIndex = 1
// Generate name & symbol if not present // Generate name & symbol if not present
@ -313,9 +316,9 @@ export class Nft {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
// if ((await this.getNFTPermissions(nftAddress, address)).manager !== true) { if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {
// throw new Error(`Caller is not Manager`) throw new Error(`Caller is not Manager`)
// } }
// Estimate gas for addToCreateERC20List method // Estimate gas for addToCreateERC20List method
const estGas = await this.estGasAddErc20Deployer( const estGas = await this.estGasAddErc20Deployer(
@ -381,10 +384,13 @@ export class Nft {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
// if ((await this.getNFTPermissions(nftAddress, address)).manager !== true) { if (
// throw new Error(`Caller is not Manager`) (await this.getNftPermissions(nftAddress, address)).manager !== true ||
// } (address === erc20Deployer &&
(await this.getNftPermissions(nftAddress, address)).deployERC20 !== true)
) {
throw new Error(`Caller is not Manager nor ERC20Deployer`)
}
const estGas = await this.estGasRemoveErc20Deployer( const estGas = await this.estGasRemoveErc20Deployer(
nftAddress, nftAddress,
address, address,
@ -447,9 +453,9 @@ export class Nft {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
// if ((await this.getNFTPermissions(nftAddress, address)).manager !== true) { if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {
// throw new Error(`Caller is not Manager`) throw new Error(`Caller is not Manager`)
// } }
const estGas = await this.estGasAddMetadataUpdater( const estGas = await this.estGasAddMetadataUpdater(
nftAddress, nftAddress,
@ -512,9 +518,13 @@ export class Nft {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
// if ((await this.getNFTPermissions(nftAddress, address)).manager !== true) { if (
// throw new Error(`Caller is not Manager`) (await this.getNftPermissions(nftAddress, address)).manager !== true ||
// } (address !== metadataUpdater &&
(await this.getNftPermissions(nftAddress, address)).updateMetadata !== true)
) {
throw new Error(`Caller is not Manager nor Metadata Updater`)
}
const estGas = await this.esGasRemoveMetadataUpdater( const estGas = await this.esGasRemoveMetadataUpdater(
nftAddress, nftAddress,
@ -578,9 +588,9 @@ export class Nft {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
// if ((await this.getNFTPermissions(nftAddress, address)).manager !== true) { if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {
// throw new Error(`Caller is not Manager`) throw new Error(`Caller is not Manager`)
// } }
const estGas = await this.estGasAddStoreUpdater( const estGas = await this.estGasAddStoreUpdater(
nftAddress, nftAddress,
@ -642,9 +652,13 @@ export class Nft {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
// if ((await this.getNFTPermissions(nftAddress, address)).manager !== true) { if (
// throw new Error(`Caller is not Manager`) (await this.getNftPermissions(nftAddress, address)).manager !== true ||
// } (address !== storeUpdater &&
(await this.getNftPermissions(nftAddress, address)).store !== true)
) {
throw new Error(`Caller is not Manager nor storeUpdater`)
}
const estGas = await this.estGasRemoveStoreUpdater( const estGas = await this.estGasRemoveStoreUpdater(
nftAddress, nftAddress,
@ -882,7 +896,7 @@ export class Nft {
/** /**
* Estimate gas cost for setMetadata method * Estimate gas cost for setMetadata method
* @param {String} nftAddress erc721 contract adress * @param {String} nftAddress erc721 contract adress
* @param {String} nftOwner Current NFT Owner adress * @param {String} metadataUpdater metadataUpdater address
* @param {Number} metadataState User which will receive the NFT, will also be set as Manager * @param {Number} metadataState User which will receive the NFT, will also be set as Manager
* @param {String} metaDataDecryptorUrl * @param {String} metaDataDecryptorUrl
* @param {Number} tokenId The id of the token to be transfered * @param {Number} tokenId The id of the token to be transfered
@ -891,7 +905,7 @@ export class Nft {
*/ */
public async estGasSetMetadata( public async estGasSetMetadata(
nftAddress: string, nftAddress: string,
nftOwner: string, metadataUpdater: string,
metadataState: number, metadataState: number,
metaDataDecryptorUrl: string, metaDataDecryptorUrl: string,
metaDataDecryptorAddress: string, metaDataDecryptorAddress: string,
@ -915,7 +929,7 @@ export class Nft {
data, data,
metadataHash metadataHash
) )
.estimateGas({ from: nftOwner }, (err, estGas) => .estimateGas({ from: metadataUpdater }, (err, estGas) =>
err ? gasLimitDefault : estGas err ? gasLimitDefault : estGas
) )
} catch (e) { } catch (e) {
@ -930,8 +944,6 @@ export class Nft {
* will clean all permissions both on erc721 and erc20 level. * will clean all permissions both on erc721 and erc20 level.
* @param {String} nftAddress erc721 contract adress * @param {String} nftAddress erc721 contract adress
* @param {String} address Caller address NFT Owner adress * @param {String} address Caller address NFT Owner adress
* @param {String} nftReceiver User which will receive the NFT, will also be set as Manager
* @param {Number} tokenId The id of the token to be transfered
* @return {Promise<TransactionReceipt>} trxReceipt * @return {Promise<TransactionReceipt>} trxReceipt
*/ */
public async setMetadata( public async setMetadata(
@ -946,9 +958,9 @@ export class Nft {
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
// if (!(await this.getNFTPermissions(nftAddress, address)).updateMetadata) { if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {
// throw new Error(`Caller is not NFT Owner`) throw new Error(`Caller is not Metadata updater`)
// } }
const estGas = await this.estGasSetMetadata( const estGas = await this.estGasSetMetadata(
nftAddress, nftAddress,
@ -981,49 +993,68 @@ export class Nft {
return trxReceipt return trxReceipt
} }
/** Get Owner /**
* Estimate gas cost for setMetadataState method
* @param {String} nftAddress erc721 contract adress * @param {String} nftAddress erc721 contract adress
* @return {Promise<string>} string * @param {String} nftOwner Current NFT Owner adress
* @param {Number} metadataState new metadata state
* @param {Contract} nftContract optional contract instance
* @return {Promise<any>}
*/ */
public async getNftOwner(nftAddress: string): Promise<string> { public async estGasSetMetadataState(
nftAddress: string,
metadataUpdater: string,
metadataState: number,
contractInstance?: Contract
): Promise<any> {
const nftContract =
contractInstance || new this.web3.eth.Contract(this.nftAbi, nftAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await nftContract.methods
.setMetaDataState(metadataState)
.estimateGas({ from: metadataUpdater }, (err, estGas) =>
err ? gasLimitDefault : estGas
)
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* setMetadataState Used for updating the metadata State
* @param {String} nftAddress erc721 contract adress
* @param {String} address Caller address => metadata updater
* @param {Number} metadataState new metadata state
* @return {Promise<TransactionReceipt>} trxReceipt
*/
public async setMetadataState(
nftAddress: string,
address: string,
metadataState: number
): Promise<TransactionReceipt> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress) const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const trxReceipt = await nftContract.methods.ownerOf(1).call()
if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {
throw new Error(`Caller is not Metadata updater`)
}
const estGas = await this.estGasSetMetadataState(nftAddress, address, metadataState)
// Call transferFrom function of the contract
const trxReceipt = await nftContract.methods.setMetaDataState(metadataState).send({
from: address,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
return trxReceipt return trxReceipt
} }
/** Get users NFT Permissions
* @param {String} nftAddress erc721 contract adress
* @param {String} address user adress
* @return {Promise<Roles>}
*/
public async getNftPermissions(nftAddress: string, address: string): Promise<Roles> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const roles = await nftContract.methods.getPermissions(address).call()
return roles
}
/** Get users ERC20Deployer role
* @param {String} nftAddress erc721 contract adress
* @param {String} address user adress
* @return {Promise<Roles>}
*/
public async isErc20Deployer(nftAddress: string, address: string): Promise<boolean> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const isERC20Deployer = await nftContract.methods.isERC20Deployer(address).call()
return isERC20Deployer
}
/** Gets data at a given `key`
* @param {String} nftAddress erc721 contract adress
* @param {String} key the key which value to retrieve
* @return {Promise<string>} The data stored at the key
*/
public async getData(nftAddress: string, key: string): Promise<string> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const data = await nftContract.methods.getData(key).call()
return data
}
/** Estimate gas cost for setTokenURI method /** Estimate gas cost for setTokenURI method
* @param nftAddress erc721 contract adress * @param nftAddress erc721 contract adress
* @param address user adress * @param address user adress
@ -1071,4 +1102,67 @@ export class Nft {
}) })
return trxReceipt return trxReceipt
} }
/** Get Owner
* @param {String} nftAddress erc721 contract adress
* @return {Promise<string>} string
*/
public async getNftOwner(nftAddress: string): Promise<string> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const trxReceipt = await nftContract.methods.ownerOf(1).call()
return trxReceipt
}
/** Get users NFT Permissions
* @param {String} nftAddress erc721 contract adress
* @param {String} address user adress
* @return {Promise<Roles>}
*/
public async getNftPermissions(nftAddress: string, address: string): Promise<Roles> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const roles = await nftContract.methods.getPermissions(address).call()
return roles
}
/** Get users Metadata, return Metadata details
* @param {String} nftAddress erc721 contract adress
* @return {Promise<Objecta>}
*/
public async getMetadata(nftAddress: string): Promise<Object> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
return await nftContract.methods.getMetaData().call()
}
/** Get users ERC20Deployer role
* @param {String} nftAddress erc721 contract adress
* @param {String} address user adress
* @return {Promise<Roles>}
*/
public async isErc20Deployer(nftAddress: string, address: string): Promise<boolean> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const isERC20Deployer = await nftContract.methods.isERC20Deployer(address).call()
return isERC20Deployer
}
/** Gets data at a given `key`
* @param {String} nftAddress erc721 contract adress
* @param {String} key the key which value to retrieve
* @return {Promise<string>} The data stored at the key
*/
public async getData(nftAddress: string, key: string): Promise<string> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const data = await nftContract.methods.getData(key).call()
return data
}
/** Gets data at a given `key`
* @param {String} nftAddress erc721 contract adress
* @param {String} id
* @return {Promise<string>} The data stored at the key
*/
public async getTokenURI(nftAddress: string, id: number): Promise<string> {
const nftContract = new this.web3.eth.Contract(this.nftAbi, nftAddress)
const data = await nftContract.methods.tokenURI(id).call()
return data
}
} }

View File

@ -2,6 +2,7 @@ import { assert, expect } from 'chai'
import { AbiItem } from 'web3-utils/types' import { AbiItem } from 'web3-utils/types'
import { TestContractHandler } from '../TestContractHandler' import { TestContractHandler } from '../TestContractHandler'
import Web3 from 'web3' import Web3 from 'web3'
import { ecsign } from 'ethereumjs-util'
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json' import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
import SideStaking from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json' import SideStaking from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
@ -20,6 +21,13 @@ import {
import { ZERO_ADDRESS } from '../../src/utils' import { ZERO_ADDRESS } from '../../src/utils'
const web3 = new Web3('http://127.0.0.1:8545') const web3 = new Web3('http://127.0.0.1:8545')
function signMessage(message, privateKey) {
const { v, r, s } = ecsign(
Buffer.from(message.slice(2), 'hex'),
Buffer.from(privateKey, 'hex')
)
return { v, r, s }
}
describe('Nft Factory test', () => { describe('Nft Factory test', () => {
let factoryOwner: string let factoryOwner: string
@ -375,27 +383,45 @@ describe('Nft Factory test', () => {
expect(await dtContract.methods.balanceOf(user2).call()).to.equal(dtAmount) expect(await dtContract.methods.balanceOf(user2).call()).to.equal(dtAmount)
expect(await dtContract2.methods.balanceOf(user2).call()).to.equal(dtAmount) expect(await dtContract2.methods.balanceOf(user2).call()).to.equal(dtAmount)
const providerData = JSON.stringify({ timeout: 0 })
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const orders: TokenOrder[] = [ const orders: TokenOrder[] = [
{ {
tokenAddress: dtAddress, tokenAddress: dtAddress,
consumer: consumer, consumer: consumer,
amount: dtAmount,
serviceIndex: serviceIndex, serviceIndex: serviceIndex,
providerFeeAddress: consumeFeeAddress, providerFeeAddress: consumeFeeAddress,
providerFeeToken: consumeFeeToken, providerFeeToken: consumeFeeToken,
providerFeeAmount: consumeFeeAmount providerFeeAmount: consumeFeeAmount,
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
}, },
{ {
tokenAddress: dtAddress2, tokenAddress: dtAddress2,
consumer: consumer, consumer: consumer,
amount: dtAmount,
serviceIndex: serviceIndex, serviceIndex: serviceIndex,
providerFeeAddress: consumeFeeAddress, providerFeeAddress: consumeFeeAddress,
providerFeeToken: consumeFeeToken, providerFeeToken: consumeFeeToken,
providerFeeAmount: consumeFeeAmount providerFeeAmount: consumeFeeAmount,
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
} }
] ]
console.log('orders', orders)
await nftFactory.startMultipleTokenOrder(user2, orders) await nftFactory.startMultipleTokenOrder(user2, orders)
// we check user2 has no more DTs // we check user2 has no more DTs

View File

@ -1,5 +1,6 @@
import { assert } from 'chai' import { assert } from 'chai'
import Web3 from 'web3' import Web3 from 'web3'
import { ecsign } from 'ethereumjs-util'
import ERC20TemplateEnterprise from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json' import ERC20TemplateEnterprise from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json'
import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json' import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
@ -19,6 +20,14 @@ import { FreCreationParams, FreOrderParams } from '../../../src/interfaces'
const web3 = new Web3('http://127.0.0.1:8545') const web3 = new Web3('http://127.0.0.1:8545')
function signMessage(message, privateKey) {
const { v, r, s } = ecsign(
Buffer.from(message.slice(2), 'hex'),
Buffer.from(privateKey, 'hex')
)
return { v, r, s }
}
describe('Datatoken', () => { describe('Datatoken', () => {
let nftOwner: string let nftOwner: string
let user1: string let user1: string
@ -127,7 +136,7 @@ describe('Datatoken', () => {
} }
}) })
it('#addMinter - should add user1 as minter, if nftDatatoken has ERC20Deployer permission', async () => { it('#addMinter - should add user1 as minter, if user has ERC20Deployer permission', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true) assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false) assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false)
@ -136,6 +145,19 @@ describe('Datatoken', () => {
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true) assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
}) })
it('#addMinter - should FAIL TO add user1 as minter, if user has ERC20Deployer permission', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user3)) === false)
assert((await datatoken.getDTPermissions(datatokenAddress, user2)).minter === false)
try {
await datatoken.addMinter(datatokenAddress, user3, user2)
} catch (e) {
assert(e.message === 'Caller is not ERC20Deployer')
}
assert((await datatoken.getDTPermissions(datatokenAddress, user2)).minter === false)
})
it('#mint - should mint ERC20 datatoken to user1, if Minter', async () => { it('#mint - should mint ERC20 datatoken to user1, if Minter', async () => {
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true) assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
await datatoken.mint(datatokenAddress, nftOwner, '10', user1) await datatoken.mint(datatokenAddress, nftOwner, '10', user1)
@ -160,6 +182,25 @@ describe('Datatoken', () => {
exchangeId = fre.events.NewFixedRate.returnValues[0] exchangeId = fre.events.NewFixedRate.returnValues[0]
}) })
it('#createFixedRate - should FAIL create FRE if NOT ERC20Deployer', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user3)) === false)
const freParams: FreCreationParams = {
fixedRateAddress: contractHandler.fixedRateAddress,
baseTokenAddress: contractHandler.daiAddress,
owner: nftOwner,
marketFeeCollector: nftOwner,
baseTokenDecimals: 18,
dataTokenDecimals: 18,
fixedRate: web3.utils.toWei('1'),
marketFee: 1e15
}
try {
await datatoken.createFixedRate(datatokenAddress, user3, freParams)
} catch (e) {
assert(e.message === 'User is not ERC20 Deployer')
}
})
it('#createDispenser - method creates a dispenser for the erc20DT', async () => { it('#createDispenser - method creates a dispenser for the erc20DT', async () => {
const dispenserParams: DispenserParams = { const dispenserParams: DispenserParams = {
maxTokens: '10', maxTokens: '10',
@ -175,6 +216,36 @@ describe('Datatoken', () => {
assert(dispenser !== null) assert(dispenser !== null)
}) })
it('#createDispenser - should FAIL to create a Dispenser if not ERC20 Deployer', async () => {
const dispenserParams: DispenserParams = {
maxTokens: '10',
maxBalance: '100'
}
assert((await nftDatatoken.isErc20Deployer(nftAddress, user3)) === false)
try {
await datatoken.createDispenser(
datatokenAddress,
user2,
contractHandler.dispenserAddress,
dispenserParams
)
} catch (e) {
assert(e.message === 'User is not ERC20 Deployer')
}
})
it('#removeMinter - should FAIL to remove user1 as minter, if caller is NOT ERC20Deployer', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user2)) === false)
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
try {
await datatoken.removeMinter(datatokenAddress, user2, user1)
} catch (e) {
assert(e.message === 'Caller is not ERC20Deployer')
}
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
})
it('#removeMinter - should remove user1 as minter, if nftDatatoken has ERC20Deployer permission', async () => { it('#removeMinter - should remove user1 as minter, if nftDatatoken has ERC20Deployer permission', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true) assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true) assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
@ -184,7 +255,23 @@ describe('Datatoken', () => {
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false) assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false)
}) })
it('#addPaymentManager - should add user2 as paymentManager, if nftDatatoken has ERC20Deployer permission', async () => { it('#addPaymentManager - should FAIL TO add user2 as paymentManager, if caller is NOT ERC20Deployer', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
assert(
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
)
try {
await datatoken.addPaymentManager(datatokenAddress, user1, user2)
} catch (e) {
assert(e.message === 'Caller is not ERC20Deployer')
}
assert(
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
)
})
it('#addPaymentManager - should add user2 as paymentManager, if caller has ERC20Deployer permission', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true) assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
assert( assert(
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
@ -197,7 +284,23 @@ describe('Datatoken', () => {
) )
}) })
it('#removePaymentManager - should remove user2 as paymentManager, if nftDatatoken has ERC20Deployer permission', async () => { it('#removePaymentManager - should FAIL TO remove user2 as paymentManager, if nftDatatoken has ERC20Deployer permission', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
assert(
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true
)
try {
await datatoken.removePaymentManager(datatokenAddress, user1, user2)
} catch (e) {
assert(e.message === 'Caller is not ERC20Deployer')
}
assert(
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true
)
})
it('#removePaymentManager - should remove user2 as paymentManager, if Caller has ERC20Deployer permission', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true) assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
assert( assert(
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true (await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true
@ -246,15 +349,30 @@ describe('Datatoken', () => {
'User2 does not hold 0 datatokens' 'User2 does not hold 0 datatokens'
) )
const providerData = JSON.stringify({ timeout: 0 })
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const order = await datatoken.startOrder( const order = await datatoken.startOrder(
datatokenAddress, datatokenAddress,
user1, user1,
user2, user2,
'1',
1, 1,
user3, user3,
'0x0000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000',
'0' '0',
signedMessage.v,
web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
web3.utils.toHex(web3.utils.asciiToHex(providerData))
) )
assert(order !== null) assert(order !== null)
@ -272,15 +390,30 @@ describe('Datatoken', () => {
}) })
it('#buyFromDispenserAndOrder- Enterprise method', async () => { it('#buyFromDispenserAndOrder- Enterprise method', async () => {
const providerData = JSON.stringify({ timeout: 0 })
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const order: OrderParams = { const order: OrderParams = {
consumer: user1, consumer: user1,
amount: '1',
serviceIndex: 1, serviceIndex: 1,
providerFeeAddress: user1, providerFeeAddress: user3,
providerFeeToken: '0x0000000000000000000000000000000000000000', providerFeeToken: '0x0000000000000000000000000000000000000000',
providerFeeAmount: '0' providerFeeAmount: '0',
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
} }
console.log('order', order)
const buyFromDispenseTx = await datatoken.buyFromDispenserAndOrder( const buyFromDispenseTx = await datatoken.buyFromDispenserAndOrder(
datatokenAddress, datatokenAddress,
nftOwner, nftOwner,
@ -291,13 +424,28 @@ describe('Datatoken', () => {
}) })
it('#buyFromFreAndOrder - Enterprise method ', async () => { it('#buyFromFreAndOrder - Enterprise method ', async () => {
const providerData = JSON.stringify({ timeout: 0 })
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const order: OrderParams = { const order: OrderParams = {
consumer: user1, consumer: user1,
amount: '1',
serviceIndex: 1, serviceIndex: 1,
providerFeeAddress: user1, providerFeeAddress: user1,
providerFeeToken: '0x0000000000000000000000000000000000000000', providerFeeToken: '0x0000000000000000000000000000000000000000',
providerFeeAmount: '0' providerFeeAmount: '0',
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
} }
const fre: FreOrderParams = { const fre: FreOrderParams = {
@ -312,6 +460,30 @@ describe('Datatoken', () => {
assert(buyTx !== null) assert(buyTx !== null)
}) })
it('#cleanPermissions - should FAIL to clean permissions at ERC20 level, if NOT NFT Owner', async () => {
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3)
assert(
(await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true
)
try {
await datatoken.cleanPermissions(datatokenAddress, user2)
} catch (e) {
assert(e.message === 'Caller is NOT Nft Owner')
}
assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3)
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
assert(
(await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true
)
})
it('#cleanPermissions - should clean permissions at ERC20 level', async () => { it('#cleanPermissions - should clean permissions at ERC20 level', async () => {
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true) assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
@ -339,7 +511,7 @@ describe('Datatoken', () => {
assert(address, 'Not able to get the parent ERC721 address') 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 () => { it('#setData - should set a value into 725Y standard, if Caller has ERC20Deployer permission', async () => {
const data = web3.utils.asciiToHex('SomeData') const data = web3.utils.asciiToHex('SomeData')
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true) assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
@ -349,4 +521,18 @@ describe('Datatoken', () => {
const key = web3.utils.keccak256(datatokenAddress) const key = web3.utils.keccak256(datatokenAddress)
assert((await nftDatatoken.getData(nftAddress, key)) === data) assert((await nftDatatoken.getData(nftAddress, key)) === data)
}) })
it('#setData - should FAIL to set a value into 725Y standard, if Caller has NOT ERC20Deployer permission', async () => {
const data = web3.utils.asciiToHex('NewData')
const OldData = web3.utils.asciiToHex('SomeData')
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
try {
await datatoken.setData(datatokenAddress, user1, data)
} catch (e) {
assert(e.message === 'User is not ERC20 Deployer')
}
const key = web3.utils.keccak256(datatokenAddress)
assert((await nftDatatoken.getData(nftAddress, key)) === OldData)
})
}) })

View File

@ -78,6 +78,11 @@ describe('NFT', () => {
nftAddress = await nftFactory.createNFT(nftOwner, nftData) nftAddress = await nftFactory.createNFT(nftOwner, nftData)
nftDatatoken = new Nft(web3, ERC721Template.abi as AbiItem[]) nftDatatoken = new Nft(web3, ERC721Template.abi as AbiItem[])
}) })
it('#getTokenURI', async () => {
const tokenURI = await nftDatatoken.getTokenURI(nftAddress, 1)
assert(tokenURI === 'https://oceanprotocol.com/nft/')
console.log(tokenURI)
})
it('#createERC20 - should create a new ERC20 DT from NFT contract', async () => { it('#createERC20 - should create a new ERC20 DT from NFT contract', async () => {
const erc20Address = await nftDatatoken.createErc20( const erc20Address = await nftDatatoken.createErc20(
@ -96,6 +101,26 @@ describe('NFT', () => {
assert(erc20Address !== null) assert(erc20Address !== null)
}) })
it('#createERC20 - should fail to create a new ERC20 DT if not ERC20Deployer', async () => {
try {
await nftDatatoken.createErc20(
nftAddress,
user1,
nftOwner,
user1,
user2,
'0x0000000000000000000000000000000000000000',
'0',
'10000',
nftName,
nftSymbol,
1
)
} catch (e) {
assert(e.message === 'Caller is not ERC20Deployer')
}
})
// Manager // Manager
it('#addManager - should add a new Manager', async () => { it('#addManager - should add a new Manager', async () => {
assert((await nftDatatoken.getNftPermissions(nftAddress, user1)).manager === false) assert((await nftDatatoken.getNftPermissions(nftAddress, user1)).manager === false)
@ -138,14 +163,19 @@ describe('NFT', () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true) assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
}) })
it('#addManager - should fail to add a new Manager, if NOT NFT Owner', async () => {
try {
await nftDatatoken.addManager(nftAddress, user1, user1)
} catch (e) {
assert(e.message === 'Caller is not NFT Owner')
}
})
it('#addERC20Deployer - should fail to add ERC20deployer if NOT Manager', async () => { it('#addERC20Deployer - should fail to add ERC20deployer if NOT Manager', async () => {
try { try {
await nftDatatoken.addErc20Deployer(nftAddress, user1, user1) await nftDatatoken.addErc20Deployer(nftAddress, user1, user1)
} catch (e) { } catch (e) {
assert( assert(e.message === 'Caller is not Manager')
e.message ===
'Returned error: VM Exception while processing transaction: revert ERC721RolesAddress: NOT MANAGER'
)
} }
}) })
@ -157,15 +187,25 @@ describe('NFT', () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false) assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
}) })
it('#removeERC20Deployer - should fail and remove ERC20deployer if NOT Manager', async () => { it('#removeERC20Deployer - should fail and remove ERC20deployer if NOT Manager nor himself an ERC20Deployer', async () => {
await nftDatatoken.addErc20Deployer(nftAddress, nftOwner, user1)
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
try { try {
await nftDatatoken.removeErc20Deployer(nftAddress, user1, user1) await nftDatatoken.removeErc20Deployer(nftAddress, user1, user1)
} catch (e) { } catch (e) {
assert( assert(e.message === 'Caller is not Manager nor ERC20Deployer')
e.message ===
'Returned error: VM Exception while processing transaction: revert ERC721RolesAddress: Not enough permissions to remove from ERC20List'
)
} }
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
})
it('#removeERC20Deployer - should fail to remove himself an ERC20Deployer', async () => {
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
try {
await nftDatatoken.removeErc20Deployer(nftAddress, user1, user1)
} catch (e) {
assert(e.message === 'Caller is not Manager nor ERC20Deployer')
}
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
}) })
// MetadataUpdate // MetadataUpdate
@ -185,10 +225,7 @@ describe('NFT', () => {
try { try {
await nftDatatoken.addMetadataUpdater(nftAddress, user1, user1) await nftDatatoken.addMetadataUpdater(nftAddress, user1, user1)
} catch (e) { } catch (e) {
assert( assert(e.message === 'Caller is not Manager')
e.message ===
'Returned error: VM Exception while processing transaction: revert ERC721RolesAddress: NOT MANAGER'
)
} }
}) })
@ -208,10 +245,7 @@ describe('NFT', () => {
try { try {
await nftDatatoken.removeMetadataUpdater(nftAddress, user1, user1) await nftDatatoken.removeMetadataUpdater(nftAddress, user1, user1)
} catch (e) { } catch (e) {
assert( assert(e.message === 'Caller is not Manager nor Metadata Updater')
e.message ===
'Returned error: VM Exception while processing transaction: revert ERC721RolesAddress: Not enough permissions to remove from metadata list'
)
} }
}) })
@ -228,10 +262,7 @@ describe('NFT', () => {
try { try {
await nftDatatoken.addStoreUpdater(nftAddress, user1, user1) await nftDatatoken.addStoreUpdater(nftAddress, user1, user1)
} catch (e) { } catch (e) {
assert( assert(e.message === 'Caller is not Manager')
e.message ===
'Returned error: VM Exception while processing transaction: revert ERC721RolesAddress: NOT MANAGER'
)
} }
}) })
@ -247,10 +278,7 @@ describe('NFT', () => {
try { try {
await nftDatatoken.removeStoreUpdater(nftAddress, user1, user1) await nftDatatoken.removeStoreUpdater(nftAddress, user1, user1)
} catch (e) { } catch (e) {
assert( assert(e.message === `Caller is not Manager nor storeUpdater`)
e.message ===
'Returned error: VM Exception while processing transaction: revert ERC721RolesAddress: Not enough permissions to remove from 725StoreList'
)
} }
}) })
@ -298,6 +326,93 @@ describe('NFT', () => {
assert((await nftDatatoken.getNftPermissions(nftAddress, nftOwner)).manager === false) assert((await nftDatatoken.getNftPermissions(nftAddress, nftOwner)).manager === false)
}) })
it('#setMetaData - should succeed to update metadata if metadataUpdater', async () => {
await nftDatatoken.addManager(nftAddress, user1, user1)
await nftDatatoken.addMetadataUpdater(nftAddress, user1, user1)
const metaDataDecryptorUrl = 'http://myprovider:8030'
const metaDataDecryptorAddress = '0x123'
const metaDataState = 1
const data = web3.utils.asciiToHex(user2)
const dataHash = web3.utils.asciiToHex(user2)
const flags = web3.utils.asciiToHex(user2)
assert(
(await nftDatatoken.getNftPermissions(nftAddress, user1)).updateMetadata === true
)
await nftDatatoken.setMetadata(
nftAddress,
user1,
metaDataState,
metaDataDecryptorUrl,
metaDataDecryptorAddress,
flags,
data,
dataHash
)
const metadata = await nftDatatoken.getMetadata(nftAddress)
assert(metadata[0] === metaDataDecryptorUrl)
assert(metadata[1] === metaDataDecryptorAddress)
// assert((await nftDatatoken.getMetadata(nftAddress)).metaDataDecryptorAddress === metaDataDecryptorAddress)
})
it('#setMetaData - should fail to update metadata if NOT metadataUpdater', async () => {
const metaDataDecryptorUrl = 'http://myprovider:8030'
const metaDataDecryptorAddress = '0x123'
const metaDataState = 1
const data = web3.utils.asciiToHex(user2)
const dataHash = web3.utils.asciiToHex(user2)
const flags = web3.utils.asciiToHex(user2)
assert(
(await nftDatatoken.getNftPermissions(nftAddress, user3)).updateMetadata === false
)
try {
await nftDatatoken.setMetadata(
nftAddress,
user3,
metaDataState,
metaDataDecryptorUrl,
metaDataDecryptorAddress,
flags,
data,
dataHash
)
} catch (e) {
assert(e.message === 'Caller is not Metadata updater')
}
assert(
(await nftDatatoken.getNftPermissions(nftAddress, user3)).updateMetadata === false
)
})
it('#setMetaDataState - should succeed to update MetadataState if metadataUpdater', async () => {
await nftDatatoken.addManager(nftAddress, user1, user1)
await nftDatatoken.addMetadataUpdater(nftAddress, user1, user1)
let metadata = await nftDatatoken.getMetadata(nftAddress)
assert(metadata[2] === '1')
assert(
(await nftDatatoken.getNftPermissions(nftAddress, user1)).updateMetadata === true
)
await nftDatatoken.setMetadataState(nftAddress, user1, 2)
metadata = await nftDatatoken.getMetadata(nftAddress)
assert(metadata[2] === '2')
})
it('#setMetaDataState - should fail to update MetadataState if NOT metadataUpdater', async () => {
let metadata = await nftDatatoken.getMetadata(nftAddress)
assert(metadata[2] === '2')
assert(
(await nftDatatoken.getNftPermissions(nftAddress, user3)).updateMetadata === false
)
try {
await nftDatatoken.setMetadataState(nftAddress, user3, 1)
} catch (e) {
assert(e.message === 'Caller is not Metadata updater')
}
metadata = await nftDatatoken.getMetadata(nftAddress)
assert(metadata[2] === '2')
})
it('#setTokenURI - should update TokenURI', async () => { it('#setTokenURI - should update TokenURI', async () => {
const tx = await nftDatatoken.setTokenURI(nftAddress, user1, 'test') const tx = await nftDatatoken.setTokenURI(nftAddress, user1, 'test')
assert(tx.events.TokenURIUpdate) assert(tx.events.TokenURIUpdate)