UNPKG

@fleupold/dex-contracts

Version:

Contracts for dFusion multi-token batch auction exchange

121 lines (120 loc) 5.86 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const BatchExchange = artifacts.require("BatchExchange"); const logging_1 = require("../src/logging"); const log = logging_1.factory.getLogger("scripts.spread_orders"); const bn_js_1 = __importDefault(require("bn.js")); const readline_1 = __importDefault(require("readline")); const utilities_1 = require("../test/utilities"); const fee_token_liquidity_1 = require("../src/fee_token_liquidity"); const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout, }); const promptUser = function (message) { return new Promise((resolve) => rl.question(message, (answer) => resolve(answer))); }; const formatAmount = function (amount, token) { const exponent = token.decimals; if (exponent) { return new bn_js_1.default(10).pow(new bn_js_1.default(exponent)).muln(amount); } throw new Error("Insufficient token data for amount formatting"); }; const argv = require("yargs") .option("tokens", { alias: "t", type: "string", describe: "Collection of trusted tokenIds", coerce: (str) => { return str.split(",").map((t) => parseInt(t)); }, }) .option("accountId", { describe: "Account index of the order placer", type: "int", default: 0, }) .option("spread", { type: "float", describe: "Percentage increase required for trade (fees not accounted)", default: 0.25, }) .option("sellAmount", { type: "int", describe: "Maximum sell amount (in full token units)", default: 1000, }) .option("validFrom", { type: "int", describe: "Number of batches (from current) until order become valid", default: 3, }) .option("expiry", { type: "int", describe: "Maximum auction batch for which these orders are valid", default: Math.pow(2, 32) - 1, }) .demand(["tokens"]) .help("Make sure that you have an RPC connection to the network in consideration. For network configurations, please see truffle-config.js Example usage \n npx truffle exec scripts/place_spread_orders.js --tokens=2,3,4 --accountId 0 --spread 0.3 --validFrom 5") .version(false).argv; module.exports = (callback) => __awaiter(void 0, void 0, void 0, function* () { try { const instance = yield BatchExchange.deployed(); const accounts = yield web3.eth.getAccounts(); const account = accounts[argv.accountId]; const batch_index = (yield instance.getCurrentBatchId()).toNumber(); log.info("Communicating with exchange for requested token info..."); const token_data = yield fee_token_liquidity_1.fetchTokenInfoFromExchange(instance, argv.tokens, artifacts); argv.tokens.map((id) => { const token = token_data.get(id); log.info(`Found ${token === null || token === void 0 ? void 0 : token.symbol} with ID ${id} at ${token === null || token === void 0 ? void 0 : token.address} having ${token === null || token === void 0 ? void 0 : token.decimals} decimals`); }); const expectedReturnFactor = 1 + argv.spread / 100; const sellAmount = argv.sellAmount; const buyAmount = sellAmount * expectedReturnFactor; let buyTokens = []; let sellTokens = []; let buyAmounts = []; let sellAmounts = []; for (let i = 0; i < argv.tokens.length - 1; i++) { const tokenA = token_data.get(argv.tokens[i]); for (let j = i + 1; j < argv.tokens.length; j++) { const tokenB = token_data.get(argv.tokens[j]); if (tokenA && tokenB) { buyTokens = buyTokens.concat(tokenA.id, tokenB.id); sellTokens = sellTokens.concat(tokenB.id, tokenA.id); buyAmounts = buyAmounts.concat(formatAmount(buyAmount, tokenA), formatAmount(buyAmount, tokenB)); sellAmounts = sellAmounts.concat(formatAmount(sellAmount, tokenB), formatAmount(sellAmount, tokenA)); log.info(`Sell ${sellAmounts.slice(-2)[0]} ${tokenB.symbol} for ${buyAmounts.slice(-2)[0]} ${tokenA.symbol}`); log.info(`Sell ${sellAmounts.slice(-2)[1]} ${tokenA.symbol} for ${buyAmounts.slice(-2)[1]} ${tokenB.symbol}`); } } } const validFroms = Array(buyTokens.length).fill(batch_index + argv.validFrom); const validTos = Array(buyTokens.length).fill(argv.expiry); const answer = yield promptUser("Are you sure you want to send this transaction to the EVM? [yN] "); if (answer.toLowerCase() == "y" || answer.toLowerCase() == "yes") { const ids = yield utilities_1.sendTxAndGetReturnValue(instance.placeValidFromOrders, buyTokens, sellTokens, validFroms, validTos, buyAmounts, sellAmounts, { from: account, }); log.info(`Successfully placed spread orders with IDs ${ids}.\n`); } callback(); } catch (error) { callback(error); } });