src/reserve_contract.js
import Web3 from 'web3'
import reserveContractABI from '../abi/KyberReserveContract.abi.json'
import BaseContract from './base_contract.js'
import { validateAddress } from './validate.js'
import { assertAdmin, assertAlerter, assertOperator } from './permission_assert.js'
/**
* ReserveContract contains extended methods for KyberReserveContract
*/
export default class ReserveContract extends BaseContract {
/**
* Create new BaseContract instance.
* @param {object} provider - Web3 provider
* @param {string} address - address of kyber reserve smart contract.
*/
constructor (web3, address) {
super(web3, address)
this.web3 = web3
this.contract = new this.web3.eth.Contract(reserveContractABI, address)
}
/**
* enableTrade allow the reserve to continue trading
* @param {object} adminAddress - address of Admin account
* @param {number} gasPrice (optional) - the gasPrice desired for the tx
* @return {object} - the tx object of send() command from this contract method
*/
async enableTrade (adminAddress, gasPrice) {
await assertAdmin(this, adminAddress)
const med = this.contract.methods.enableTrade()
return this.contract.methods.enableTrade().send({
from: adminAddress,
gas: await med.estimateGas({
from: adminAddress
}),
gasPrice: gasPrice
})
}
/**
* disableTrade stop the reserve from trading
* @param {object} alerterAddress - address of Alerter account
* @param {number} gasPrice (optional) - the gasPrice desired for the tx
* @return {object} - the tx object of send() command from this contract method
*/
async disableTrade (alerterAddress, gasPrice) {
await assertAlerter(this, alerterAddress)
const med = this.contract.methods.disableTrade()
return med.send({
from: alerterAddress,
gas: await med.estimateGas({
from: alerterAddress
}),
gasPrice: gasPrice
})
}
/**
* tradeEnabled return true if the reserve is tradeEnabled, false otherwise
* @return {boolean} - tradeEnabled status of the reserve
*/
tradeEnabled () {
return this.contract.methods.tradeEnabled().call()
}
/**
* set Contract addresses for reserve contract.
* @param {object} adminAddress - address of admin account.
* @param {string} network - address of kyber network smart contract.
* @param {string} conversion - address of kyber network smart contract.
* @param {string} sanity (optional) - address of sanity rates contract.
* @param {number} [gasPrice=undefined] - the gasPrice desired for the tx
* @returns {object} - the tx object of send() command from this contract method
*/
async setContracts (
adminAddress,
network,
conversion,
sanity,
gasPrice = undefined
) {
validateAddress(network)
validateAddress(conversion)
await assertAdmin(this, adminAddress)
if (sanity !== undefined) {
validateAddress(sanity)
} else {
sanity = '0x0000000000000000000000000000000000000000'
}
const med = this.contract.methods.setContracts(network, conversion, sanity)
return med.send({
from: adminAddress,
gas: await med.estimateGas({
from: adminAddress
}),
gasPrice: gasPrice
})
}
/**
* conversionRatesContract return the address of conversion rates of this reserve
* @return {string} - address of conversion rates contract
*/
conversionRatesContract () {
return this.contract.methods.conversionRatesContract().call()
}
/**
* sanityRatesContract return the address of sanity rates of this reserve
* @return {string} - address of sanity rates contract
*/
sanityRatesContract () {
return this.contract.methods.sanityRatesContract().call()
}
/**
* kyberNetwork return the address of kyberNetwork contract of this reserve
* @return {string} - address of kyberNetwork contract
*/
kyberNetwork () {
return this.contract.methods.kyberNetwork().call()
}
/**
* approve withdraw address for a token on reserve.
* @param {object} adminAddress - address of admin account.
* @param {string} tokenAddress - contract address of the modifying token.
* @param {string} withdrawAddress - address for withdrawal.
* @param {number} [gasPrice=undefined] - the gasPrice desired for the tx
* @returns {object} - the tx object of send() command from this contract method
*/
async approveWithdrawAddress (
adminAddress,
tokenAddress,
withdrawAddress,
gasPrice = undefined
) {
await assertAdmin(this, adminAddress)
const med = this.contract.methods.approveWithdrawAddress(
tokenAddress,
withdrawAddress,
true
)
return med.send({
from: adminAddress,
gas: await med.estimateGas({
from: adminAddress
}),
gasPrice: gasPrice
})
}
/**
* disapprove withdraw address for a token on reserve.
* @param {object} adminAddress - address of admin account.
* @param {string} tokenAddress - contract address of the modifying token.
* @param {string} withdrawAddress - address for withdrawal.
* @param {number} [gasPrice=undefined] - the gasPrice desired for the tx
* @returns {object} - the tx object of send() command from this contract method
*/
async disapproveWithdrawAddress (
adminAddress,
tokenAddress,
withdrawAddress,
gasPrice = undefined
) {
await assertAdmin(this, adminAddress)
const med = this.contract.methods.approveWithdrawAddress(
tokenAddress,
withdrawAddress,
false
)
return med.send({
from: adminAddress,
gas: await med.estimateGas({
from: adminAddress
}),
gasPrice: gasPrice
})
}
/**
* check for approval status of a token address to a particular address
* @param {object} address - address to withdraw the token to
* @param {string} tokenAddress - address of the token's smart contract. Must be deployed already.
* @returns {boolean} - true for approved, false otherwise
*/
approvedWithdrawAddresses (address, tokenAddress) {
const addressHash = Web3.utils.soliditySha3(tokenAddress, address)
return this.contract.methods.approvedWithdrawAddresses(addressHash).call()
}
/**
* withdraw an amount of token to specified account
* @param {object} operatorAddress - address of operator account.
* @param {string} tokenAddress - address of the token's smart contract. Must be deployed already.
* @param {object} amount - amount to withdraw (BN|String|int), must be in wei.
* @param {string} toAddress - address for withdrawal. Must be approved already.
* @param {number} [gasPrice=undefined] - the gasPrice desired for the tx
* @returns {object} - the tx object of send() command from this contract method
*/
async withdraw (
operatorAddress,
tokenAddress,
amount,
toAddress,
gasPrice = undefined
) {
await assertOperator(this, operatorAddress)
const med = this.contract.methods.withdraw(tokenAddress, amount, toAddress)
return med.send({
from: operatorAddress,
gas: await med.estimateGas({
from: operatorAddress
}),
gasPrice: gasPrice
})
}
/**
* Return balance of given token.
* @param {string} token - address of token to check balance.
* @return {number} - balance of given token
*/
getBalance (token) {
return this.contract.methods.getBalance(token).call()
}
/**
* set different token wallet per token.
* @param {object} adminAddress - address of admin account.
* @param {string} tokenAddress - address of the token's smart contract.
* @param {object} walletAddress - address of wallet in which tokens are present.
*/
async setTokenWallet(adminAddress, tokenAddress, walletAddress, gasPrice = undefined) {
await assertAdmin(this, adminAddress);
const setWallet = this.contract.methods.setTokenWallet(tokenAddress, walletAddress)
return setWallet.send({
from: adminAddress,
gas: await setWallet.estimateGas({from: adminAddress}),
gasPrice: gasPrice
})
}
}