@fleupold/dex-contracts
Version:
Contracts for dFusion multi-token batch auction exchange
115 lines (114 loc) • 4.91 kB
JavaScript
import BN from "bn.js";
import { factory } from "../src/logging";
const log = factory.getLogger("scripts.util");
export async function getBatchExchange(artifacts) {
const BatchExchange = artifacts.require("BatchExchange");
return BatchExchange.deployed();
}
export async function getOwl(artifacts) {
const TokenOWL = artifacts.require("TokenOWL");
const batchExchange = await getBatchExchange(artifacts);
const owlAddress = await batchExchange.feeToken();
return TokenOWL.at(owlAddress);
}
async function setAllowance(token, account, amount, exchange) {
log.info(`Approving BatchExchange at ${exchange.address} for ${amount} token ${token.address}`);
await token.approve(exchange.address, amount, {
from: account,
});
}
export async function setAllowances(users, amount, exchange, tokens) {
for (let i = 0; i < users.length; i++) {
for (let j = 0; j < tokens.length; j++) {
await setAllowance(tokens[j], users[i], amount, exchange);
}
}
}
export async function addTokens(tokenAddresses, account, exchange, owl) {
// Get amount of required OWL for listing all tokens
const feeForAddingToken = await exchange.FEE_FOR_LISTING_TOKEN_IN_OWL();
const totalFees = feeForAddingToken.mul(new BN(tokenAddresses.length));
// Ensure the user has enough OWL balance
const balanceOfOWL = await owl.balanceOf(account);
if (totalFees.gt(balanceOfOWL)) {
throw new Error("Insufficient balance of fee token to complete request.");
}
// Set OWL allowance if necessary
const allowanceOfOWL = await owl.allowance(account, exchange.address);
if (totalFees.gt(allowanceOfOWL)) {
// TODO: Only approve the minimum required amount totalFees.sub(allowanceOfOWL)
await setAllowance(owl, account, totalFees, exchange);
}
// List all tokens (if not listed previously)
const tokens = [];
for (const tokenAddress of tokenAddresses) {
const isTokenListed = await exchange.hasToken(tokenAddress);
if (!isTokenListed) {
await exchange.addToken(tokenAddress, { from: account });
log.info(`Successfully added token ${tokenAddress}`);
}
else {
log.info(`The token ${tokenAddress} was already added`);
}
// Get token information
const tokenId = await exchange.tokenAddressToIdMap(tokenAddress);
tokens.push({
id: tokenId.toNumber(),
address: tokenAddress,
});
}
// Return token information
return tokens;
}
export async function deleteOrders(orderIds, accounts, exchange) {
log.info(`Canceling ${orderIds.length} orders for ${accounts.length} users`);
for (let i = 0; i < orderIds.length; i++) {
const orderId = orderIds[i];
const account = accounts[i];
const cancelReceipt = await exchange.cancelOrders([orderId], {
from: account,
});
const events = cancelReceipt.logs
.map((log) => log.event)
.join(", ");
log.info(`Canceled/Deleted order ${orderId} for user {${account}}. Emitted events: ${events}`);
}
}
export async function submitSolution(name, batchId, solution, solverAddress, exchange) {
log.info(`Submit "${name}":
- Objective value: ${solution.objectiveValue}
- Touched orders: ${solution.touchedorderIds.join(", ")}
- Volumes: ${solution.volumes.join(", ")}
- Prices: ${solution.prices.join(", ")}
- Token ids for prices: ${solution.tokenIdsForPrice.join(", ")}`);
const objectiveValue = await exchange.submitSolution(batchId, 1, solution.owners, solution.touchedorderIds, solution.volumes, solution.prices, solution.tokenIdsForPrice, { from: solverAddress });
log.info(`Transaction for ${name}: ${objectiveValue.tx}`);
}
export async function getBatchId(exchange) {
const batchId = await exchange.getCurrentBatchId();
return batchId.toNumber();
}
export async function createMintableToken(artifacts) {
const ERC20Mintable = artifacts.require("ERC20Mintable");
return ERC20Mintable.new();
}
async function mintToken(token, account, amount, minter) {
log.info(`Mint ${amount} of token ${token.address} for user ${account}. Using ${minter} as the minter`);
await token.mint(account, amount, { from: minter });
}
export async function mintTokens(tokens, users, amount, minter) {
for (let i = 0; i < tokens.length; i++) {
for (let j = 0; j < users.length; j++) {
await mintToken(tokens[i], users[j], amount, minter);
}
}
}
async function mintOwlForUser(owl, user, amount, minter) {
log.info(`Mint ${amount} OWL to ${user}`);
return owl.mintOWL(user, amount, { from: minter });
}
export async function mintOwl(owl, users, amount, minter) {
for (let i = 0; i < users.length; i++) {
await mintOwlForUser(owl, users[i], amount, minter);
}
}