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

add more functions and tests

This commit is contained in:
lacoop6tu 2021-11-05 12:36:07 -05:00
parent 21a60ebf23
commit 8f43ae058f
5 changed files with 620 additions and 200 deletions

View File

@ -4,11 +4,11 @@ import { TransactionReceipt } from 'web3-core'
import { Contract } from 'web3-eth-contract'
import { Logger, getFairGasPrice } from '../../utils'
import BigNumber from 'bignumber.js'
const BN = require('bn.js');
import PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'
import defaultPool from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
import defaultERC20ABI from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
import Decimal from 'decimal.js'
const BN = require('bn.js')
const MaxUint256 =
'115792089237316195423570985008687907853269984665640564039457584007913129639934'
@ -131,11 +131,10 @@ export class Pool {
let result = null
const amountFormatted = await this.amountToUnits(tokenAddress, amount)
const estGas = await this.estApprove(account, tokenAddress, spender, amountFormatted)
try {
result = await token.methods
.approve(spender,new BigNumber(await this.amountToUnits(tokenAddress, amount)))
.approve(spender, new BigNumber(await this.amountToUnits(tokenAddress, amount)))
.send({
from: account,
gas: estGas + 1,
@ -165,8 +164,7 @@ export class Pool {
return result
}
/**
/**
* Estimate gas cost for setSwapFee
* @param {String} account
* @param {String} tokenAddress
@ -176,30 +174,27 @@ export class Pool {
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estSetSwapFee(
account: string,
poolAddress: string,
fee: string,
contractInstance?: Contract
): Promise<number> {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(defaultERC20ABI.abi as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.setSwapFee(fee)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
public async estSetSwapFee(
account: string,
poolAddress: string,
fee: string,
contractInstance?: Contract
): Promise<number> {
const poolContract =
contractInstance ||
new this.web3.eth.Contract(defaultERC20ABI.abi as AbiItem[], poolAddress)
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await poolContract.methods
.setSwapFee(fee)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Set pool fee
@ -216,8 +211,8 @@ export class Pool {
from: account
})
let result = null
const estGas = await this.estSetSwapFee(account,poolAddress,fee)
const estGas = await this.estSetSwapFee(account, poolAddress, fee)
try {
result = await pool.methods.setSwapFee(this.web3.utils.toWei(fee)).send({
from: account,
@ -572,7 +567,7 @@ export class Pool {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null
const estGas = await this.estCollectOPF(address, poolAddress)
try {
result = await pool.methods.collectOPF().send({
from: address,
@ -633,7 +628,7 @@ export class Pool {
const pool = new this.web3.eth.Contract(this.poolABI, poolAddress)
let result = null
const estGas = await this.estCollectMarketFee(address, poolAddress, to)
try {
result = await pool.methods.collectMarketFee(to).send({
from: address,
@ -698,7 +693,7 @@ export class Pool {
poolAddress,
newCollector
)
try {
result = await pool.methods.updateMarketFeeCollector(newCollector).send({
from: address,
@ -746,7 +741,7 @@ export class Pool {
tokenAmountIn,
tokenOut,
minAmountOut,
maxPrice ? maxPrice : MaxUint256
maxPrice || MaxUint256
)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
@ -826,8 +821,8 @@ export class Pool {
minAmountOutFormatted.toString(),
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
)
//console.log(minAmountOutFormatted, 'minamoutnoutformatted')
// console.log(minAmountOutFormatted, 'minamoutnoutformatted')
try {
result = await pool.methods
.swapExactAmountIn(
@ -884,7 +879,7 @@ export class Pool {
maxAmountIn,
tokenOut,
amountOut,
maxPrice ? maxPrice : MaxUint256
maxPrice || MaxUint256
)
.estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
@ -927,7 +922,7 @@ export class Pool {
amountOutFormatted,
maxPrice ? this.web3.utils.toWei(maxPrice) : MaxUint256
)
try {
result = await pool.methods
.swapExactAmountOut(
@ -1012,7 +1007,7 @@ export class Pool {
this.web3.utils.toWei(poolAmountOut),
weiMaxAmountsIn
)
try {
result = await pool.methods
.joinPool(this.web3.utils.toWei(poolAmountOut), weiMaxAmountsIn)
@ -1088,7 +1083,7 @@ export class Pool {
this.web3.utils.toWei(poolAmountIn),
weiMinAmountsOut
)
try {
result = await pool.methods
.exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut)
@ -1160,7 +1155,7 @@ export class Pool {
amountInFormatted,
this.web3.utils.toWei(minPoolAmountOut)
)
try {
result = await pool.methods
.joinswapExternAmountIn(
@ -1241,7 +1236,7 @@ export class Pool {
this.web3.utils.toWei(poolAmountOut),
maxAmountInFormatted
)
try {
result = await pool.methods
.joinswapPoolAmountOut(
@ -1321,7 +1316,7 @@ export class Pool {
this.web3.utils.toWei(poolAmountIn),
minTokenOutFormatted
)
try {
result = await pool.methods
.exitswapPoolAmountIn(
@ -1400,7 +1395,7 @@ export class Pool {
this.web3.utils.toWei(tokenAmountOut),
this.web3.utils.toWei(maxPoolAmountIn)
)
try {
result = await pool.methods
.exitswapExternAmountOut(

View File

@ -10,15 +10,30 @@ import { Logger, getFairGasPrice } from '../../utils'
const MAX_AWAIT_PROMISES = 10
export interface FixedPriceExchange {
exchangeID?: string
active: boolean
exchangeOwner: string
dataToken: string
baseToken: string
fixedRate: string
active: boolean
supply: string
dtDecimals: string
btDecimals: string
dtBalance: string
btBalance: string
dtSupply: string
btSupply: string
withMint: boolean
allowedSwapper: string
exchangeID?: string
}
export interface FeesInfo {
opfFee: string
marketFee: string
marketFeeCollector: string
marketFeeAvailable: string
oceanFeeAvailable: string
exchangeID: string
}
export interface FixedPriceSwap {
exchangeID: string
caller: string
@ -35,18 +50,16 @@ export class FixedRateExchange {
public GASLIMIT_DEFAULT = 1000000
/** Ocean related functions */
public oceanAddress: string = null
public fixedRateAddress:string
public fixedRateAddress: string
public fixedRateExchangeABI: AbiItem | AbiItem[]
public fixedRateContract:Contract
public fixedRateContract: Contract
public web3: Web3
public contract: Contract = null
private logger: Logger
public startBlock: number
public ssABI: AbiItem | AbiItem[]
/**
* Instantiate FixedRateExchange
* @param {any} web3
@ -61,7 +74,7 @@ export class FixedRateExchange {
startBlock?: number
) {
this.web3 = web3
if (startBlock) this.startBlock = startBlock
else this.startBlock = 0
this.fixedRateExchangeABI =
@ -72,16 +85,17 @@ export class FixedRateExchange {
this.fixedRateExchangeABI,
this.fixedRateAddress
)
this.logger = logger
}
async amountToUnits(token: string, amount: string): Promise<string> {
let decimals = 18
const tokenContract = new this.web3.eth.Contract(
defaultERC20ABI.abi as AbiItem[],
token
)
console.log('1')
try {
decimals = await tokenContract.methods.decimals().call()
} catch (e) {
@ -110,20 +124,23 @@ export class FixedRateExchange {
return amountFormatted.toString()
}
/**
* Creates unique exchange identifier.
* @param {String} dataToken Data Token Contract Address
* @param {String} owner Owner of the exchange
* @return {Promise<string>} exchangeId
*/
public async generateExchangeId(dataToken: string, owner: string): Promise<string> {
public async generateExchangeId(
basetoken: string,
dataToken: string,
owner: string
): Promise<string> {
const exchangeId = await this.contract.methods
.generateExchangeId(this.oceanAddress, dataToken, owner)
.generateExchangeId(basetoken, dataToken, owner)
.call()
return exchangeId
}
/**
* Estimate gas cost for buyDT
* @param {String} account
@ -132,26 +149,26 @@ export class FixedRateExchange {
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estBuyDT(
public async estBuyDT(
account: string,
datatokenAddress: string,
dtAmount:string,
dtAmount: string,
maxBasetokenAmount: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate =
contractInstance || this.fixedRateContract
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.buyDT(datatokenAddress,dtAmount.toString(),maxBasetokenAmount.toString())
.buyDT(datatokenAddress, dtAmount.toString(), maxBasetokenAmount.toString())
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Atomic swap
* @param {String} exchangeId ExchangeId
@ -164,15 +181,30 @@ export class FixedRateExchange {
address: string,
exchangeId: string,
datatokenAmount: string,
maxBasetokenAmount:string
maxBasetokenAmount: string
): Promise<TransactionReceipt> {
const dtAmountFormatted = await this.amountToUnits(((await this.getExchange(exchangeId)).dataToken),datatokenAmount)
const maxBtFormatted = await this.amountToUnits(((await this.getExchange(exchangeId)).baseToken),maxBasetokenAmount)
const estGas = await this.estBuyDT(address,exchangeId,dtAmountFormatted,maxBtFormatted)
const dtAmountFormatted = await this.amountToUnits(
(
await this.getExchange(exchangeId)
).dataToken,
datatokenAmount
)
const maxBtFormatted = await this.amountToUnits(
(
await this.getExchange(exchangeId)
).baseToken,
maxBasetokenAmount
)
const estGas = await this.estBuyDT(
address,
exchangeId,
dtAmountFormatted,
maxBtFormatted
)
try {
const trxReceipt = await this.contract.methods
.buyDT(exchangeId, dtAmountFormatted,maxBtFormatted)
.buyDT(exchangeId, dtAmountFormatted, maxBtFormatted)
.send({
from: address,
gas: estGas + 1,
@ -193,26 +225,26 @@ export class FixedRateExchange {
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estSellDT(
public async estSellDT(
account: string,
datatokenAddress: string,
dtAmount:string,
dtAmount: string,
maxBasetokenAmount: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate =
contractInstance || this.fixedRateContract
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.sellDT(datatokenAddress,dtAmount,maxBasetokenAmount)
.sellDT(datatokenAddress, dtAmount, maxBasetokenAmount)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Atomic swap
* @param {String} exchangeId ExchangeId
@ -225,15 +257,29 @@ export class FixedRateExchange {
address: string,
exchangeId: string,
datatokenAmount: string,
minBasetokenAmount:string
minBasetokenAmount: string
): Promise<TransactionReceipt> {
const dtAmountFormatted = await this.amountToUnits((await this.getExchange(exchangeId)).dataToken,datatokenAmount)
const minBtFormatted = await this.amountToUnits((await this.getExchange(exchangeId)).baseToken,minBasetokenAmount)
const estGas = await this.estBuyDT(address,exchangeId,dtAmountFormatted,minBtFormatted)
const dtAmountFormatted = await this.amountToUnits(
(
await this.getExchange(exchangeId)
).dataToken,
datatokenAmount
)
const minBtFormatted = await this.amountToUnits(
(
await this.getExchange(exchangeId)
).baseToken,
minBasetokenAmount
)
const estGas = await this.estBuyDT(
address,
exchangeId,
dtAmountFormatted,
minBtFormatted
)
try {
const trxReceipt = await this.contract.methods
.sellDT(exchangeId, dtAmountFormatted,minBtFormatted)
.sellDT(exchangeId, dtAmountFormatted, minBtFormatted)
.send({
from: address,
gas: estGas + 1,
@ -265,19 +311,18 @@ export class FixedRateExchange {
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estSetRate(
public async estSetRate(
account: string,
exchangeId: string,
newRate:string,
newRate: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate =
contractInstance || this.fixedRateContract
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.setRate(exchangeId,newRate)
.setRate(exchangeId, newRate)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
@ -295,13 +340,15 @@ export class FixedRateExchange {
public async setRate(
address: string,
exchangeId: string,
newRate: number,
newRate: string
): Promise<TransactionReceipt> {
const estGas = await this.estSetRate(address,exchangeId,this.web3.utils.toWei(String(newRate)))
const estGas = await this.estSetRate(
address,
exchangeId,
this.web3.utils.toWei(String(newRate))
)
const trxReceipt = await this.contract.methods
.setRate(exchangeId, this.web3.utils.toWei(String(newRate)))
.setRate(exchangeId, this.web3.utils.toWei(newRate))
.send({
from: address,
gas: estGas + 1,
@ -310,31 +357,80 @@ export class FixedRateExchange {
return trxReceipt
}
/**
/**
* Estimate gas cost for setRate
* @param {String} account
* @param {String} exchangeId ExchangeId
* @param {String} newAllowedSwapper new allowed swapper address
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estSetAllowedSwapper(
account: string,
exchangeId: string,
newAllowedSwapper: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.setRate(exchangeId, newAllowedSwapper)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Set new rate
* @param {String} exchangeId ExchangeId
* @param {String} newAllowedSwapper newAllowedSwapper (set address zero if we want to remove allowed swapper)
* @param {String} address User account
* @return {Promise<TransactionReceipt>} transaction receipt
*/
public async setAllowedSwapper(
address: string,
exchangeId: string,
newAllowedSwapper: string
): Promise<TransactionReceipt> {
const estGas = await this.estSetAllowedSwapper(address, exchangeId, newAllowedSwapper)
const trxReceipt = await this.contract.methods
.setAllowedSwapper(exchangeId, newAllowedSwapper)
.send({
from: address,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
return trxReceipt
}
/**
* Estimate gas cost for activate
* @param {String} account
* @param {String} exchangeId ExchangeId
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estActivate(
account: string,
exchangeId: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate =
contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
public async estActivate(
account: string,
exchangeId: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.toggleExchangeState(exchangeId)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Activate an exchange
@ -350,8 +446,8 @@ export class FixedRateExchange {
if (!exchange) return null
if (exchange.active === true) return null
const gasLimitDefault = this.GASLIMIT_DEFAULT
const estGas = await this.estActivate(address,exchangeId)
const estGas = await this.estActivate(address, exchangeId)
const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({
from: address,
gas: estGas + 1,
@ -360,33 +456,30 @@ export class FixedRateExchange {
return trxReceipt
}
/**
/**
* Estimate gas cost for deactivate
* @param {String} account
* @param {String} exchangeId ExchangeId
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estDeactivate(
account: string,
exchangeId: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate =
contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.toggleExchangeState(exchangeId)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
public async estDeactivate(
account: string,
exchangeId: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.toggleExchangeState(exchangeId)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Deactivate an exchange
@ -397,18 +490,19 @@ export class FixedRateExchange {
public async deactivate(
address: string,
exchangeId: string
): Promise<TransactionReceipt> {
const exchange = await this.getExchange(exchangeId)
if (!exchange) return null
if (exchange.active === false) return null
const estGas = await this.estDeactivate(address,exchangeId)
const estGas = await this.estDeactivate(address, exchangeId)
const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({
from: address,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
return trxReceipt
}
@ -423,29 +517,101 @@ export class FixedRateExchange {
}
/**
* Get Supply
* Get Datatoken Supply in the exchange
* @param {String} exchangeId ExchangeId
* @return {Promise<string>} Rate (converted from wei)
* @return {Promise<string>} dt supply formatted
*/
public async getSupply(exchangeId: string): Promise<string> {
const weiRate = await this.contract.methods.getSupply(exchangeId).call()
return this.web3.utils.fromWei(weiRate)
public async getDTSupply(exchangeId: string): Promise<string> {
const dtSupply = await this.contract.methods.getDTSupply(exchangeId).call()
return await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).dataToken,
dtSupply
)
}
/**
* getOceanNeeded
* Get Basetoken Supply in the exchange
* @param {String} exchangeId ExchangeId
* @param {Number} dataTokenAmount Amount of Data Tokens
* @return {Promise<string>} Ocean amount needed
* @return {Promise<string>} dt supply formatted
*/
public async getOceanNeeded(
public async getBTSupply(exchangeId: string): Promise<string> {
const btSupply = await this.contract.methods.getBTSupply(exchangeId).call()
return await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).baseToken,
btSupply
)
}
/**
* Get Allower Swapper (if set this is the only account which can use this exchange, else is set at address(0))
* @param {String} exchangeId ExchangeId
* @return {Promise<string>} address of allowedSwapper
*/
public async getAllowedSwapper(exchangeId: string): Promise<string> {
return await this.contract.methods.getAllowedSwapper(exchangeId).call()
}
/**
* getBTNeeded - returns amount in basetoken that user will pay for dataTokenAmount
* @param {String} exchangeId ExchangeId
* @param {Number} dataTokenAmount Amount of Data Tokens user wants to buy
* @return {Promise<string>} Amount of basetoken needed for buying
*/
public async getAmountBTIn(
exchangeId: string,
dataTokenAmount: string
): Promise<string> {
const weiRate = await this.contract.methods
.calcBaseInGivenOutDT(exchangeId, this.web3.utils.toWei(dataTokenAmount))
const result = await this.contract.methods
.calcBaseInGivenOutDT(
exchangeId,
await this.amountToUnits(
(
await this.getExchange(exchangeId)
).dataToken,
dataTokenAmount
)
)
.call()
return this.web3.utils.fromWei(weiRate)
return await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).baseToken,
result.baseTokenAmount
)
}
/**
* getBTOut - returns amount in basetoken that user will receive for dataTokenAmount sold
* @param {String} exchangeId ExchangeId
* @param {Number} dataTokenAmount Amount of Data Tokens
* @return {Promise<string>} Amount of basetokens user will receive
*/
public async getAmountBTOut(
exchangeId: string,
dataTokenAmount: string
): Promise<string> {
const result = await this.contract.methods
.calcBaseOutGivenInDT(
exchangeId,
await this.amountToUnits(
(
await this.getExchange(exchangeId)
).dataToken,
dataTokenAmount
)
)
.call()
return await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).baseToken,
result.baseTokenAmount
)
}
/**
@ -457,9 +623,50 @@ export class FixedRateExchange {
const result: FixedPriceExchange = await this.contract.methods
.getExchange(exchangeId)
.call()
// result.fixedRate = this.web3.utils.fromWei(result.fixedRate)
// result.supply = this.web3.utils.fromWei(result.supply)
// result.exchangeID = exchangeId
result.dtDecimals = result.dtDecimals.toString()
result.btDecimals = result.btDecimals.toString()
result.dtBalance = await this.unitsToAmount(result.dataToken, result.dtBalance)
result.btBalance = await this.unitsToAmount(result.baseToken, result.btBalance)
result.dtSupply = await this.unitsToAmount(result.dataToken, result.dtSupply)
result.btSupply = await this.unitsToAmount(result.baseToken, result.btSupply)
result.fixedRate = this.web3.utils.fromWei(result.fixedRate)
result.exchangeID = exchangeId
return result
}
/**
* Get fee details for an exchange
* @param {String} exchangeId ExchangeId
* @return {Promise<FixedPricedExchange>} Exchange details
*/
public async getFeesInfo(exchangeId: string): Promise<FeesInfo> {
const result: FeesInfo = await this.contract.methods.getFeesInfo(exchangeId).call()
result.opfFee = await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).baseToken,
result.opfFee
)
result.marketFee = await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).baseToken,
result.marketFee
)
result.marketFeeAvailable = await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).baseToken,
result.marketFeeAvailable
)
result.oceanFeeAvailable = await this.unitsToAmount(
(
await this.getExchange(exchangeId)
).baseToken,
result.oceanFeeAvailable
)
result.exchangeID = exchangeId
return result
}
@ -482,7 +689,106 @@ export class FixedRateExchange {
return result
}
/**
* Estimate gas cost for activate
* @param {String} account
* @param {String} exchangeId ExchangeId
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estActivateMint(
account: string,
exchangeId: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.toggleMintState(exchangeId, true)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
}
/**
* Activate minting option for fixed rate contract
* @param {String} exchangeId ExchangeId
* @param {String} address User address
* @return {Promise<TransactionReceipt>} transaction receipt
*/
public async activateMint(
address: string,
exchangeId: string
): Promise<TransactionReceipt> {
const exchange = await this.getExchange(exchangeId)
if (!exchange) return null
if (exchange.withMint === true) return null
const gasLimitDefault = this.GASLIMIT_DEFAULT
const estGas = await this.estActivateMint(address, exchangeId)
const trxReceipt = await this.contract.methods
.toggleMintState(exchangeId, true)
.send({
from: address,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
return trxReceipt
}
/**
* Estimate gas cost for deactivate
* @param {String} account
* @param {String} exchangeId ExchangeId
* @param {Contract} contractInstance optional contract instance
* @return {Promise<number>}
*/
public async estDeactivateMint(
account: string,
exchangeId: string,
contractInstance?: Contract
): Promise<number> {
const fixedRate = contractInstance || this.fixedRateContract
const gasLimitDefault = this.GASLIMIT_DEFAULT
let estGas
try {
estGas = await fixedRate.methods
.toggleMintState(exchangeId)
.estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))
} catch (e) {
estGas = gasLimitDefault
}
return estGas
}
/**
* Deactivate minting for fixed rate
* @param {String} exchangeId ExchangeId
* @param {String} address User address
* @return {Promise<TransactionReceipt>} transaction receipt
*/
public async deactivateMint(
address: string,
exchangeId: string
): Promise<TransactionReceipt> {
const exchange = await this.getExchange(exchangeId)
if (!exchange) return null
if (exchange.withMint === false) return null
const estGas = await this.estDeactivate(address, exchangeId)
const trxReceipt = await this.contract.methods
.toggleMintState(exchangeId, false)
.send({
from: address,
gas: estGas + 1,
gasPrice: await getFairGasPrice(this.web3)
})
return trxReceipt
}
}

View File

@ -65,7 +65,7 @@ export class SideStaking {
/**
* Get DTs in circulation (amount vested not accounted)
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatoken address
* @param {String} datatokenAddress datatoken address
* @return {String}
*/
async getDataTokenCirculatingSupply(
@ -87,7 +87,7 @@ export class SideStaking {
/**
* Get Publisher address
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatoken address
* @param {String} datatokenAddress datatoken address
* @return {String}
*/
async getPublisherAddress(
@ -159,7 +159,7 @@ export class SideStaking {
}
/**
* Get dt balance in the staking contract available for being added as liquidity
* Get dt balance in the staking contract available for being added as liquidity
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
@ -175,7 +175,7 @@ export class SideStaking {
} catch (e) {
this.logger.error(`ERROR: Failed to get: ${e.message}`)
}
result = await this.unitsToAmount(datatokenAddress,result)
result = await this.unitsToAmount(datatokenAddress, result)
return result
}
@ -200,7 +200,7 @@ export class SideStaking {
* Get total amount vesting
* @param {String} ssAddress side staking contract address
* @param {String} datatokenAddress datatokenAddress
* @return {String}
* @return {String}
*/
async getvestingAmount(ssAddress: string, datatokenAddress: string): Promise<string> {
const sideStaking = new this.web3.eth.Contract(this.ssABI, ssAddress)
@ -210,7 +210,7 @@ export class SideStaking {
} catch (e) {
this.logger.error(`ERROR: Failed to get: ${e.message}`)
}
result = await this.unitsToAmount(datatokenAddress,result)
result = await this.unitsToAmount(datatokenAddress, result)
return result
}
@ -251,7 +251,7 @@ export class SideStaking {
} catch (e) {
this.logger.error(`ERROR: Failed to get: ${e.message}`)
}
result = await this.unitsToAmount(datatokenAddress,result)
result = await this.unitsToAmount(datatokenAddress, result)
return result
}
@ -284,7 +284,7 @@ export class SideStaking {
return estGas
}
/**Send vested tokens available to the publisher address, can be called by anyone
/** Send vested tokens available to the publisher address, can be called by anyone
*
* @param {String} account
* @param {String} ssAddress side staking contract address

View File

@ -4,6 +4,7 @@ import { TestContractHandler } from '../../../TestContractHandler'
import { Contract } from 'web3-eth-contract'
import Web3 from 'web3'
import BigNumber from 'bignumber.js'
import BN from 'bn.js'
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
import SSContract from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
@ -32,6 +33,8 @@ describe('Fixed Rate unit test', () => {
let user3: string
let initialBlock: number
let fixedRateAddress: string
let daiAddress: string
let usdcAddress: string
let exchangeId: string
let contracts: TestContractHandler
let fixedRate: FixedRateExchange
@ -41,7 +44,7 @@ describe('Fixed Rate unit test', () => {
let daiContract: Contract
let usdcContract: Contract
const vestedBlocks = 2500000
const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'
it('should deploy contracts', async () => {
contracts = new TestContractHandler(
web3,
@ -72,11 +75,11 @@ describe('Fixed Rate unit test', () => {
user2 = contracts.accounts[3]
user3 = contracts.accounts[4]
exchangeOwner = contracts.accounts[0]
await contracts.deployContracts(factoryOwner, FactoryRouter.abi as AbiItem[])
// initialize fixed rate
//
daiContract = new web3.eth.Contract(
contracts.MockERC20.options.jsonInterface,
@ -87,14 +90,11 @@ describe('Fixed Rate unit test', () => {
contracts.MockERC20.options.jsonInterface,
contracts.usdcAddress
)
console.log(
await usdcContract.methods.decimals().call(),
'USDC DECIMALS IN THIS TEST'
)
})
describe('Test a Fixed Rate Exchange with DAI (18 Decimals)', () => {
@ -110,21 +110,16 @@ describe('Fixed Rate unit test', () => {
const ercData = {
templateIndex: 1,
strings: ['ERC20B1', 'ERC20DT1Symbol'],
addresses: [
contracts.accounts[0],
user3,
contracts.accounts[0],
'0x0000000000000000000000000000000000000000'
],
addresses: [contracts.accounts[0], user3, contracts.accounts[0], ADDRESS_ZERO],
uints: [web3.utils.toWei('1000000'), 0],
bytess: []
}
//[baseToken,owner,marketFeeCollector,allowedSwapper]
// [baseToken,owner,marketFeeCollector,allowedSwapper]
const fixedRateData = {
fixedPriceAddress:contracts.fixedRateAddress,
addresses:[contracts.daiAddress,exchangeOwner,user3, '0x0000000000000000000000000000000000000000'],
uints:[18,18,web3.utils.toWei('1'),1e15,0]
fixedPriceAddress: contracts.fixedRateAddress,
addresses: [contracts.daiAddress, exchangeOwner, user3, ADDRESS_ZERO],
uints: [18, 18, web3.utils.toWei('1'), 1e15, 0]
}
const nftFactory = new NFTFactory(contracts.factory721Address, web3, LoggerInstance)
@ -135,7 +130,7 @@ describe('Fixed Rate unit test', () => {
ercData,
fixedRateData
)
initialBlock = await web3.eth.getBlockNumber()
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
@ -143,49 +138,171 @@ describe('Fixed Rate unit test', () => {
dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
// user2 has no dt1
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
fixedRateAddress = contracts.fixedRateAddress
fixedRate = new FixedRateExchange(web3, LoggerInstance, fixedRateAddress, FixedRate.abi as AbiItem[],contracts.oceanAddress)
fixedRate = new FixedRateExchange(
web3,
LoggerInstance,
fixedRateAddress,
FixedRate.abi as AbiItem[],
contracts.oceanAddress
)
assert(fixedRate != null)
})
it('#isActive - should return true if exchange is active', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(
true
)
expect(await fixedRate.isActive('0x00')).to.equal(
false
)
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
expect(await fixedRate.isActive('0x00')).to.equal(false)
})
it('#deactivate - should deactivate an exchange if exchangeOwner', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
await fixedRate.deactivate(exchangeOwner, exchangeId)
expect(await fixedRate.isActive(exchangeId)).to.equal(false)
})
it('#activate - should activate an exchange if exchangeOwner', async () => {
expect(await fixedRate.isActive(exchangeId)).to.equal(false)
await fixedRate.activate(exchangeOwner, exchangeId)
expect(await fixedRate.isActive(exchangeId)).to.equal(true)
})
it('#activateMint - should activate Mint(allows fixed rate contract to mint dts if required), if exchangeOwner', async () => {
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(false)
await fixedRate.activateMint(exchangeOwner, exchangeId)
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(true)
})
it('#dectivateMint - should deactivate Mint if exchangeOwner', async () => {
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(true)
await fixedRate.deactivateMint(exchangeOwner, exchangeId)
expect((await fixedRate.getExchange(exchangeId)).withMint).to.equal(false)
})
it('#generate exchangeId - should generate a specific exchangeId', async () => {
expect(
await fixedRate.generateExchangeId(contracts.daiAddress, dtAddress, exchangeOwner)
).to.equal(exchangeId)
})
it('#getNumberOfExchanges - should return total number of exchanges', async () => {
expect(await fixedRate.getNumberOfExchanges()).to.equal('1')
})
it('#getExchanges - should return all exchanges ids', async () => {
const exchangeIds = await fixedRate.getExchanges()
expect(exchangeIds[0]).to.equal(exchangeId)
})
it('#getRate - should return rate', async () => {
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
})
it('#setRate - set new rate if exchangeOwner', async () => {
await fixedRate.setRate(exchangeOwner, exchangeId, '2')
expect(await fixedRate.getRate(exchangeId)).to.equal('2')
await fixedRate.setRate(exchangeOwner, exchangeId, '1')
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
})
it('#getDTSupply - should get the dt supply in the exchange', async () => {
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('0')
})
it('#getBTSupply - should get the bt supply in the exchange', async () => {
expect(await fixedRate.getBTSupply(exchangeId)).to.equal('0')
})
it('#getBTNeeded - should get bt amount for a specific dt amount', async () => {
console.log(await fixedRate.getAmountBTIn(exchangeId, '100'))
})
it('#getBTNeeded - should get bt amount for a specific dt amount', async () => {
console.log(await fixedRate.getAmountBTOut(exchangeId, '100'))
})
it('#buyDT - user2 should buy some dt', async () => {
await dtContract.methods.mint(exchangeOwner,web3.utils.toWei('1000')).send({from:exchangeOwner})
await dtContract.methods.approve(fixedRateAddress,web3.utils.toWei('1000')).send({from:exchangeOwner})
await daiContract.methods.transfer(user2,web3.utils.toWei('100')).send({from:exchangeOwner})
await daiContract.methods.approve(fixedRateAddress,web3.utils.toWei('100')).send({from:user2})
const tx = await fixedRate.buyDT(user2,exchangeId,'10','11')
// console.log(tx.events.Swapped.returnValues)
await dtContract.methods
.mint(exchangeOwner, web3.utils.toWei('1000'))
.send({ from: exchangeOwner })
await dtContract.methods
.approve(fixedRateAddress, web3.utils.toWei('1000'))
.send({ from: exchangeOwner })
await daiContract.methods
.transfer(user2, web3.utils.toWei('100'))
.send({ from: exchangeOwner })
await daiContract.methods
.approve(fixedRateAddress, web3.utils.toWei('100'))
.send({ from: user2 })
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
const daiBalanceBefore = new BN(await daiContract.methods.balanceOf(user2).call())
expect(daiBalanceBefore.toString()).to.equal(web3.utils.toWei('100'))
const tx = await fixedRate.buyDT(user2, exchangeId, '10', '11')
// console.log(tx.events.Swapped.returnValues)
assert(tx.events.Swapped != null)
const args = tx.events.Swapped.returnValues
expect(args.exchangeId).to.equal(exchangeId)
expect(args.by).to.equal(user2)
expect(args.dataTokenSwappedAmount).to.equal(web3.utils.toWei('10'))
expect(args.tokenOutAddress).to.equal(dtAddress)
expect(await dtContract.methods.balanceOf(user2).call()).to.equal(
args.dataTokenSwappedAmount
)
expect(
daiBalanceBefore.sub(new BN(args.baseTokenSwappedAmount)).toString()
).to.equal(await daiContract.methods.balanceOf(user2).call())
})
it('#sellDT - user2 should sell some dt', async () => {
await dtContract.methods.approve(fixedRateAddress,web3.utils.toWei('10')).send({from:user2})
const tx = await fixedRate.sellDT(user2,exchangeId,'10','9')
// console.log(tx.events.Swapped.returnValues)
await dtContract.methods
.approve(fixedRateAddress, web3.utils.toWei('10'))
.send({ from: user2 })
const daiBalanceBefore = new BN(await daiContract.methods.balanceOf(user2).call())
const tx = await fixedRate.sellDT(user2, exchangeId, '10', '9')
// console.log(tx.events.Swapped.returnValues)
assert(tx.events.Swapped != null)
const args = tx.events.Swapped.returnValues
expect(args.exchangeId).to.equal(exchangeId)
expect(args.by).to.equal(user2)
expect(args.dataTokenSwappedAmount).to.equal(web3.utils.toWei('10'))
expect(args.tokenOutAddress).to.equal(contracts.daiAddress)
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
expect(
daiBalanceBefore.add(new BN(args.baseTokenSwappedAmount)).toString()
).to.equal(await daiContract.methods.balanceOf(user2).call())
})
it('#getExchange - should return exchange details', async () => {
const result = await fixedRate.getExchange(exchangeId)
expect(result.active).to.equal(true)
expect(result.btDecimals).to.equal('18')
expect(result.dtDecimals).to.equal('18')
expect(result.baseToken).to.equal(contracts.daiAddress)
expect(result.dataToken).to.equal(dtAddress)
expect(result.exchangeOwner).to.equal(exchangeOwner)
expect(result.withMint).to.equal(false)
expect(result.dtBalance).to.equal('10')
expect(result.btBalance).to.equal('0')
expect(result.dtSupply).to.equal('1000')
expect(result.btSupply).to.equal('0')
expect(result.fixedRate).to.equal('1')
})
it('#getFeesInfo - should return exchange fee details', async () => {
const result = await fixedRate.getFeesInfo(exchangeId)
expect(result.marketFee).to.equal('0.001')
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for market and always in basetoken so it's 0.01 DAI
// we made 2 swaps for 10 DT at rate 1, the fee is 0.1% for ocean community and always in basetoken so it's 0.01 DAI
expect(result.marketFeeAvailable).to.equal('0.02') // formatted for basetoken decimals
expect(result.oceanFeeAvailable).to.equal('0.02') // formatted for basetoken decimals
expect(result.marketFeeCollector).to.equal(user3)
expect(result.opfFee).to.equal('0.001')
})
it('#getAllowedSwapper- should return address(0) if not set, if exchangeOwner', async () => {
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(ADDRESS_ZERO)
})
it('#setAllowedSwapper- should return address(0) if not set, if exchangeOwner', async () => {
await fixedRate.setAllowedSwapper(exchangeOwner, exchangeId, user2)
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(user2)
})
})
})

View File

@ -260,15 +260,17 @@ describe('SideStaking unit test', () => {
sideStakingAddress,
erc20Token
)
expect(
await sideStaking.unitsToAmount(erc20Token,await erc20Contract.methods.balanceOf(contracts.accounts[0]).call() )
await sideStaking.unitsToAmount(
erc20Token,
await erc20Contract.methods.balanceOf(contracts.accounts[0]).call()
)
).to.equal(await sideStaking.getvestingAmountSoFar(sideStakingAddress, erc20Token))
expect(
await sideStaking.getvestingLastBlock(sideStakingAddress, erc20Token)
).to.equal((await web3.eth.getBlockNumber()).toString())
})
it('#swapExactAmountIn - should swap', async () => {