@fleupold/dex-contracts
Version:
Contracts for dFusion multi-token batch auction exchange
112 lines (111 loc) • 5.75 kB
JavaScript
;
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 });
exports.placeFeeTokenLiquidityOrders = exports.fetchTokenInfoFromExchange = void 0;
const bn_js_1 = __importDefault(require("bn.js"));
const MAXU32 = new bn_js_1.default(2).pow(new bn_js_1.default(32)).sub(new bn_js_1.default(1));
/**
* Used to recover relevant {@link TokenInfo | TokenInfo} by ID from the exchange such as number of decimals or name.
* @param exchange - An instance of deployed Batch Exchange Contract
* @param tokenIds - An array of token ids as listed on the Batch Exchange.
* @param artifacts - A context-like object providing a gateway to Truffle contract ABIs.
* @returns A mapping of TokenInfo objects fetched from the exchange.
* Note that nullish TokenInfo objects are returned in places where the requested token ID failed to fetch.
*/
function fetchTokenInfoFromExchange(exchange, tokenIds, artifacts) {
return __awaiter(this, void 0, void 0, function* () {
const ERC20 = artifacts.require("ERC20Detailed");
// Fetching token data from EVM
const tokenObjects = new Map();
yield Promise.all(tokenIds.map((id) => __awaiter(this, void 0, void 0, function* () {
const tokenAddress = yield exchange.tokenIdToAddressMap(id);
let tokenInfo;
try {
const tokenInstance = yield ERC20.at(tokenAddress);
const [symbol, decimals] = yield Promise.all([
tokenInstance.symbol(),
tokenInstance.decimals(),
]);
tokenInfo = {
id: id,
symbol: symbol,
decimals: decimals.toNumber(),
address: tokenAddress,
};
}
catch (err) {
// This generic try-catch is essentially a TokenNotFoundError
// Could occur when the given ID slot is not occupied by a registered token on the exhchange
// or if the code registered at address occupied by a token slot is not that of and ERC20 token
tokenInfo = {
id: id,
address: tokenAddress,
};
}
tokenObjects.set(id, tokenInfo);
})));
return tokenObjects;
});
}
exports.fetchTokenInfoFromExchange = fetchTokenInfoFromExchange;
/**
* A handy function providing fee token liquidity by placing orders selling the fee token
* at the specified provision price for each specified token.
* @param exchange - BatchExchange Smart Contract
* @param tokenIds - An array of token indices as represented on the exchange
* @param provisionPrice - Price at which liquidity is to be provided
* @param sellAmountOwl - Amount of feeToken to be sold
* @param artifacts - A context-like object providing a gateway to Truffle contract ABIs.
* @returns Void Promise
*/
function placeFeeTokenLiquidityOrders(exchange, tokenIds, provisionPrice, sellAmountOwl, artifacts) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const minBuyAmounts = [];
const validTokenIds = [];
const feeToken = yield fetchTokenInfoFromExchange(exchange, [0], artifacts);
// This is expected to always be OWL which has 18 digits.
const feeDigits = ((_a = feeToken.get(0)) === null || _a === void 0 ? void 0 : _a.decimals) || 18;
const tokenInfo = yield fetchTokenInfoFromExchange(exchange, tokenIds, artifacts);
for (const tokenId of tokenIds) {
const numDigits = (_b = tokenInfo.get(tokenId)) === null || _b === void 0 ? void 0 : _b.decimals;
if (numDigits) {
validTokenIds.push(tokenId);
if (numDigits < feeDigits) {
minBuyAmounts.push(sellAmountOwl
.mul(provisionPrice)
.div(new bn_js_1.default(10).pow(new bn_js_1.default(feeDigits - numDigits))));
}
else {
minBuyAmounts.push(sellAmountOwl
.mul(provisionPrice)
.mul(new bn_js_1.default(10).pow(new bn_js_1.default(numDigits - feeDigits))));
}
}
}
const numOrders = validTokenIds.length;
const batchId = (yield exchange.getCurrentBatchId()).toNumber();
if (numOrders == 0) {
return [];
}
yield exchange.placeValidFromOrders(validTokenIds, // buyTokens
Array(numOrders).fill(0), // sellTokens
Array(numOrders).fill(batchId + 2), // validFroms (all to begin 2 batches from now)
Array(numOrders).fill(MAXU32), // validTos
minBuyAmounts, // buyAmounts
Array(numOrders).fill(sellAmountOwl));
return validTokenIds;
});
}
exports.placeFeeTokenLiquidityOrders = placeFeeTokenLiquidityOrders;