Skip to content

Commit

Permalink
separate cancelation flows for different invalidators
Browse files Browse the repository at this point in the history
  • Loading branch information
ZumZoom committed Dec 8, 2023
1 parent d72fc3a commit 9b80d11
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 60 deletions.
26 changes: 14 additions & 12 deletions contracts/OrderMixin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,31 +97,33 @@ abstract contract OrderMixin is IOrderMixin, EIP712, OnlyWethReceiver, Predicate
/**
* @notice See {IOrderMixin-cancelOrder}.
*/
function cancelOrder(MakerTraits makerTraits, bytes32 orderHash) public {
if (makerTraits.useBitInvalidator()) {
_bitInvalidator[msg.sender].massInvalidate(makerTraits.nonceOrEpoch(), 0);
} else {
_remainingInvalidator[msg.sender][orderHash] = RemainingInvalidatorLib.fullyFilled();
}
function cancelOrder(bytes32 orderHash) public {
_remainingInvalidator[msg.sender][orderHash] = RemainingInvalidatorLib.fullyFilled();
emit OrderCancelled(orderHash);
}

/**
* @notice See {IOrderMixin-cancelOrders}.
*/
function cancelOrders(MakerTraits[] calldata makerTraits, bytes32[] calldata orderHashes) external {
if (makerTraits.length != orderHashes.length) revert MismatchArraysLengths();
function cancelOrders(bytes32[] calldata orderHashes) external {

Check warning on line 108 in contracts/OrderMixin.sol

View check run for this annotation

Codecov / codecov/patch

contracts/OrderMixin.sol#L108

Added line #L108 was not covered by tests
unchecked {
for (uint256 i = 0; i < makerTraits.length; i++) {
cancelOrder(makerTraits[i], orderHashes[i]);
for (uint256 i = 0; i < orderHashes.length; i++) {
cancelOrder(orderHashes[i]);

Check warning on line 111 in contracts/OrderMixin.sol

View check run for this annotation

Codecov / codecov/patch

contracts/OrderMixin.sol#L110-L111

Added lines #L110 - L111 were not covered by tests
}
}
}

/**
* @notice See {IOrderMixin-bitsInvalidateForOrder}.
* @notice See {IOrderMixin-invalidateBit}.
*/
function invalidateBit(MakerTraits makerTraits) external {
invalidateBits(makerTraits, 0);
}

/**
* @notice See {IOrderMixin-invalidateBits}.
*/
function bitsInvalidateForOrder(MakerTraits makerTraits, uint256 additionalMask) external {
function invalidateBits(MakerTraits makerTraits, uint256 additionalMask) public {
if (!makerTraits.useBitInvalidator()) revert OrderIsNotSuitableForMassInvalidation();
_bitInvalidator[msg.sender].massInvalidate(makerTraits.nonceOrEpoch(), additionalMask);
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/extensions/ETHOrders.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ contract ETHOrders is IPostInteraction, OnlyWethReceiver {
/**
* @notice Sets ordersMakersBalances to 0, refunds ETH and does standard order cancellation on Limit Order Protocol.
*/
function cancelOrder(MakerTraits makerTraits, bytes32 orderHash) external {
function cancelOrder(bytes32 orderHash) external {
if (ordersMakersBalances[orderHash].maker != msg.sender) revert InvalidOrder();
IOrderMixin(_limitOrderProtocol).cancelOrder(makerTraits, orderHash);
IOrderMixin(_limitOrderProtocol).cancelOrder(orderHash);
uint256 refundETHAmount = ordersMakersBalances[orderHash].balance;
ordersMakersBalances[orderHash].balance = 0;
_WETH.safeWithdrawTo(refundETHAmount, msg.sender);
Expand Down
14 changes: 9 additions & 5 deletions contracts/interfaces/IOrderMixin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,24 +87,28 @@ interface IOrderMixin {

/**
* @notice Cancels order's quote
* @param makerTraits Order makerTraits
* @param orderHash Hash of the order to cancel
*/
function cancelOrder(MakerTraits makerTraits, bytes32 orderHash) external;
function cancelOrder(bytes32 orderHash) external;

/**
* @notice Cancels orders' quotes
* @param makerTraits Orders makerTraits
* @param orderHashes Hashes of the orders to cancel
*/
function cancelOrders(MakerTraits[] calldata makerTraits, bytes32[] calldata orderHashes) external;
function cancelOrders(bytes32[] calldata orderHashes) external;

/**
* @notice Cancels quote of the maker (works for bit-invalidating orders only)
* @param makerTraits Order makerTraits
*/
function invalidateBit(MakerTraits makerTraits) external;

/**
* @notice Cancels all quotes of the maker (works for bit-invalidating orders only)
* @param makerTraits Order makerTraits
* @param additionalMask Additional bitmask to invalidate orders
*/
function bitsInvalidateForOrder(MakerTraits makerTraits, uint256 additionalMask) external;
function invalidateBits(MakerTraits makerTraits, uint256 additionalMask) external;

/**
* @notice Returns order hash, hashed with limit order protocol contract EIP712
Expand Down
56 changes: 16 additions & 40 deletions test/LimitOrderProtocol.js
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ describe('LimitOrderProtocol', function () {
await expect(fillTx).to.changeTokenBalances(weth, [addr, ethOrders, addr1], [ether('0.2'), ether('-0.2'), '0']);

/// Cancel order
const canceltx = ethOrders.connect(addr1).cancelOrder(order.makerTraits, orderHash);
const canceltx = ethOrders.connect(addr1).cancelOrder(orderHash);
await expect(canceltx).to.changeTokenBalance(weth, ethOrders, ether('-0.1'));
await expect(canceltx).to.changeEtherBalance(addr1, ether('0.1'));

Expand Down Expand Up @@ -879,7 +879,7 @@ describe('LimitOrderProtocol', function () {
const data = buildOrderData(chainId, swap.address, order);
const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value);

await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash);
await swap.connect(addr1).cancelOrder(orderHash);

expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0');
});
Expand Down Expand Up @@ -923,53 +923,31 @@ describe('LimitOrderProtocol', function () {
const { swap, chainId, order } = await loadFixture(orderCancelationInit);
const data = buildOrderData(chainId, swap.address, order);
const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value);
await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash);
await swap.connect(addr1).cancelOrder(orderHash);
expect(await swap.remainingInvalidatorForOrder(addr1.address, orderHash)).to.equal('0');
});

it('should cancel own order with massInvalidate', async function () {
const { dai, weth, swap, chainId } = await loadFixture(orderCancelationInit);

it('should cancel own order with invalidateBit', async function () {
const { swap } = await loadFixture(orderCancelationInit);
const orderNonce = 0;
const order = buildOrder({
makerAsset: dai.address,
takerAsset: weth.address,
makingAmount: 1,
takingAmount: 1,
maker: addr1.address,
makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }),
});
const data = buildOrderData(chainId, swap.address, order);
const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value);

await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash);
const makerTraits = buildMakerTraitsRFQ({ nonce: orderNonce });
await swap.connect(addr1).invalidateBit(makerTraits);
const invalidator = await swap.bitInvalidatorForOrder(addr1.address, orderNonce);
expect(invalidator).to.equal('1');
});

it('should cancel own order with massInvalidate, huge nonce', async function () {
const { dai, weth, swap, chainId } = await loadFixture(orderCancelationInit);

it('should cancel own order with invalidateBit, huge nonce', async function () {
const { swap } = await loadFixture(orderCancelationInit);
const orderNonce = 1023;
const order = buildOrder({
makerAsset: dai.address,
takerAsset: weth.address,
makingAmount: 1,
takingAmount: 1,
maker: addr1.address,
makerTraits: buildMakerTraitsRFQ({ nonce: orderNonce }),
});
const data = buildOrderData(chainId, swap.address, order);
const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value);

await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash);
const makerTraits = buildMakerTraitsRFQ({ nonce: orderNonce });
await swap.connect(addr1).invalidateBit(makerTraits);
const invalidator = await swap.bitInvalidatorForOrder(addr1.address, orderNonce);
expect(invalidator).to.equal(1n << 255n);
});

it('should cancel any hash', async function () {
const { swap, order } = await loadFixture(orderCancelationInit);
await swap.connect(addr1).cancelOrder(order.makerTraits, '0x0000000000000000000000000000000000000000000000000000000000000001');
const { swap } = await loadFixture(orderCancelationInit);
await swap.connect(addr1).cancelOrder('0x0000000000000000000000000000000000000000000000000000000000000001');
expect(await swap.remainingInvalidatorForOrder(addr1.address, '0x0000000000000000000000000000000000000000000000000000000000000001')).to.equal('0');
});

Expand All @@ -980,13 +958,13 @@ describe('LimitOrderProtocol', function () {
const data = buildOrderData(chainId, swap.address, order);
const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value);

await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash);
await swap.connect(addr1).cancelOrder(orderHash);

await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)))
.to.be.revertedWithCustomError(swap, 'InvalidatedOrder');
});

it('should not fill cancelled order, massInvalidate', async function () {
it('should not fill cancelled order, invalidateBit', async function () {
const { dai, weth, swap, chainId } = await loadFixture(orderCancelationInit);

const orderNonce = 0;
Expand All @@ -1000,10 +978,8 @@ describe('LimitOrderProtocol', function () {
});
const signature = await signOrder(order, chainId, swap.address, addr1);
const { r, _vs: vs } = ethers.utils.splitSignature(signature);
const data = buildOrderData(chainId, swap.address, order);
const orderHash = ethers.utils._TypedDataEncoder.hash(data.domain, data.types, data.value);

await swap.connect(addr1).cancelOrder(order.makerTraits, orderHash);
await swap.connect(addr1).invalidateBit(order.makerTraits);

await expect(swap.fillOrder(order, r, vs, 1, fillWithMakingAmount(1)))
.to.be.revertedWithCustomError(swap, 'BitInvalidatedOrder');
Expand Down
2 changes: 1 addition & 1 deletion test/MeasureGas.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe('MeasureGas', function () {
});

const orderHash = await swap.hashOrder(order);
const tx = await swap.cancelOrder(order.makerTraits, orderHash); ;
const tx = await swap.cancelOrder(orderHash); ;
console.log(`invalidate order gasUsed: ${(await tx.wait()).gasUsed}`);
});
});

0 comments on commit 9b80d11

Please sign in to comment.