mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
Merge branch 'v4main' into feature/integrate-erc721-erc20-template-contracts
This commit is contained in:
commit
39f7de6c1a
@ -24,7 +24,7 @@
|
|||||||
"release": "release-it --non-interactive",
|
"release": "release-it --non-interactive",
|
||||||
"changelog": "auto-changelog -p",
|
"changelog": "auto-changelog -p",
|
||||||
"prepublishOnly": "npm run build",
|
"prepublishOnly": "npm run build",
|
||||||
"test:pool": "mocha --config=test/unit/.mocharc.json --node-env=test --exit 'test/unit/NFTFactory.test.ts'",
|
"test:pool": "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'",
|
||||||
"test:unit:cover": "nyc --report-dir coverage/unit npm run test:unit",
|
"test:unit:cover": "nyc --report-dir coverage/unit npm run test:unit",
|
||||||
"test:integration": "mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/**/*.test.ts'",
|
"test:integration": "mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/**/*.test.ts'",
|
||||||
|
@ -9,8 +9,45 @@ interface Template {
|
|||||||
templateAddress: string
|
templateAddress: string
|
||||||
isActive: boolean
|
isActive: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TokenOrder {
|
||||||
|
tokenAddress: string
|
||||||
|
consumer: string
|
||||||
|
amount: string | number
|
||||||
|
serviceId: number
|
||||||
|
consumeFeeAddress: string
|
||||||
|
consumeFeeToken: string // address of the token marketplace wants to add fee on top
|
||||||
|
consumeFeeAmount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NFTCreateData {
|
||||||
|
name: string
|
||||||
|
symbol: string
|
||||||
|
templateIndex: number
|
||||||
|
baseURI: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ErcCreateData {
|
||||||
|
templateIndex: number
|
||||||
|
strings: string[]
|
||||||
|
addresses: string[]
|
||||||
|
uints: (string | number)[]
|
||||||
|
bytess: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PoolData {
|
||||||
|
addresses: string[]
|
||||||
|
ssParams: (string | number)[]
|
||||||
|
swapFees: number[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FixedData {
|
||||||
|
fixedPriceAddress: string
|
||||||
|
addresses: string[]
|
||||||
|
uints: (string | number)[]
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Provides an interface for NFT DataTokens
|
* Provides an interface for NFT Factory contract
|
||||||
*/
|
*/
|
||||||
export class NFTFactory {
|
export class NFTFactory {
|
||||||
public GASLIMIT_DEFAULT = 1000000
|
public GASLIMIT_DEFAULT = 1000000
|
||||||
@ -149,6 +186,24 @@ export class NFTFactory {
|
|||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if ERC20 is deployed from the factory
|
||||||
|
* @param {String} datatoken Datatoken address we want to check
|
||||||
|
* @return {Promise<Boolean>} return true if deployed from this factory
|
||||||
|
*/
|
||||||
|
public async checkDatatoken(datatoken: string): Promise<Boolean> {
|
||||||
|
const isDeployed = await this.factory721.methods.erc20List(datatoken).call()
|
||||||
|
return isDeployed
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if NFT is deployed from the factory
|
||||||
|
* @param {String} nftAddress nftAddress address we want to check
|
||||||
|
* @return {Promise<String>} return address(0) if it's not, or the nftAddress if true
|
||||||
|
*/
|
||||||
|
public async checkNFT(nftAddress: string): Promise<String> {
|
||||||
|
const confirmAddress = await this.factory721.methods.erc721List(nftAddress).call()
|
||||||
|
return confirmAddress
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new erc721 token template - only factory Owner
|
* Add a new erc721 token template - only factory Owner
|
||||||
* @param {String} address
|
* @param {String} address
|
||||||
@ -364,4 +419,157 @@ export class NFTFactory {
|
|||||||
|
|
||||||
return trxReceipt
|
return trxReceipt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev startMultipleTokenOrder
|
||||||
|
* Used as a proxy to order multiple services
|
||||||
|
* Users can have inifinite approvals for fees for factory instead of having one approval/ erc20 contract
|
||||||
|
* Requires previous approval of all :
|
||||||
|
* - consumeFeeTokens
|
||||||
|
* - publishMarketFeeTokens
|
||||||
|
* - erc20 datatokens
|
||||||
|
* @param orders an array of struct tokenOrder
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async startMultipleTokenOrder(
|
||||||
|
address: string,
|
||||||
|
orders: TokenOrder[]
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.startMultipleTokenOrder(orders)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.startMultipleTokenOrder(orders)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev createNftWithErc
|
||||||
|
* Creates a new NFT, then a ERC20,all in one call
|
||||||
|
* @param _NftCreateData input data for nft creation
|
||||||
|
* @param _ErcCreateData input data for erc20 creation
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async createNftWithErc(
|
||||||
|
address: string,
|
||||||
|
nftCreateData: NFTCreateData,
|
||||||
|
ercCreateData: ErcCreateData
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.createNftWithErc(nftCreateData, ercCreateData)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.createNftWithErc(nftCreateData, ercCreateData)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev createNftErcWithPool
|
||||||
|
* Creates a new NFT, then a ERC20, then a Pool, all in one call
|
||||||
|
* Use this carefully, because if Pool creation fails, you are still going to pay a lot of gas
|
||||||
|
* @param _NftCreateData input data for NFT Creation
|
||||||
|
* @param _ErcCreateData input data for ERC20 Creation
|
||||||
|
* @param _PoolData input data for Pool Creation
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async createNftErcWithPool(
|
||||||
|
address: string,
|
||||||
|
nftCreateData: NFTCreateData,
|
||||||
|
ercCreateData: ErcCreateData,
|
||||||
|
poolData: PoolData
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.createNftErcWithPool(nftCreateData, ercCreateData, poolData)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.createNftErcWithPool(nftCreateData, ercCreateData, poolData)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev createNftErcWithFixedRate
|
||||||
|
* Creates a new NFT, then a ERC20, then a FixedRateExchange, all in one call
|
||||||
|
* Use this carefully, because if Fixed Rate creation fails, you are still going to pay a lot of gas
|
||||||
|
* @param _NftCreateData input data for NFT Creation
|
||||||
|
* @param _ErcCreateData input data for ERC20 Creation
|
||||||
|
* @param _FixedData input data for FixedRate Creation
|
||||||
|
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async createNftErcWithFixedRate(
|
||||||
|
address: string,
|
||||||
|
nftCreateData: NFTCreateData,
|
||||||
|
ercCreateData: ErcCreateData,
|
||||||
|
fixedData: FixedData
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.factory721.methods
|
||||||
|
.createNftErcWithFixedRate(nftCreateData, ercCreateData, fixedData)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.factory721.methods
|
||||||
|
.createNftErcWithFixedRate(nftCreateData, ercCreateData, fixedData)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
378
src/pools/Router.ts
Normal file
378
src/pools/Router.ts
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
import { Contract } from 'web3-eth-contract'
|
||||||
|
import Web3 from 'web3'
|
||||||
|
import { TransactionReceipt } from 'web3-core'
|
||||||
|
import { AbiItem } from 'web3-utils'
|
||||||
|
import defaultRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
|
||||||
|
import { Logger, getFairGasPrice, generateDtName } from '../utils'
|
||||||
|
|
||||||
|
interface Operations {
|
||||||
|
exchangeIds: string
|
||||||
|
source: string
|
||||||
|
operation: number
|
||||||
|
tokenIn: string
|
||||||
|
amountsIn: string | number
|
||||||
|
tokenOut: string
|
||||||
|
amountsOut: string | number
|
||||||
|
maxPrice: string | number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an interface for FactoryRouter contract
|
||||||
|
*/
|
||||||
|
export class Router {
|
||||||
|
public GASLIMIT_DEFAULT = 1000000
|
||||||
|
public routerAddress: string
|
||||||
|
public RouterABI: AbiItem | AbiItem[]
|
||||||
|
public web3: Web3
|
||||||
|
private logger: Logger
|
||||||
|
public startBlock: number
|
||||||
|
public router: Contract
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate Router.
|
||||||
|
* @param {String} routerAddress
|
||||||
|
* @param {AbiItem | AbiItem[]} Router
|
||||||
|
* @param {Web3} web3
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
routerAddress: string,
|
||||||
|
web3: Web3,
|
||||||
|
logger: Logger,
|
||||||
|
RouterABI?: AbiItem | AbiItem[],
|
||||||
|
startBlock?: number
|
||||||
|
) {
|
||||||
|
this.routerAddress = routerAddress
|
||||||
|
this.RouterABI = RouterABI || (defaultRouter.abi as AbiItem[])
|
||||||
|
this.web3 = web3
|
||||||
|
this.logger = logger
|
||||||
|
this.startBlock = startBlock || 0
|
||||||
|
this.router = new this.web3.eth.Contract(this.RouterABI, this.routerAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuyDTBatch
|
||||||
|
* @param {String} address
|
||||||
|
* @param {Operations} operations Operations objects array
|
||||||
|
* @return {Promise<TransactionReceipt>} Transaction receipt
|
||||||
|
*/
|
||||||
|
public async buyDTBatch(
|
||||||
|
address: string,
|
||||||
|
operations: Operations[]
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
// Get estimated gas value
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.buyDTBatch(operations)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods.buyDTBatch(operations).send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if a token is on ocean tokens list, if true opfFee is ZERO in pools with that token/DT
|
||||||
|
* @return {Promise<boolean>} true if is on the list.
|
||||||
|
*/
|
||||||
|
public async isOceanTokens(address: string): Promise<boolean> {
|
||||||
|
return await this.router.methods.oceanTokens(address).call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if an address is a side staking contract.
|
||||||
|
* @return {Promise<boolean>} true if is a SS contract
|
||||||
|
*/
|
||||||
|
public async isSideStaking(address: string): Promise<boolean> {
|
||||||
|
return await this.router.methods.ssContracts(address).call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if an address is a Fixed Rate contract.
|
||||||
|
* @return {Promise<boolean>} true if is a Fixed Rate contract
|
||||||
|
*/
|
||||||
|
public async isFixedPrice(address: string): Promise<boolean> {
|
||||||
|
return await this.router.methods.fixedPrice(address).call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get Router Owner
|
||||||
|
* @return {Promise<string>} Router Owner address
|
||||||
|
*/
|
||||||
|
public async getOwner(): Promise<string> {
|
||||||
|
return await this.router.methods.routerOwner().call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get NFT Factory address
|
||||||
|
* @return {Promise<string>} NFT Factory address
|
||||||
|
*/
|
||||||
|
public async getNFTFactory(): Promise<string> {
|
||||||
|
return await this.router.methods.factory().call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if an address is a pool template contract.
|
||||||
|
* @return {Promise<boolean>} true if is a Template
|
||||||
|
*/
|
||||||
|
public async isPoolTemplate(address: string): Promise<boolean> {
|
||||||
|
return await this.router.methods.isPoolTemplate(address).call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new token to oceanTokens list, pools with basetoken in this list have NO opf Fee
|
||||||
|
* @param {String} address
|
||||||
|
* @param {String} tokenAddress template address to add
|
||||||
|
* @return {Promise<TransactionReceipt>}
|
||||||
|
*/
|
||||||
|
public async addOceanToken(
|
||||||
|
address: string,
|
||||||
|
tokenAddress: string
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
if ((await this.getOwner()) !== address) {
|
||||||
|
throw new Error(`Caller is not Router Owner`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.addOceanToken(tokenAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods.addOceanToken(tokenAddress).send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a token from oceanTokens list, pools without basetoken in this list have a opf Fee
|
||||||
|
* @param {String} address
|
||||||
|
* @param {String} tokenAddress address to remove
|
||||||
|
* @return {Promise<TransactionReceipt>}
|
||||||
|
*/
|
||||||
|
public async removeOceanToken(
|
||||||
|
address: string,
|
||||||
|
tokenAddress: string
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
if ((await this.getOwner()) !== address) {
|
||||||
|
throw new Error(`Caller is not Router Owner`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.removeOceanToken(tokenAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods.removeOceanToken(tokenAddress).send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new contract to ssContract list, after is added, can be used when deploying a new pool
|
||||||
|
* @param {String} address
|
||||||
|
* @param {String} tokenAddress contract address to add
|
||||||
|
* @return {Promise<TransactionReceipt>}
|
||||||
|
*/
|
||||||
|
public async addSSContract(
|
||||||
|
address: string,
|
||||||
|
tokenAddress: string
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
if ((await this.getOwner()) !== address) {
|
||||||
|
throw new Error(`Caller is not Router Owner`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.addSSContract(tokenAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods.addSSContract(tokenAddress).send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new contract to fixedRate list, after is added, can be used when deploying a new pool
|
||||||
|
* @param {String} address
|
||||||
|
* @param {String} tokenAddress contract address to add
|
||||||
|
* @return {Promise<TransactionReceipt>}
|
||||||
|
*/
|
||||||
|
public async addFixedRateContract(
|
||||||
|
address: string,
|
||||||
|
tokenAddress: string
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
if ((await this.getOwner()) !== address) {
|
||||||
|
throw new Error(`Caller is not Router Owner`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.addFixedRateContract(tokenAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods.addFixedRateContract(tokenAddress).send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get OPF Fee per token
|
||||||
|
* @return {Promise<number>} OPF fee for a specific baseToken
|
||||||
|
*/
|
||||||
|
public async getOPFFee(baseToken: string): Promise<number> {
|
||||||
|
return await this.router.methods.getOPFFee(baseToken).call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get Current OPF Fee
|
||||||
|
* @return {Promise<number>} OPF fee
|
||||||
|
*/
|
||||||
|
public async getCurrentOPFFee(): Promise<number> {
|
||||||
|
return await this.router.methods.swapOceanFee().call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new contract to fixedRate list, after is added, can be used when deploying a new pool
|
||||||
|
* @param {String} address
|
||||||
|
* @param {String} newFee new OPF Fee
|
||||||
|
* @return {Promise<TransactionReceipt>}
|
||||||
|
*/
|
||||||
|
public async updateOPFFee(
|
||||||
|
address: string,
|
||||||
|
newFee: number
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
if ((await this.getOwner()) !== address) {
|
||||||
|
throw new Error(`Caller is not Router Owner`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.updateOPFFee(newFee)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods.updateOPFFee(newFee).send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new template to poolTemplates mapping, after template is added,it can be used
|
||||||
|
* @param {String} address
|
||||||
|
* @param {String} templateAddress template address to add
|
||||||
|
* @return {Promise<TransactionReceipt>}
|
||||||
|
*/
|
||||||
|
public async addPoolTemplate(
|
||||||
|
address: string,
|
||||||
|
templateAddress: string
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
if ((await this.getOwner()) !== address) {
|
||||||
|
throw new Error(`Caller is not Router Owner`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.addPoolTemplate(templateAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods.addPoolTemplate(templateAddress).send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove template from poolTemplates mapping, after template is removed,it can be used anymore
|
||||||
|
* @param {String} address
|
||||||
|
* @param {String} templateAddress template address to remove
|
||||||
|
* @return {Promise<TransactionReceipt>}
|
||||||
|
*/
|
||||||
|
public async removePoolTemplate(
|
||||||
|
address: string,
|
||||||
|
templateAddress: string
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
if ((await this.getOwner()) !== address) {
|
||||||
|
throw new Error(`Caller is not Router Owner`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gasLimitDefault = this.GASLIMIT_DEFAULT
|
||||||
|
let estGas
|
||||||
|
try {
|
||||||
|
estGas = await this.router.methods
|
||||||
|
.removePoolTemplate(templateAddress)
|
||||||
|
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
|
||||||
|
} catch (e) {
|
||||||
|
estGas = gasLimitDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke createToken function of the contract
|
||||||
|
const trxReceipt = await this.router.methods
|
||||||
|
.removePoolTemplate(templateAddress)
|
||||||
|
.send({
|
||||||
|
from: address,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: await getFairGasPrice(this.web3)
|
||||||
|
})
|
||||||
|
|
||||||
|
return trxReceipt
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
import { Contract } from 'web3-eth-contract'
|
import { Contract } from 'web3-eth-contract'
|
||||||
import { AbiItem } from 'web3-utils/types'
|
import { AbiItem } from 'web3-utils/types'
|
||||||
|
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
||||||
// TODO: add OPF deployment
|
// TODO: add OPF deployment
|
||||||
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
|
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
|
||||||
const oceanAddress = '0x967da4048cd07ab37855c090aaf366e4ce1b9f48'
|
const oceanAddress = '0x967da4048cd07ab37855c090aaf366e4ce1b9f48'
|
||||||
@ -16,6 +16,8 @@ export class TestContractHandler {
|
|||||||
public Dispenser: Contract
|
public Dispenser: Contract
|
||||||
public OPFCollector: Contract
|
public OPFCollector: Contract
|
||||||
public PoolTemplate: Contract
|
public PoolTemplate: Contract
|
||||||
|
public MockERC20: Contract
|
||||||
|
public MockOcean: Contract
|
||||||
|
|
||||||
public ERC721FactoryBytecode: string
|
public ERC721FactoryBytecode: string
|
||||||
public ERC20TemplateBytecode: string
|
public ERC20TemplateBytecode: string
|
||||||
@ -26,6 +28,7 @@ export class TestContractHandler {
|
|||||||
public DispenserBytecode: string
|
public DispenserBytecode: string
|
||||||
public PoolTemplateBytecode: string
|
public PoolTemplateBytecode: string
|
||||||
public OPFCollectorBytecode: string
|
public OPFCollectorBytecode: string
|
||||||
|
public MockERC20Bytecode: string
|
||||||
|
|
||||||
public factory721Address: string
|
public factory721Address: string
|
||||||
public template721Address: string
|
public template721Address: string
|
||||||
@ -36,7 +39,9 @@ export class TestContractHandler {
|
|||||||
public dispenserAddress: string
|
public dispenserAddress: string
|
||||||
public poolTemplateAddress: string
|
public poolTemplateAddress: string
|
||||||
public opfCollectorAddress: string
|
public opfCollectorAddress: string
|
||||||
|
public oceanAddress: string
|
||||||
|
public daiAddress: string
|
||||||
|
public usdcAddress: string
|
||||||
public web3: Web3
|
public web3: Web3
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -68,6 +73,7 @@ export class TestContractHandler {
|
|||||||
this.SideStaking = new this.web3.eth.Contract(SideStakingABI)
|
this.SideStaking = new this.web3.eth.Contract(SideStakingABI)
|
||||||
this.FixedRate = new this.web3.eth.Contract(FixedRateABI)
|
this.FixedRate = new this.web3.eth.Contract(FixedRateABI)
|
||||||
this.Dispenser = new this.web3.eth.Contract(DispenserABI)
|
this.Dispenser = new this.web3.eth.Contract(DispenserABI)
|
||||||
|
this.MockERC20 = new this.web3.eth.Contract(MockERC20.abi as AbiItem[])
|
||||||
|
|
||||||
this.ERC721FactoryBytecode = factory721Bytecode
|
this.ERC721FactoryBytecode = factory721Bytecode
|
||||||
this.ERC20TemplateBytecode = template20Bytecode
|
this.ERC20TemplateBytecode = template20Bytecode
|
||||||
@ -77,6 +83,7 @@ export class TestContractHandler {
|
|||||||
this.SideStakingBytecode = sideStakingBytecode
|
this.SideStakingBytecode = sideStakingBytecode
|
||||||
this.FixedRateBytecode = fixedRateBytecode
|
this.FixedRateBytecode = fixedRateBytecode
|
||||||
this.DispenserBytecode = dispenserBytecode
|
this.DispenserBytecode = dispenserBytecode
|
||||||
|
this.MockERC20Bytecode = MockERC20.bytecode
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAccounts(): Promise<string[]> {
|
public async getAccounts(): Promise<string[]> {
|
||||||
@ -156,10 +163,39 @@ export class TestContractHandler {
|
|||||||
return contract.options.address
|
return contract.options.address
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// DEPLOY OCEAN MOCK
|
||||||
|
// get est gascost
|
||||||
|
estGas = await this.MockERC20.deploy({
|
||||||
|
data: this.MockERC20Bytecode,
|
||||||
|
arguments: ['OCEAN', 'OCEAN', 18]
|
||||||
|
}).estimateGas(function (err, estGas) {
|
||||||
|
if (err) console.log('DeployContracts: ' + err)
|
||||||
|
return estGas
|
||||||
|
})
|
||||||
|
// deploy the contract and get it's address
|
||||||
|
this.oceanAddress = await this.MockERC20.deploy({
|
||||||
|
data: this.MockERC20Bytecode,
|
||||||
|
arguments: ['OCEAN', 'OCEAN', 18]
|
||||||
|
})
|
||||||
|
.send({
|
||||||
|
from: owner,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: '3000000000'
|
||||||
|
})
|
||||||
|
.then(function (contract) {
|
||||||
|
return contract.options.address
|
||||||
|
})
|
||||||
|
|
||||||
// DEPLOY ROUTER
|
// DEPLOY ROUTER
|
||||||
estGas = await this.Router.deploy({
|
estGas = await this.Router.deploy({
|
||||||
data: this.RouterBytecode,
|
data: this.RouterBytecode,
|
||||||
arguments: [owner, oceanAddress, this.poolTemplateAddress, communityCollector, []]
|
arguments: [
|
||||||
|
owner,
|
||||||
|
this.oceanAddress,
|
||||||
|
this.poolTemplateAddress,
|
||||||
|
communityCollector,
|
||||||
|
[]
|
||||||
|
]
|
||||||
}).estimateGas(function (err, estGas) {
|
}).estimateGas(function (err, estGas) {
|
||||||
if (err) console.log('DeployContracts: ' + err)
|
if (err) console.log('DeployContracts: ' + err)
|
||||||
return estGas
|
return estGas
|
||||||
@ -167,7 +203,13 @@ export class TestContractHandler {
|
|||||||
// deploy the contract and get it's address
|
// deploy the contract and get it's address
|
||||||
this.routerAddress = await this.Router.deploy({
|
this.routerAddress = await this.Router.deploy({
|
||||||
data: this.RouterBytecode,
|
data: this.RouterBytecode,
|
||||||
arguments: [owner, oceanAddress, this.poolTemplateAddress, communityCollector, []]
|
arguments: [
|
||||||
|
owner,
|
||||||
|
this.oceanAddress,
|
||||||
|
this.poolTemplateAddress,
|
||||||
|
communityCollector,
|
||||||
|
[]
|
||||||
|
]
|
||||||
})
|
})
|
||||||
.send({
|
.send({
|
||||||
from: owner,
|
from: owner,
|
||||||
@ -276,6 +318,52 @@ export class TestContractHandler {
|
|||||||
return contract.options.address
|
return contract.options.address
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// DEPLOY USDC MOCK
|
||||||
|
// get est gascost
|
||||||
|
estGas = await this.MockERC20.deploy({
|
||||||
|
data: this.MockERC20Bytecode,
|
||||||
|
arguments: ['USDC', 'USDC', 6]
|
||||||
|
}).estimateGas(function (err, estGas) {
|
||||||
|
if (err) console.log('DeployContracts: ' + err)
|
||||||
|
return estGas
|
||||||
|
})
|
||||||
|
// deploy the contract and get it's address
|
||||||
|
this.usdcAddress = await this.MockERC20.deploy({
|
||||||
|
data: this.MockERC20Bytecode,
|
||||||
|
arguments: ['USDC', 'USDC', 6]
|
||||||
|
})
|
||||||
|
.send({
|
||||||
|
from: owner,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: '3000000000'
|
||||||
|
})
|
||||||
|
.then(function (contract) {
|
||||||
|
return contract.options.address
|
||||||
|
})
|
||||||
|
|
||||||
|
// DEPLOY DAI MOCK
|
||||||
|
// get est gascost
|
||||||
|
estGas = await this.MockERC20.deploy({
|
||||||
|
data: this.MockERC20Bytecode,
|
||||||
|
arguments: ['DAI', 'DAI', 18]
|
||||||
|
}).estimateGas(function (err, estGas) {
|
||||||
|
if (err) console.log('DeployContracts: ' + err)
|
||||||
|
return estGas
|
||||||
|
})
|
||||||
|
// deploy the contract and get it's address
|
||||||
|
this.daiAddress = await this.MockERC20.deploy({
|
||||||
|
data: this.MockERC20Bytecode,
|
||||||
|
arguments: ['DAI', 'DAI', 18]
|
||||||
|
})
|
||||||
|
.send({
|
||||||
|
from: owner,
|
||||||
|
gas: estGas + 1,
|
||||||
|
gasPrice: '3000000000'
|
||||||
|
})
|
||||||
|
.then(function (contract) {
|
||||||
|
return contract.options.address
|
||||||
|
})
|
||||||
|
|
||||||
const RouterContract = new this.web3.eth.Contract(routerABI, this.routerAddress)
|
const RouterContract = new this.web3.eth.Contract(routerABI, this.routerAddress)
|
||||||
|
|
||||||
await RouterContract.methods.addFactory(this.factory721Address).send({ from: owner })
|
await RouterContract.methods.addFactory(this.factory721Address).send({ from: owner })
|
||||||
@ -288,9 +376,9 @@ export class TestContractHandler {
|
|||||||
await RouterContract.methods
|
await RouterContract.methods
|
||||||
.addSSContract(this.sideStakingAddress)
|
.addSSContract(this.sideStakingAddress)
|
||||||
.send({ from: owner })
|
.send({ from: owner })
|
||||||
// TODO: add OPF deployment and update argument
|
// TODO: add OPF deployment
|
||||||
await RouterContract.methods
|
// await RouterContract.methods
|
||||||
.changeRouterOwner(communityCollector)
|
// .changeRouterOwner(communityCollector)
|
||||||
.send({ from: owner })
|
// .send({ from: owner })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { assert } from 'chai'
|
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'
|
||||||
@ -9,11 +9,11 @@ import Router from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRo
|
|||||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||||
import Dispenser from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
|
import Dispenser from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
|
||||||
import FixedRate from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'
|
import 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 PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
|
||||||
import { LoggerInstance } from '../../src/utils'
|
import { LoggerInstance } from '../../src/utils'
|
||||||
// import { NFTDataToken } from '../../../src/datatokens/NFTDatatoken'
|
// import { NFTDataToken } from '../../../src/datatokens/NFTDatatoken'
|
||||||
import { NFTFactory } from '../../src/factories/NFTFactory'
|
import { NFTFactory } from '../../src/factories/NFTFactory'
|
||||||
// import { DT20Factory } from '../../../src/factories/DT20Factory'
|
|
||||||
|
|
||||||
const web3 = new Web3('http://127.0.0.1:8545')
|
const web3 = new Web3('http://127.0.0.1:8545')
|
||||||
|
|
||||||
@ -22,18 +22,13 @@ describe('NFT Factory test', () => {
|
|||||||
let nftOwner: string
|
let nftOwner: string
|
||||||
let user1: string
|
let user1: string
|
||||||
let user2: string
|
let user2: string
|
||||||
|
let user3: string
|
||||||
let contracts: TestContractHandler
|
let contracts: TestContractHandler
|
||||||
let nftFactory: NFTFactory
|
let nftFactory: NFTFactory
|
||||||
|
let dtAddress: string
|
||||||
|
let dtAddress2: string
|
||||||
|
let nftAddress: string
|
||||||
|
|
||||||
const nftName = 'NFT'
|
|
||||||
const nftSymbol = 'NFTSymbol'
|
|
||||||
const nftTemplateIndex = 1
|
|
||||||
const data = web3.utils.asciiToHex('SomeData')
|
|
||||||
const flags = web3.utils.asciiToHex(
|
|
||||||
'f8929916089218bdb4aa78c3ecd16633afd44b8aef89299160'
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: complete unit test
|
|
||||||
it('should deploy contracts', async () => {
|
it('should deploy contracts', async () => {
|
||||||
contracts = new TestContractHandler(
|
contracts = new TestContractHandler(
|
||||||
web3,
|
web3,
|
||||||
@ -59,10 +54,18 @@ describe('NFT Factory test', () => {
|
|||||||
factoryOwner = contracts.accounts[0]
|
factoryOwner = contracts.accounts[0]
|
||||||
nftOwner = contracts.accounts[1]
|
nftOwner = contracts.accounts[1]
|
||||||
user1 = contracts.accounts[2]
|
user1 = contracts.accounts[2]
|
||||||
console.log(factoryOwner)
|
user2 = contracts.accounts[3]
|
||||||
|
user3 = contracts.accounts[4]
|
||||||
|
|
||||||
await contracts.deployContracts(factoryOwner, Router.abi as AbiItem[])
|
await contracts.deployContracts(factoryOwner, Router.abi as AbiItem[])
|
||||||
|
|
||||||
console.log('BOOM')
|
const daiContract = new web3.eth.Contract(
|
||||||
|
contracts.MockERC20.options.jsonInterface,
|
||||||
|
contracts.daiAddress
|
||||||
|
)
|
||||||
|
await daiContract.methods
|
||||||
|
.approve(contracts.factory721Address, web3.utils.toWei('10000'))
|
||||||
|
.send({ from: contracts.accounts[0] })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should initiate NFTFactory instance', async () => {
|
it('should initiate NFTFactory instance', async () => {
|
||||||
@ -71,12 +74,12 @@ describe('NFT Factory test', () => {
|
|||||||
|
|
||||||
it('#getCurrentNFTCount - should return actual nft count (0)', async () => {
|
it('#getCurrentNFTCount - should return actual nft count (0)', async () => {
|
||||||
const nftCount = await nftFactory.getCurrentNFTCount()
|
const nftCount = await nftFactory.getCurrentNFTCount()
|
||||||
assert(nftCount === 0)
|
expect(nftCount).to.equal('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('#getCurrentTokenCount - should return actual token count (0)', async () => {
|
it('#getCurrentTokenCount - should return actual token count (0)', async () => {
|
||||||
const tokenCount = await nftFactory.getCurrentTokenCount()
|
const tokenCount = await nftFactory.getCurrentTokenCount()
|
||||||
assert(tokenCount === 0)
|
expect(tokenCount).to.equal('0')
|
||||||
})
|
})
|
||||||
it('#getOwner - should return actual owner', async () => {
|
it('#getOwner - should return actual owner', async () => {
|
||||||
const owner = await nftFactory.getOwner()
|
const owner = await nftFactory.getOwner()
|
||||||
@ -84,11 +87,11 @@ describe('NFT Factory test', () => {
|
|||||||
})
|
})
|
||||||
it('#getCurrentNFTTemplateCount - should return actual nft template count (1)', async () => {
|
it('#getCurrentNFTTemplateCount - should return actual nft template count (1)', async () => {
|
||||||
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
||||||
assert(nftTemplateCount === 1)
|
expect(nftTemplateCount).to.equal('1')
|
||||||
})
|
})
|
||||||
it('#getCurrentTokenTemplateCount - should return actual token template count (1)', async () => {
|
it('#getCurrentTokenTemplateCount - should return actual token template count (1)', async () => {
|
||||||
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
||||||
assert(tokenTemplateCount === 1)
|
expect(tokenTemplateCount).to.equal('1')
|
||||||
})
|
})
|
||||||
it('#getNFTTemplate - should return NFT template struct', async () => {
|
it('#getNFTTemplate - should return NFT template struct', async () => {
|
||||||
const nftTemplate = await nftFactory.getNFTTemplate(1)
|
const nftTemplate = await nftFactory.getNFTTemplate(1)
|
||||||
@ -103,7 +106,7 @@ describe('NFT Factory test', () => {
|
|||||||
it('#addNFTTemplate - should add NFT template if factory owner', async () => {
|
it('#addNFTTemplate - should add NFT template if factory owner', async () => {
|
||||||
await nftFactory.addNFTTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
await nftFactory.addNFTTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
||||||
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
const nftTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
||||||
assert(nftTemplateCount === 2)
|
expect(nftTemplateCount).to.equal('2')
|
||||||
const nftTemplate = await nftFactory.getNFTTemplate(2)
|
const nftTemplate = await nftFactory.getNFTTemplate(2)
|
||||||
assert(nftTemplate.isActive === true)
|
assert(nftTemplate.isActive === true)
|
||||||
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
||||||
@ -111,7 +114,7 @@ describe('NFT Factory test', () => {
|
|||||||
it('#disableNFTTemplate - should disable NFT template if factory owner', async () => {
|
it('#disableNFTTemplate - should disable NFT template if factory owner', async () => {
|
||||||
let nftTemplate = await nftFactory.getNFTTemplate(2)
|
let nftTemplate = await nftFactory.getNFTTemplate(2)
|
||||||
assert(nftTemplate.isActive === true)
|
assert(nftTemplate.isActive === true)
|
||||||
await nftFactory.disableNFTTemplate(contracts.accounts[0], 2) // owner disable template index = 2
|
await nftFactory.disableNFTTemplate(contracts.accounts[0], 2) // owner disables template index = 2
|
||||||
|
|
||||||
nftTemplate = await nftFactory.getNFTTemplate(2)
|
nftTemplate = await nftFactory.getNFTTemplate(2)
|
||||||
assert(nftTemplate.isActive === false)
|
assert(nftTemplate.isActive === false)
|
||||||
@ -119,7 +122,7 @@ describe('NFT Factory test', () => {
|
|||||||
it('#reactivateNFTTemplate - should disable NFT template if factory owner', async () => {
|
it('#reactivateNFTTemplate - should disable NFT template if factory owner', async () => {
|
||||||
let nftTemplate = await nftFactory.getNFTTemplate(2)
|
let nftTemplate = await nftFactory.getNFTTemplate(2)
|
||||||
assert(nftTemplate.isActive === false)
|
assert(nftTemplate.isActive === false)
|
||||||
await nftFactory.reactivateNFTTemplate(contracts.accounts[0], 2) // owner reactivate template index = 2
|
await nftFactory.reactivateNFTTemplate(contracts.accounts[0], 2) // owner reactivates template index = 2
|
||||||
|
|
||||||
nftTemplate = await nftFactory.getNFTTemplate(2)
|
nftTemplate = await nftFactory.getNFTTemplate(2)
|
||||||
assert(nftTemplate.isActive === true)
|
assert(nftTemplate.isActive === true)
|
||||||
@ -127,7 +130,7 @@ describe('NFT Factory test', () => {
|
|||||||
it('#addTokenTemplate - should add Datatoken template if factory owner', async () => {
|
it('#addTokenTemplate - should add Datatoken template if factory owner', async () => {
|
||||||
await nftFactory.addTokenTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
await nftFactory.addTokenTemplate(contracts.accounts[0], contracts.fixedRateAddress) // contracts.fixedRateAddress it's just a dummy contract in this case
|
||||||
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
const tokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
||||||
assert(tokenTemplateCount === 2)
|
expect(tokenTemplateCount).to.equal('2')
|
||||||
const nftTemplate = await nftFactory.getTokenTemplate(2)
|
const nftTemplate = await nftFactory.getTokenTemplate(2)
|
||||||
assert(nftTemplate.isActive === true)
|
assert(nftTemplate.isActive === true)
|
||||||
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
assert(nftTemplate.templateAddress === contracts.fixedRateAddress)
|
||||||
@ -136,7 +139,7 @@ describe('NFT Factory test', () => {
|
|||||||
it('#disableTokenTemplate - should disable Token template if factory owner', async () => {
|
it('#disableTokenTemplate - should disable Token template if factory owner', async () => {
|
||||||
let tokenTemplate = await nftFactory.getTokenTemplate(2)
|
let tokenTemplate = await nftFactory.getTokenTemplate(2)
|
||||||
assert(tokenTemplate.isActive === true)
|
assert(tokenTemplate.isActive === true)
|
||||||
await nftFactory.disableTokenTemplate(contracts.accounts[0], 2) // owner disable template index = 2
|
await nftFactory.disableTokenTemplate(contracts.accounts[0], 2) // owner disables template index = 2
|
||||||
|
|
||||||
tokenTemplate = await nftFactory.getTokenTemplate(2)
|
tokenTemplate = await nftFactory.getTokenTemplate(2)
|
||||||
assert(tokenTemplate.isActive === false)
|
assert(tokenTemplate.isActive === false)
|
||||||
@ -144,9 +147,216 @@ describe('NFT Factory test', () => {
|
|||||||
it('#reactivateTokenTemplate - should disable Token template if factory owner', async () => {
|
it('#reactivateTokenTemplate - should disable Token template if factory owner', async () => {
|
||||||
let tokenTemplate = await nftFactory.getTokenTemplate(2)
|
let tokenTemplate = await nftFactory.getTokenTemplate(2)
|
||||||
assert(tokenTemplate.isActive === false)
|
assert(tokenTemplate.isActive === false)
|
||||||
await nftFactory.reactivateTokenTemplate(contracts.accounts[0], 2) // owner reactivate template index = 2
|
await nftFactory.reactivateTokenTemplate(contracts.accounts[0], 2) // owner reactivates template index = 2
|
||||||
|
|
||||||
tokenTemplate = await nftFactory.getTokenTemplate(2)
|
tokenTemplate = await nftFactory.getTokenTemplate(2)
|
||||||
assert(tokenTemplate.isActive === true)
|
assert(tokenTemplate.isActive === true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('#createNftwithErc - should create an NFT and a Datatoken ', async () => {
|
||||||
|
// we prepare transaction parameters objects
|
||||||
|
const nftData = {
|
||||||
|
name: '72120Bundle',
|
||||||
|
symbol: '72Bundle',
|
||||||
|
templateIndex: 1,
|
||||||
|
baseURI: 'https://oceanprotocol.com/nft/'
|
||||||
|
}
|
||||||
|
const ercData = {
|
||||||
|
templateIndex: 1,
|
||||||
|
strings: ['ERC20B1', 'ERC20DT1Symbol'],
|
||||||
|
addresses: [
|
||||||
|
contracts.accounts[0],
|
||||||
|
user3,
|
||||||
|
user2,
|
||||||
|
'0x0000000000000000000000000000000000000000'
|
||||||
|
],
|
||||||
|
uints: [web3.utils.toWei('10000'), 0],
|
||||||
|
bytess: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const txReceipt = await nftFactory.createNftWithErc(
|
||||||
|
contracts.accounts[0],
|
||||||
|
nftData,
|
||||||
|
ercData
|
||||||
|
)
|
||||||
|
|
||||||
|
// EVENTS HAVE BEEN EMITTED
|
||||||
|
expect(txReceipt.events.NFTCreated.event === 'NFTCreated')
|
||||||
|
expect(txReceipt.events.TokenCreated.event === 'TokenCreated')
|
||||||
|
|
||||||
|
// stored for later use in startMultipleTokenOrder test
|
||||||
|
nftAddress = txReceipt.events.NFTCreated.returnValues.newTokenAddress
|
||||||
|
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#createNftErcWithPool- should create an NFT, a Datatoken and a pool DT/DAI', async () => {
|
||||||
|
// we prepare transaction parameters objects
|
||||||
|
const nftData = {
|
||||||
|
name: '72120Bundle',
|
||||||
|
symbol: '72Bundle',
|
||||||
|
templateIndex: 1,
|
||||||
|
baseURI: 'https://oceanprotocol.com/nft/'
|
||||||
|
}
|
||||||
|
const ercData = {
|
||||||
|
templateIndex: 1,
|
||||||
|
strings: ['ERC20B1', 'ERC20DT1Symbol'],
|
||||||
|
addresses: [user2, user3, user2, '0x0000000000000000000000000000000000000000'],
|
||||||
|
uints: [web3.utils.toWei('1000000'), 0],
|
||||||
|
bytess: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const poolData = {
|
||||||
|
addresses: [
|
||||||
|
contracts.sideStakingAddress,
|
||||||
|
contracts.daiAddress,
|
||||||
|
contracts.factory721Address,
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.poolTemplateAddress
|
||||||
|
],
|
||||||
|
ssParams: [
|
||||||
|
web3.utils.toWei('1'), // rate
|
||||||
|
18, // basetokenDecimals
|
||||||
|
web3.utils.toWei('10000'),
|
||||||
|
2500000, // vested blocks
|
||||||
|
web3.utils.toWei('2000') // baseToken initial pool liquidity
|
||||||
|
],
|
||||||
|
swapFees: [
|
||||||
|
1e15, //
|
||||||
|
1e15
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const txReceipt = await nftFactory.createNftErcWithPool(
|
||||||
|
contracts.accounts[0],
|
||||||
|
nftData,
|
||||||
|
ercData,
|
||||||
|
poolData
|
||||||
|
)
|
||||||
|
|
||||||
|
// EVENTS HAVE BEEN EMITTED
|
||||||
|
expect(txReceipt.events.NFTCreated.event === 'NFTCreated')
|
||||||
|
expect(txReceipt.events.TokenCreated.event === 'TokenCreated')
|
||||||
|
expect(txReceipt.events.NewPool.event === 'NewPool')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#createNftErcWithFixedRate- should create an NFT, a datatoken and create a Fixed Rate Exchange', async () => {
|
||||||
|
// we prepare transaction parameters objects
|
||||||
|
const nftData = {
|
||||||
|
name: '72120Bundle',
|
||||||
|
symbol: '72Bundle',
|
||||||
|
templateIndex: 1,
|
||||||
|
baseURI: 'https://oceanprotocol.com/nft/'
|
||||||
|
}
|
||||||
|
const ercData = {
|
||||||
|
templateIndex: 1,
|
||||||
|
strings: ['ERC20B1', 'ERC20DT1Symbol'],
|
||||||
|
addresses: [
|
||||||
|
contracts.accounts[0],
|
||||||
|
user3,
|
||||||
|
user2,
|
||||||
|
'0x0000000000000000000000000000000000000000'
|
||||||
|
],
|
||||||
|
uints: [web3.utils.toWei('1000000'), 0],
|
||||||
|
bytess: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const fixedData = {
|
||||||
|
fixedPriceAddress: contracts.fixedRateAddress,
|
||||||
|
addresses: [contracts.daiAddress, contracts.accounts[0], contracts.accounts[0]],
|
||||||
|
uints: [18, 18, web3.utils.toWei('1'), 1e15]
|
||||||
|
}
|
||||||
|
|
||||||
|
const txReceipt = await nftFactory.createNftErcWithFixedRate(
|
||||||
|
contracts.accounts[0],
|
||||||
|
nftData,
|
||||||
|
ercData,
|
||||||
|
fixedData
|
||||||
|
)
|
||||||
|
|
||||||
|
// EVENTS HAVE BEEN EMITTED
|
||||||
|
expect(txReceipt.events.NFTCreated.event === 'NFTCreated')
|
||||||
|
expect(txReceipt.events.TokenCreated.event === 'TokenCreated')
|
||||||
|
expect(txReceipt.events.NewFixedRate.event === 'NewFixedRate')
|
||||||
|
|
||||||
|
// stored for later use in startMultipleTokenOrder test
|
||||||
|
dtAddress2 = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#startMultipleTokenOrder- should succed to start multiple orders', async () => {
|
||||||
|
const consumer = user2 // could be different user
|
||||||
|
const dtAmount = web3.utils.toWei('1')
|
||||||
|
const serviceId = 1 // dummy index
|
||||||
|
const consumeFeeAddress = user3 // marketplace fee Collector
|
||||||
|
const consumeFeeAmount = 0 // fee to be collected on top, requires approval
|
||||||
|
const consumeFeeToken = contracts.daiAddress // token address for the feeAmount, in this case DAI
|
||||||
|
|
||||||
|
// we reuse a DT created in a previous test
|
||||||
|
const dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
|
||||||
|
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
|
||||||
|
// dt owner mint dtAmount to user2
|
||||||
|
await dtContract.methods.mint(user2, dtAmount).send({ from: contracts.accounts[0] })
|
||||||
|
|
||||||
|
// user2 approves NFTFactory to move his dtAmount
|
||||||
|
await dtContract.methods
|
||||||
|
.approve(contracts.factory721Address, dtAmount)
|
||||||
|
.send({ from: user2 })
|
||||||
|
|
||||||
|
// we reuse another DT created in a previous test
|
||||||
|
const dtContract2 = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress2)
|
||||||
|
expect(await dtContract2.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
|
||||||
|
// dt owner mint dtAmount to user2
|
||||||
|
await dtContract2.methods.mint(user2, dtAmount).send({ from: contracts.accounts[0] })
|
||||||
|
// user2 approves NFTFactory to move his dtAmount
|
||||||
|
await dtContract2.methods
|
||||||
|
.approve(contracts.factory721Address, dtAmount)
|
||||||
|
.send({ from: user2 })
|
||||||
|
|
||||||
|
// we check user2 has enought DTs
|
||||||
|
expect(await dtContract.methods.balanceOf(user2).call()).to.equal(dtAmount)
|
||||||
|
expect(await dtContract2.methods.balanceOf(user2).call()).to.equal(dtAmount)
|
||||||
|
|
||||||
|
const orders = [
|
||||||
|
{
|
||||||
|
tokenAddress: dtAddress,
|
||||||
|
consumer: consumer,
|
||||||
|
amount: dtAmount,
|
||||||
|
serviceId: serviceId,
|
||||||
|
consumeFeeAddress: consumeFeeAddress,
|
||||||
|
consumeFeeToken: consumeFeeToken,
|
||||||
|
consumeFeeAmount: consumeFeeAmount
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tokenAddress: dtAddress2,
|
||||||
|
consumer: consumer,
|
||||||
|
amount: dtAmount,
|
||||||
|
serviceId: serviceId,
|
||||||
|
consumeFeeAddress: consumeFeeAddress,
|
||||||
|
consumeFeeToken: consumeFeeToken,
|
||||||
|
consumeFeeAmount: consumeFeeAmount
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
await nftFactory.startMultipleTokenOrder(user2, orders)
|
||||||
|
|
||||||
|
// we check user2 has no more DTs
|
||||||
|
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
expect(await dtContract2.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
})
|
||||||
|
it('#checkDatatoken - should confirm if DT is from the factory', async () => {
|
||||||
|
assert((await nftFactory.checkDatatoken(dtAddress)) === true)
|
||||||
|
assert((await nftFactory.checkDatatoken(dtAddress2)) === true)
|
||||||
|
assert((await nftFactory.checkDatatoken(user2)) === false)
|
||||||
|
assert((await nftFactory.checkDatatoken(nftAddress)) === false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#checkNFT - should return nftAddress if from the factory, or address(0) if not', async () => {
|
||||||
|
assert(
|
||||||
|
(await nftFactory.checkNFT(dtAddress)) ===
|
||||||
|
'0x0000000000000000000000000000000000000000'
|
||||||
|
)
|
||||||
|
assert((await nftFactory.checkNFT(nftAddress)) === nftAddress)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
331
test/unit/pools/Router.test.ts
Normal file
331
test/unit/pools/Router.test.ts
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
import { assert, expect } from 'chai'
|
||||||
|
import { AbiItem } from 'web3-utils/types'
|
||||||
|
import { TestContractHandler } from '../../TestContractHandler'
|
||||||
|
import Web3 from 'web3'
|
||||||
|
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
|
||||||
|
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
|
||||||
|
import SideStaking from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
|
||||||
|
import FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
|
||||||
|
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||||
|
import Dispenser from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
|
||||||
|
import FixedRate from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'
|
||||||
|
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
||||||
|
import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
|
||||||
|
import { LoggerInstance } from '../../../src/utils'
|
||||||
|
import { NFTFactory } from '../../../src/factories/NFTFactory'
|
||||||
|
import { Router } from '../../../src/pools/Router'
|
||||||
|
const { keccak256 } = require('@ethersproject/keccak256')
|
||||||
|
const web3 = new Web3('http://127.0.0.1:8545')
|
||||||
|
const communityCollector = '0xeE9300b7961e0a01d9f0adb863C7A227A07AaD75'
|
||||||
|
|
||||||
|
describe('Router unit test', () => {
|
||||||
|
let factoryOwner: string
|
||||||
|
let nftOwner: string
|
||||||
|
let user1: string
|
||||||
|
let user2: string
|
||||||
|
let user3: string
|
||||||
|
let contracts: TestContractHandler
|
||||||
|
let router: Router
|
||||||
|
let dtAddress: string
|
||||||
|
let dtAddress2: string
|
||||||
|
let nftAddress: string
|
||||||
|
|
||||||
|
it('should deploy contracts', async () => {
|
||||||
|
contracts = new TestContractHandler(
|
||||||
|
web3,
|
||||||
|
ERC721Template.abi as AbiItem[],
|
||||||
|
ERC20Template.abi as AbiItem[],
|
||||||
|
PoolTemplate.abi as AbiItem[],
|
||||||
|
ERC721Factory.abi as AbiItem[],
|
||||||
|
FactoryRouter.abi as AbiItem[],
|
||||||
|
SideStaking.abi as AbiItem[],
|
||||||
|
FixedRate.abi as AbiItem[],
|
||||||
|
Dispenser.abi as AbiItem[],
|
||||||
|
|
||||||
|
ERC721Template.bytecode,
|
||||||
|
ERC20Template.bytecode,
|
||||||
|
PoolTemplate.bytecode,
|
||||||
|
ERC721Factory.bytecode,
|
||||||
|
FactoryRouter.bytecode,
|
||||||
|
SideStaking.bytecode,
|
||||||
|
FixedRate.bytecode,
|
||||||
|
Dispenser.bytecode
|
||||||
|
)
|
||||||
|
await contracts.getAccounts()
|
||||||
|
factoryOwner = contracts.accounts[0]
|
||||||
|
nftOwner = contracts.accounts[1]
|
||||||
|
user1 = contracts.accounts[2]
|
||||||
|
user2 = contracts.accounts[3]
|
||||||
|
user3 = contracts.accounts[4]
|
||||||
|
|
||||||
|
await contracts.deployContracts(factoryOwner, FactoryRouter.abi as AbiItem[])
|
||||||
|
|
||||||
|
const daiContract = new web3.eth.Contract(
|
||||||
|
contracts.MockERC20.options.jsonInterface,
|
||||||
|
contracts.daiAddress
|
||||||
|
)
|
||||||
|
await daiContract.methods
|
||||||
|
.approve(contracts.factory721Address, web3.utils.toWei('10000'))
|
||||||
|
.send({ from: contracts.accounts[0] })
|
||||||
|
|
||||||
|
expect(await daiContract.methods.balanceOf(contracts.accounts[0]).call()).to.equal(
|
||||||
|
web3.utils.toWei('100000')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should initiate Router instance', async () => {
|
||||||
|
router = new Router(contracts.routerAddress, web3, LoggerInstance)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#getOwner - should return actual owner', async () => {
|
||||||
|
const owner = await router.getOwner()
|
||||||
|
assert(owner === contracts.accounts[0])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#getNFTFactory - should return NFT Factory address', async () => {
|
||||||
|
const factory = await router.getNFTFactory()
|
||||||
|
assert(factory === contracts.factory721Address)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#isOceanTokens - should return true if in oceanTokens list', async () => {
|
||||||
|
expect(await router.isOceanTokens(contracts.oceanAddress)).to.equal(true)
|
||||||
|
expect(await router.isOceanTokens(contracts.daiAddress)).to.equal(false)
|
||||||
|
})
|
||||||
|
it('#isSideStaking - should return true if in ssContracts list', async () => {
|
||||||
|
expect(await router.isSideStaking(contracts.sideStakingAddress)).to.equal(true)
|
||||||
|
expect(await router.isSideStaking(contracts.fixedRateAddress)).to.equal(false)
|
||||||
|
})
|
||||||
|
it('#isFixedPrice - should return true if in fixedPrice list', async () => {
|
||||||
|
expect(await router.isFixedPrice(contracts.fixedRateAddress)).to.equal(true)
|
||||||
|
expect(await router.isFixedPrice(contracts.daiAddress)).to.equal(false)
|
||||||
|
// Dispenser contract is also a fixed price contract
|
||||||
|
expect(await router.isFixedPrice(contracts.dispenserAddress)).to.equal(true)
|
||||||
|
})
|
||||||
|
it('#isPoolTemplate - should return true if in poolTemplates list', async () => {
|
||||||
|
expect(await router.isPoolTemplate(contracts.poolTemplateAddress)).to.equal(true)
|
||||||
|
expect(await router.isPoolTemplate(contracts.fixedRateAddress)).to.equal(false)
|
||||||
|
})
|
||||||
|
it('#addOceanToken - should add a new token into oceanTokens list(NO OPF FEE)', async () => {
|
||||||
|
await router.addOceanToken(contracts.accounts[0], contracts.daiAddress)
|
||||||
|
expect(await router.isOceanTokens(contracts.daiAddress)).to.equal(true)
|
||||||
|
})
|
||||||
|
it('#removeOceanToken - should remove a token from oceanTokens list', async () => {
|
||||||
|
await router.removeOceanToken(contracts.accounts[0], contracts.daiAddress)
|
||||||
|
expect(await router.isOceanTokens(contracts.daiAddress)).to.equal(false)
|
||||||
|
})
|
||||||
|
it('#addSSContract - should add a new token into SSContracts list', async () => {
|
||||||
|
await router.addSSContract(contracts.accounts[0], contracts.daiAddress)
|
||||||
|
expect(await router.isSideStaking(contracts.daiAddress)).to.equal(true)
|
||||||
|
})
|
||||||
|
it('#addFixedRate - should add a new token into fixedPrice list', async () => {
|
||||||
|
await router.addFixedRateContract(contracts.accounts[0], contracts.daiAddress)
|
||||||
|
expect(await router.isFixedPrice(contracts.daiAddress)).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#getOPFFee - should return actual OPF fee for a given baseToken', async () => {
|
||||||
|
const opfFee = 1e15
|
||||||
|
expect(await router.getOPFFee(contracts.oceanAddress)).to.equal('0')
|
||||||
|
expect(await router.getOPFFee(contracts.daiAddress)).to.equal(opfFee.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#getCurrentOPFFee - should return actual OPF Fee', async () => {
|
||||||
|
const opfFee = 1e15
|
||||||
|
expect(await router.getCurrentOPFFee()).to.equal(opfFee.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#updateOPFFee - should update opf fee if Router Owner', async () => {
|
||||||
|
const opfFee = 1e15
|
||||||
|
expect(await router.getCurrentOPFFee()).to.equal(opfFee.toString())
|
||||||
|
const newOPFFee = 1e14
|
||||||
|
await router.updateOPFFee(contracts.accounts[0], 1e14)
|
||||||
|
expect(await router.getCurrentOPFFee()).to.equal(newOPFFee.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#addPoolTemplate - should add a new token into poolTemplates mapping if Router Owner', async () => {
|
||||||
|
await router.addPoolTemplate(contracts.accounts[0], contracts.daiAddress)
|
||||||
|
expect(await router.isPoolTemplate(contracts.daiAddress)).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#removePoolTemplate - should add a new token into poolTemplates mapping if Router Owner', async () => {
|
||||||
|
await router.removePoolTemplate(contracts.accounts[0], contracts.daiAddress)
|
||||||
|
expect(await router.isPoolTemplate(contracts.daiAddress)).to.equal(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('#buyDTBatch - should buy multiple DT in one call', async () => {
|
||||||
|
// APPROVE DAI
|
||||||
|
const daiContract = new web3.eth.Contract(
|
||||||
|
contracts.MockERC20.options.jsonInterface,
|
||||||
|
contracts.daiAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(await daiContract.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
await daiContract.methods
|
||||||
|
.transfer(user2, web3.utils.toWei('2'))
|
||||||
|
.send({ from: contracts.accounts[0] })
|
||||||
|
expect(await daiContract.methods.balanceOf(user2).call()).to.equal(
|
||||||
|
web3.utils.toWei('2')
|
||||||
|
)
|
||||||
|
await daiContract.methods
|
||||||
|
.approve(contracts.routerAddress, web3.utils.toWei('2'))
|
||||||
|
.send({ from: user2 })
|
||||||
|
|
||||||
|
// CREATE A FIRST POOL
|
||||||
|
// we prepare transaction parameters objects
|
||||||
|
const nftData = {
|
||||||
|
name: '72120Bundle',
|
||||||
|
symbol: '72Bundle',
|
||||||
|
templateIndex: 1,
|
||||||
|
baseURI: 'https://oceanprotocol.com/nft/'
|
||||||
|
}
|
||||||
|
const ercData = {
|
||||||
|
templateIndex: 1,
|
||||||
|
strings: ['ERC20B1', 'ERC20DT1Symbol'],
|
||||||
|
addresses: [
|
||||||
|
contracts.accounts[0],
|
||||||
|
user3,
|
||||||
|
contracts.accounts[0],
|
||||||
|
'0x0000000000000000000000000000000000000000'
|
||||||
|
],
|
||||||
|
uints: [web3.utils.toWei('1000000'), 0],
|
||||||
|
bytess: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const poolData = {
|
||||||
|
addresses: [
|
||||||
|
contracts.sideStakingAddress,
|
||||||
|
contracts.daiAddress,
|
||||||
|
contracts.factory721Address,
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.poolTemplateAddress
|
||||||
|
],
|
||||||
|
ssParams: [
|
||||||
|
web3.utils.toWei('1'), // rate
|
||||||
|
18, // basetokenDecimals
|
||||||
|
web3.utils.toWei('10000'),
|
||||||
|
2500000, // vested blocks
|
||||||
|
web3.utils.toWei('2000') // baseToken initial pool liquidity
|
||||||
|
],
|
||||||
|
swapFees: [
|
||||||
|
1e15, //
|
||||||
|
1e15
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const nftFactory = new NFTFactory(contracts.factory721Address, web3, LoggerInstance)
|
||||||
|
|
||||||
|
const txReceipt = await nftFactory.createNftErcWithPool(
|
||||||
|
contracts.accounts[0],
|
||||||
|
nftData,
|
||||||
|
ercData,
|
||||||
|
poolData
|
||||||
|
)
|
||||||
|
|
||||||
|
const erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||||
|
const pool1 = txReceipt.events.NewPool.returnValues.poolAddress
|
||||||
|
|
||||||
|
// CREATE A SECOND POOL
|
||||||
|
|
||||||
|
const nftData2 = {
|
||||||
|
name: '72120Bundle2',
|
||||||
|
symbol: '72Bundle2',
|
||||||
|
templateIndex: 1,
|
||||||
|
baseURI: 'https://oceanprotocol.com/nft2/'
|
||||||
|
}
|
||||||
|
const ercData2 = {
|
||||||
|
templateIndex: 1,
|
||||||
|
strings: ['ERC20B12', 'ERC20DT1Symbol2'],
|
||||||
|
addresses: [
|
||||||
|
contracts.accounts[0],
|
||||||
|
user3,
|
||||||
|
contracts.accounts[0],
|
||||||
|
'0x0000000000000000000000000000000000000000'
|
||||||
|
],
|
||||||
|
uints: [web3.utils.toWei('1000000'), 0],
|
||||||
|
bytess: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const poolData2 = {
|
||||||
|
addresses: [
|
||||||
|
contracts.sideStakingAddress,
|
||||||
|
contracts.daiAddress,
|
||||||
|
contracts.factory721Address,
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.accounts[0],
|
||||||
|
contracts.poolTemplateAddress
|
||||||
|
],
|
||||||
|
ssParams: [
|
||||||
|
web3.utils.toWei('1'), // rate
|
||||||
|
18, // basetokenDecimals
|
||||||
|
web3.utils.toWei('10000'),
|
||||||
|
2500000, // vested blocks
|
||||||
|
web3.utils.toWei('2000') // baseToken initial pool liquidity
|
||||||
|
],
|
||||||
|
swapFees: [
|
||||||
|
1e15, //
|
||||||
|
1e15
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const txReceipt2 = await nftFactory.createNftErcWithPool(
|
||||||
|
contracts.accounts[0],
|
||||||
|
nftData2,
|
||||||
|
ercData2,
|
||||||
|
poolData2
|
||||||
|
)
|
||||||
|
|
||||||
|
const erc20Token2 = txReceipt2.events.TokenCreated.returnValues.newTokenAddress
|
||||||
|
const pool2 = txReceipt2.events.NewPool.returnValues.poolAddress
|
||||||
|
|
||||||
|
const erc20Contract = new web3.eth.Contract(
|
||||||
|
ERC20Template.abi as AbiItem[],
|
||||||
|
erc20Token
|
||||||
|
)
|
||||||
|
// user2 has no dt1
|
||||||
|
expect(await erc20Contract.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
|
||||||
|
const erc20Contract2 = new web3.eth.Contract(
|
||||||
|
ERC20Template.abi as AbiItem[],
|
||||||
|
erc20Token2
|
||||||
|
)
|
||||||
|
// user2 has no dt2
|
||||||
|
expect(await erc20Contract2.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
|
||||||
|
// we now can prepare the Operations objects
|
||||||
|
|
||||||
|
// operation: 0 - swapExactAmountIn
|
||||||
|
// 1 - swapExactAmountOut
|
||||||
|
// 2 - FixedRateExchange
|
||||||
|
// 3 - Dispenser
|
||||||
|
const operations1 = {
|
||||||
|
exchangeIds: keccak256('0x00'), // used only for FixedRate or Dispenser, but needs to be filled even for pool
|
||||||
|
source: pool1, // pool Address
|
||||||
|
operation: 0, // swapExactAmountIn
|
||||||
|
tokenIn: contracts.daiAddress,
|
||||||
|
amountsIn: web3.utils.toWei('1'), // when swapExactAmountIn is EXACT amount IN
|
||||||
|
tokenOut: erc20Token,
|
||||||
|
amountsOut: web3.utils.toWei('0.1'), // when swapExactAmountIn is MIN amount OUT
|
||||||
|
maxPrice: web3.utils.toWei('10') // max price (only for pools)
|
||||||
|
}
|
||||||
|
|
||||||
|
const operations2 = {
|
||||||
|
exchangeIds: keccak256('0x00'), // used only for FixedRate or Dispenser, but needs to be filled even for pool
|
||||||
|
source: pool2, // pool Address
|
||||||
|
operation: 0, // swapExactAmountIn
|
||||||
|
tokenIn: contracts.daiAddress,
|
||||||
|
amountsIn: web3.utils.toWei('1'), // when swapExactAmountIn is EXACT amount IN
|
||||||
|
tokenOut: erc20Token2,
|
||||||
|
amountsOut: web3.utils.toWei('0.1'), // when swapExactAmountIn is MIN amount OUT
|
||||||
|
maxPrice: web3.utils.toWei('10') // max price (only for pools)
|
||||||
|
}
|
||||||
|
|
||||||
|
await router.buyDTBatch(user2, [operations1, operations2])
|
||||||
|
|
||||||
|
// user2 had 2 dai and now has zero
|
||||||
|
expect(await daiContract.methods.balanceOf(user2).call()).to.equal('0')
|
||||||
|
|
||||||
|
// user2 got his dts
|
||||||
|
expect(parseInt(await erc20Contract.methods.balanceOf(user2).call())).gt(0)
|
||||||
|
expect(parseInt(await erc20Contract2.methods.balanceOf(user2).call())).gt(0)
|
||||||
|
})
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user