Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions contracts/src/matching/HyperdriveMatchingEngineV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ contract HyperdriveMatchingEngineV2 is
/// @notice The EIP712 typehash of the OrderIntent struct.
bytes32 public constant ORDER_INTENT_TYPEHASH =
keccak256(
"OrderIntent(address trader,address counterparty,address hyperdrive,uint256 fundAmount,uint256 bondAmount,uint256 minVaultSharePrice,Options options,uint8 orderType,uint256 minMaturityTime,uint256 maxMaturityTime,uint256 expiry,bytes32 salt)"
"OrderIntent(address trader,address counterparty,address hyperdrive,uint256 fundAmount,uint256 bondAmount,uint256 minVaultSharePrice,Options options,uint8 orderType,uint256 minMaturityTime,uint256 maxMaturityTime,uint256 expiry,bytes32 salt)Options(address destination,bool asBase)"
);

/// @notice The EIP712 typehash of the Options struct.
Expand Down Expand Up @@ -76,6 +76,9 @@ contract HyperdriveMatchingEngineV2 is
/// @param _order2 The second order to match.
/// @param _surplusRecipient The address that receives the surplus funds
/// from matching the trades.
/// @dev In the case of _handleMint(), the matching logic is "exact price"
/// semantics according to the order intent, to within numerical precision,
/// with any surplus going to the party that executed the match.
function matchOrders(
OrderIntent calldata _order1,
OrderIntent calldata _order2,
Expand Down Expand Up @@ -383,6 +386,11 @@ contract HyperdriveMatchingEngineV2 is
OrderIntent calldata _makerOrder,
OrderIntent calldata _takerOrder
) external nonReentrant {
// Ensure sender is the trader.
if (msg.sender != _takerOrder.trader) {
revert InvalidSender();
}

// Validate maker order and taker order.
bytes32 makerOrderHash = _validateOrdersWithTaker(
_makerOrder,
Expand Down Expand Up @@ -839,23 +847,42 @@ contract HyperdriveMatchingEngineV2 is
OrderIntent[] calldata _orders
) external nonReentrant {
bytes32[] memory orderHashes = new bytes32[](_orders.length);
for (uint256 i = 0; i < _orders.length; i++) {
uint256 validOrderCount = 0;

uint256 orderCount = _orders.length;
for (uint256 i = 0; i < orderCount; i++) {
// Skip if order is already fully executed or cancelled
bytes32 orderHash = hashOrderIntent(_orders[i]);
if (
orderAmountsUsed[orderHash].bondAmount >=
_orders[i].bondAmount ||
orderAmountsUsed[orderHash].fundAmount >=
_orders[i].fundAmount ||
isCancelled[orderHash]
) {
continue;
}

// Ensure sender is the trader.
if (msg.sender != _orders[i].trader) {
revert InvalidSender();
}

// Verify signature.
bytes32 orderHash = hashOrderIntent(_orders[i]);
if (!verifySignature(orderHash, _orders[i].signature, msg.sender)) {
revert InvalidSignature();
}

// Cancel the order.
isCancelled[orderHash] = true;
orderHashes[i] = orderHash;
orderHashes[validOrderCount] = orderHash;
validOrderCount++;
}

// Emit event with assembly to truncate array to actual size
assembly {
mstore(orderHashes, validOrderCount)
}
emit OrdersCancelled(msg.sender, orderHashes);
}

Expand Down
8 changes: 8 additions & 0 deletions test/units/matching/HyperdriveMatchingEngineV2Test.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,9 @@ contract HyperdriveMatchingEngineV2Test is HyperdriveTest {
uint256 bobShortBalanceBefore = _getShortBalance(bob);

// Fill order
vm.startPrank(bob);
matchingEngine.fillOrder(makerOrder, takerOrder);
vm.stopPrank();

// Verify balances
assertLt(baseToken.balanceOf(alice), aliceBaseBalanceBefore);
Expand Down Expand Up @@ -675,7 +677,9 @@ contract HyperdriveMatchingEngineV2Test is HyperdriveTest {
uint256 bobLongBalanceBefore = _getLongBalance(bob);

// Fill order
vm.startPrank(bob);
matchingEngine.fillOrder(makerOrder, takerOrder);
vm.stopPrank();

// Verify balances
assertLt(baseToken.balanceOf(alice), aliceBaseBalanceBefore);
Expand Down Expand Up @@ -706,10 +710,12 @@ contract HyperdriveMatchingEngineV2Test is HyperdriveTest {
IHyperdriveMatchingEngineV2.OrderType.OpenLong // Same as maker
);

vm.startPrank(bob);
vm.expectRevert(
IHyperdriveMatchingEngineV2.InvalidOrderCombination.selector
);
matchingEngine.fillOrder(makerOrder, invalidTakerOrder);
vm.stopPrank();

// Test expired order
makerOrder.expiry = block.timestamp - 1;
Expand All @@ -722,8 +728,10 @@ contract HyperdriveMatchingEngineV2Test is HyperdriveTest {
IHyperdriveMatchingEngineV2.OrderType.OpenShort
);

vm.startPrank(bob);
vm.expectRevert(IHyperdriveMatchingEngineV2.AlreadyExpired.selector);
matchingEngine.fillOrder(makerOrder, validTakerOrder);
vm.stopPrank();
}

// Helper functions.
Expand Down