@gnosis.pm/dex-contracts
Version:
Contracts for dFusion multi-token batch auction exchange
104 lines (103 loc) • 4.38 kB
JavaScript
const jsonrpc = "2.0";
const id = 0;
const send = function (method, params, web3Provider) {
return new Promise(function (resolve, reject) {
web3Provider.currentProvider.send({ id, jsonrpc, method, params }, (error, result) => {
if (error) {
reject(error);
}
else {
resolve(result);
}
});
});
};
// Wait for n blocks to pass
/**
* Wait for n (evm) seconds to pass
* @param seconds - time to wait
* @param web3Provider - potentially different in contract tests and system end-to-end testing.
*/
export async function waitForNSeconds(seconds, web3Provider = web3) {
await send("evm_increaseTime", [seconds], web3Provider);
await send("evm_mine", [], web3Provider);
}
export async function closeAuction(instance, web3Provider = web3) {
const time_remaining = (await instance.getSecondsRemainingInBatch()).toNumber();
await waitForNSeconds(time_remaining + 1, web3Provider);
}
/* eslint-disable @typescript-eslint/no-explicit-any */
export async function sendTxAndGetReturnValue(method, ...args) {
const result = await method.call(...args);
await method.sendTransaction(...args);
return result;
}
/* eslint-enable @typescript-eslint/no-explicit-any */
/**
* Finalizes user's pending deposits by updating user's balances for all input tokens.
* It assumes no withdrawals have been requested.
* State of the contract after the execution of this function for tokenAddress:
* ```
* balanceState[userAddress][tokenAddress] = {
* balance: pendingDepositAmount,
* pendingDeposits: null,
* pendingWithdraws: null,
* }
* ```
* @param userAddress - address of the user who deposited
* @param epochTokenLocker - instance of the epoch token locker to which the user deposited
* @param tokenAddresses - list of token addresses for which a deposit is pending
*/
export async function applyBalances(userAddress, epochTokenLocker, tokenAddresses) {
await closeAuction(epochTokenLocker);
for (const tokenAddress of tokenAddresses) {
await epochTokenLocker.withdraw(userAddress, tokenAddress);
}
}
/**
* Makes deposit transactions from a list of Deposit Objects
* @param numTokens - number of tokens to be registered on this exchange.
* @param maxTokens - Maximum number of tokens (a contract contructor parameter)
*/
export const setupGenericStableX = async function (numTokens = 2, maxTokens = 2 ** 16 - 1) {
const MockContract = artifacts.require("MockContract");
const BatchExchange = artifacts.require("BatchExchange");
const feeToken = await MockContract.new();
await feeToken.givenAnyReturnBool(true);
const instance = await BatchExchange.new(maxTokens, feeToken.address);
const tokens = [feeToken];
for (let i = 0; i < numTokens - 1; i++) {
const token = await MockContract.new();
await instance.addToken(token.address);
await token.givenAnyReturnBool(true);
tokens.push(token);
}
return instance;
};
/**
* Makes deposit transactions from a list of Deposit Objects
* @param contract - BatchExchange smart contract
* @param accounts - An array of (unlocked) ethereum account addresses
* @param depositList - Array of Deposit Objects
* @param sufficiencyFactor - Factor of deposit amount to be deposited (default: 1)
*/
export async function makeDeposits(contract, accounts, depositList, sufficiencyFactor = 1) {
for (const deposit of depositList) {
const tokenAddress = await contract.tokenIdToAddressMap(deposit.token);
await contract.deposit(tokenAddress, deposit.amount.muln(sufficiencyFactor), { from: accounts[deposit.user] });
}
}
/**
* Makes placeOrder transactions from a list of Order Objects
* @param contract - BatchExchange smart contract
* @param accounts - An array of (unlocked) ethereum account addresses
* @param orderList - An array of Order Objects
* @param auctionIndex - The auction in which the order should be placed
*/
export async function placeOrders(contract, accounts, orderList, auctionIndex) {
const orderIds = [];
for (const order of orderList) {
orderIds.push((await sendTxAndGetReturnValue(contract.placeOrder, order.buyToken, order.sellToken, auctionIndex, order.buyAmount, order.sellAmount, { from: accounts[order.user] })).toNumber());
}
return orderIds;
}