/* eslint-disable no-underscore-dangle */
import BigNumber from 'bignumber.js';
import { networkFactory } from '../../interfaces';
import Numbers from '../../utils/Numbers';
import IContract from '../IContract';
import ERC20Contract from '../ERC20/ERC20Contract';
/**
* @typedef {Object} NetworkFactory~Options
* @property {Boolean} test
* @property {Boolean} localtest ganache local blockchain
* @property {Web3Connection} [web3Connection=Web3Connection] created from params: 'test', 'localtest' and optional 'web3Connection' string and 'privateKey'
* @property {string} [contractAddress]
*/
/**
* NetworkFactory Object
* @class NetworkFactory
* @param {NetworkFactory~Options} options
*/
class NetworkFactory extends IContract {
constructor(params) {
super({ abi: networkFactory, ...params });
}
/**
* Asserts the 2 {@link ERC20Contract} on the current address
* @function
* @return {Promise<void>}
* @throws {Error} Contract is not deployed, first deploy it and provide a contract address
*/
__assert = async () => {
if (!this.getAddress()) {
throw new Error(
'Contract is not deployed, first deploy it and provide a contract address',
);
}
// Use ABI
this.params.contract.use(networkFactory, this.getAddress());
const beproAddress = await this.getSettlerTokenAddress();
// Set Token Address Contract for easy access
this.params.settlerToken = new ERC20Contract({
web3Connection: this.web3Connection,
contractAddress: beproAddress,
});
// Assert Token Contract
await this.params.settlerToken.start();
await this.params.settlerToken.__assert();
};
/**
* Get Network By Creator Address
* @param {Address} address
* @returns {Adddress}
*/
getNetworkByAddress(address) {
return this.getContract()
.methods.getNetworkByAddress(address)
.call();
}
/**
* Get Network By Id
* @param {number} id
* @returns {Adddress}
*/
getNetworkById(id) {
return this.getContract()
.methods.getNetworkById(id)
.call();
}
/**
* Get Amount of Networks Forked in the Protocol
* @returns {Promise<number>}
*/
async getAmountofNetworksForked() {
return Number(await this.getContract().methods.networksAmount().call());
}
async networksAmount() {
return BigNumber(await this.getContract().methods.networksAmount().call());
}
/**
* Get Total Amount of Tokens Locked by Operator in the Network
* @param {Address} address
* @returns {Promise<number>}
*/
async getLockedStakedByAddress(address) {
return Numbers.fromDecimals(
await this.getContract().methods.tokensLocked(address).call(),
18,
);
}
async getTokensLocked(address) {
return Numbers.fromDecimalsToBN(
await this.getContract().methods.tokensLocked(address).call(),
18,
);
}
/**
* Get Open Issues Available
* @param {Address} address
* @returns {Address[]}
*/
getNetworks() {
return this.getContract()
.methods.networksArray()
.call();
}
/**
* Get Total Amount of Tokens Staked in the Protocol
* @returns {Promise<number>}
*/
async getBEPROLocked() {
return Numbers.fromDecimals(
await this.getContract().methods.tokensLockedTotal().call(),
18,
);
}
async tokensLockedTotal() {
return Numbers.fromDecimalsToBN(
await this.getContract().methods.tokensLockedTotal().call(),
18,
);
}
/**
* Verify if Address is Council
* @param {Object} params
* @param {number} params.address
* @returns {Promise<address>}
*/
async isOperator({ address }) {
return await this.getLockedStakedByAddress(address) >= await this.OPERATOR_AMOUNT();
}
/**
* Get Settler Token Address
* @returns {Promise<address>}
*/
getSettlerTokenAddress() {
return this.getContract()
.methods.beproAddress()
.call();
}
beproAddress() {
return this.getContract()
.methods.beproAddress()
.call();
}
/**
* Get Amount Needed for Operator
* @returns {Promise<Integer>}
*/
async OPERATOR_AMOUNT() {
return Numbers.fromDecimals(
await this.getContract()
.methods.OPERATOR_AMOUNT()
.call(),
18,
);
}
/**
* Approve ERC20 Allowance
* @function
* @return {Promise<number>}
*/
approveSettlerERC20Token = async () => {
const totalMaxAmount = await this.getSettlerTokenContract().totalSupply();
return this.getSettlerTokenContract().approve({
address: this.getAddress(),
amount: totalMaxAmount,
});
};
/**
* Verify if Approved
* @function
* @param {Object} params
* @param {number} params.amount
* @param {Address} params.address
* @return {Promise<number>}
*/
isApprovedSettlerToken = ({ amount, address }) => this.getSettlerTokenContract().isApproved({
address,
amount,
spenderAddress: this.getAddress(),
});
/**
* lock tokens for operator use
* @param {Object} params
* @params params.tokenAmount {number}
* @throws {Error} Tokens Amount has to be higher than 0
* @throws {Error} Tokens not approve for tx, first use 'approveERC20'
* @return {Promise<TransactionObject>}
*/
lock({ tokenAmount }, options) {
if (tokenAmount <= 0) {
throw new Error('Token Amount has to be higher than 0');
}
return this.__sendTx(
this.getContract().methods.lock(
Numbers.toSmartContractDecimals(tokenAmount, this.getSettlerTokenContract().getDecimals()),
),
options,
);
}
/**
* Unlock Tokens for oracles
* @throws {Error} Tokens Amount has to be higher than 0
* @return {Promise<TransactionObject>}
*/
unlock(options) {
return this.__sendTx(
this.getContract().methods.unlock(),
options,
);
}
/**
* Create Network
* @param {Object} params
* @param {Address} params.settlerToken
* @param {Address} params.transactionalToken
* @return {Promise<TransactionObject>}
*/
createNetwork({ settlerToken, transactionalToken }, options) {
return this.__sendTx(
this.getContract()
.methods.createNetwork(settlerToken, transactionalToken),
options,
);
}
/**
* Deploys Contracts
* @function
* @param {Object} params
* @param {string} params.beproAddress
* @param {IContract~TxOptions} options
* @return {Promise<*|undefined>}
*/
deploy = async ({ beproAddress }, options) => {
const params = [ beproAddress ];
const res = await this.__deploy(params, options);
this.params.contractAddress = res.contractAddress;
/* Call to Backend API */
await this.__assert();
return res;
};
/**
* @function
* @return ERC20Contract|null
*/
getSettlerTokenContract() {
return this.params.settlerToken;
}
}
export default NetworkFactory;
Source