Implementation and tests in the protocol for cancelling all orders up to a specific time
This commit is contained in:
committed by
Amir Bandeali
parent
e98b4ea26d
commit
aeb0742434
@@ -30,7 +30,7 @@ contract Exchange is
|
||||
MixinSettlementProxy,
|
||||
MixinWrapperFunctions
|
||||
{
|
||||
string constant public VERSION = "2.0.0-alpha";
|
||||
string constant public VERSION = "2.0.1-alpha";
|
||||
|
||||
function Exchange(
|
||||
IToken _zrxToken,
|
||||
|
@@ -53,38 +53,43 @@ contract IExchange {
|
||||
uint256 takerTokenCancelledAmount,
|
||||
bytes32 indexed orderHash
|
||||
);
|
||||
|
||||
|
||||
event LogCancelBefore(
|
||||
address indexed maker,
|
||||
uint256 salt
|
||||
);
|
||||
|
||||
function ZRX_TOKEN_CONTRACT()
|
||||
public view
|
||||
returns (address);
|
||||
|
||||
|
||||
function TOKEN_TRANSFER_PROXY_CONTRACT()
|
||||
public view
|
||||
returns (address);
|
||||
|
||||
|
||||
function EXTERNAL_QUERY_GAS_LIMIT()
|
||||
public view
|
||||
returns (uint16);
|
||||
|
||||
|
||||
function VERSION()
|
||||
public view
|
||||
returns (string);
|
||||
|
||||
|
||||
function filled(bytes32)
|
||||
public view
|
||||
returns (uint256);
|
||||
|
||||
|
||||
function cancelled(bytes32)
|
||||
public view
|
||||
returns (uint256);
|
||||
|
||||
|
||||
/// @dev Calculates the sum of values already filled and cancelled for a given order.
|
||||
/// @param orderHash The Keccak-256 hash of the given order.
|
||||
/// @return Sum of values already filled and cancelled.
|
||||
function getUnavailableTakerTokenAmount(bytes32 orderHash)
|
||||
public view
|
||||
returns (uint256 unavailableTakerTokenAmount);
|
||||
|
||||
|
||||
/// @dev Calculates partial value given a numerator and denominator.
|
||||
/// @param numerator Numerator.
|
||||
/// @param denominator Denominator.
|
||||
@@ -93,7 +98,7 @@ contract IExchange {
|
||||
function getPartialAmount(uint256 numerator, uint256 denominator, uint256 target)
|
||||
public pure
|
||||
returns (uint256 partialAmount);
|
||||
|
||||
|
||||
/// @dev Checks if rounding error > 0.1%.
|
||||
/// @param numerator Numerator.
|
||||
/// @param denominator Denominator.
|
||||
@@ -102,7 +107,7 @@ contract IExchange {
|
||||
function isRoundingError(uint256 numerator, uint256 denominator, uint256 target)
|
||||
public pure
|
||||
returns (bool isError);
|
||||
|
||||
|
||||
/// @dev Calculates Keccak-256 hash of order with specified parameters.
|
||||
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
|
||||
/// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
|
||||
@@ -110,7 +115,7 @@ contract IExchange {
|
||||
function getOrderHash(address[5] orderAddresses, uint256[6] orderValues)
|
||||
public view
|
||||
returns (bytes32 orderHash);
|
||||
|
||||
|
||||
/// @dev Verifies that an order signature is valid.
|
||||
/// @param signer address of signer.
|
||||
/// @param hash Signed Keccak-256 hash.
|
||||
@@ -126,7 +131,7 @@ contract IExchange {
|
||||
bytes32 s)
|
||||
public pure
|
||||
returns (bool isValid);
|
||||
|
||||
|
||||
/// @dev Fills the input order.
|
||||
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
|
||||
/// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
|
||||
@@ -144,7 +149,7 @@ contract IExchange {
|
||||
bytes32 s)
|
||||
public
|
||||
returns (uint256 takerTokenFilledAmount);
|
||||
|
||||
|
||||
/// @dev Cancels the input order.
|
||||
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
|
||||
/// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
|
||||
@@ -157,6 +162,9 @@ contract IExchange {
|
||||
public
|
||||
returns (uint256 takerTokenCancelledAmount);
|
||||
|
||||
/// @dev Cancels all orders for a specified maker up to a certain time.
|
||||
/// @param salt Orders created with a lower salt value will be cancelled
|
||||
function cancelOrdersBefore(uint256 salt) external;
|
||||
|
||||
/// @dev Fills an order with specified parameters and ECDSA signature. Throws if specified amount not filled entirely.
|
||||
/// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient.
|
||||
|
@@ -43,6 +43,10 @@ contract MixinExchangeCore is
|
||||
mapping (bytes32 => uint256) public filled;
|
||||
mapping (bytes32 => uint256) public cancelled;
|
||||
|
||||
// Mapping of makerAddress => lowest salt an order can have in order to be fillable
|
||||
// Orders with a salt less than their maker's epoch are considered cancelled
|
||||
mapping (address => uint256) public makerEpoch;
|
||||
|
||||
event LogFill(
|
||||
address indexed makerAddress,
|
||||
address takerAddress,
|
||||
@@ -66,6 +70,11 @@ contract MixinExchangeCore is
|
||||
bytes32 indexed orderHash
|
||||
);
|
||||
|
||||
event LogCancelBefore(
|
||||
address indexed maker,
|
||||
uint256 salt
|
||||
);
|
||||
|
||||
/*
|
||||
* Core exchange functions
|
||||
*/
|
||||
@@ -119,6 +128,12 @@ contract MixinExchangeCore is
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Validate order is not cancelled
|
||||
if (order.salt < makerEpoch[order.makerAddress]) {
|
||||
LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), orderHash);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update state
|
||||
filled[orderHash] = safeAdd(filled[orderHash], takerTokenFilledAmount);
|
||||
|
||||
@@ -154,7 +169,7 @@ contract MixinExchangeCore is
|
||||
{
|
||||
// Compute the order hash
|
||||
bytes32 orderHash = getOrderHash(order);
|
||||
|
||||
|
||||
// Validate the order
|
||||
require(order.makerTokenAmount > 0);
|
||||
require(order.takerTokenAmount > 0);
|
||||
@@ -186,7 +201,16 @@ contract MixinExchangeCore is
|
||||
);
|
||||
return takerTokenCancelledAmount;
|
||||
}
|
||||
|
||||
|
||||
/// @param salt Orders created with a salt less than this value will be cancelled.
|
||||
function cancelOrdersBefore(uint256 salt)
|
||||
external
|
||||
{
|
||||
require(salt > makerEpoch[msg.sender]); // epoch must be monotonically increasing
|
||||
makerEpoch[msg.sender] = salt;
|
||||
LogCancelBefore(msg.sender, salt);
|
||||
}
|
||||
|
||||
/// @dev Checks if rounding error > 0.1%.
|
||||
/// @param numerator Numerator.
|
||||
/// @param denominator Denominator.
|
||||
|
@@ -36,4 +36,7 @@ contract MExchangeCore is LibOrder {
|
||||
public
|
||||
returns (uint256 takerTokenCancelledAmount);
|
||||
|
||||
function cancelOrdersBefore(
|
||||
uint256 salt)
|
||||
external;
|
||||
}
|
||||
|
@@ -167,6 +167,18 @@ export class ExchangeWrapper {
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
public async cancelOrdersBeforeAsync(
|
||||
timestamp: BigNumber,
|
||||
from: string,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const txHash = await this._exchange.cancelOrdersBefore.sendTransactionAsync(
|
||||
timestamp,
|
||||
{ from },
|
||||
);
|
||||
const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
|
||||
return tx;
|
||||
}
|
||||
|
||||
public async getOrderHashAsync(signedOrder: SignedOrder): Promise<string> {
|
||||
const order = orderUtils.getOrderStruct(signedOrder);
|
||||
const orderHash = await this._exchange.getOrderHash.callAsync(order);
|
||||
|
@@ -28,6 +28,10 @@ export interface BatchCancelOrders {
|
||||
takerTokenCancelAmounts: BigNumber[];
|
||||
}
|
||||
|
||||
export interface CancelOrdersBefore {
|
||||
timestamp: BigNumber;
|
||||
}
|
||||
|
||||
export interface DefaultOrderParams {
|
||||
exchangeAddress: string;
|
||||
makerAddress: string;
|
||||
|
Reference in New Issue
Block a user