diff --git a/solidity/orders/script/CreateOrder.s.sol b/solidity/orders/script/CreateOrder.s.sol index 7fbf10e72..8d86bf185 100644 --- a/solidity/orders/script/CreateOrder.s.sol +++ b/solidity/orders/script/CreateOrder.s.sol @@ -54,10 +54,12 @@ contract CreateOrder is Script { expectedRejectExpression: string(expectedRejectExpression) }); CommonTypes.Coin[] memory maxKeychainFees = new CommonTypes.Coin[](0); - Types.OrderData memory orderData = Types.OrderData({ + Types.BasicOrderData memory orderData = Types.BasicOrderData({ thresholdPrice: thresholdPrice, priceCondition: priceCondition, - pricePair: pricePair, + pricePair: pricePair + }); + Types.CommonExecutionData memory commonExecutionData = Types.CommonExecutionData({ creatorDefinedTxFields: creatorDefinedTxFields, signRequestData: signRequestData }); @@ -66,7 +68,7 @@ contract CreateOrder is Script { mockSlinkyPrecompile.setPrice(pricePair.base, pricePair.quote, thresholdPrice); vm.etch(IWARDEN_PRECOMPILE_ADDRESS, address(wPrecompile).code); vm.startBroadcast(broadcaster); - FACTORY.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + FACTORY.createOrder(abi.encode(orderData), commonExecutionData, maxKeychainFees, OrderType.Basic, salt); vm.stopBroadcast(); } diff --git a/solidity/orders/src/AdvancedOrder.sol b/solidity/orders/src/AdvancedOrder.sol index 16043eaa7..58f0a7a40 100644 --- a/solidity/orders/src/AdvancedOrder.sol +++ b/solidity/orders/src/AdvancedOrder.sol @@ -3,11 +3,21 @@ pragma solidity >=0.8.25 <0.9.0; import { GetPriceResponse, ISlinky, ISLINKY_PRECOMPILE_ADDRESS } from "precompile-slinky/ISlinky.sol"; import { IAsync, IASYNC_PRECOMPILE_ADDRESS } from "precompile-async/IAsync.sol"; +import { Types as CommonTypes } from "precompile-common/Types.sol"; import { AbstractOrder } from "./AbstractOrder.sol"; import { Caller, ExecutionData, IExecution } from "./IExecution.sol"; +import { Registry } from "./Registry.sol"; +import { Types } from "./Types.sol"; + +error ConditionNotMet(); +error ExecutedError(); +error Unauthorized(); + +event Executed(); contract AdvancedOrder is AbstractOrder, IExecution { - Types.OrderData public orderData; + Types.AdvancedOrderData public orderData; + Types.CommonExecutionData public commonExecutionData; ISlinky private immutable SLINKY_PRECOMPILE; IAsync private immutable ASYNC_PRECOMPILE; @@ -20,12 +30,13 @@ contract AdvancedOrder is AbstractOrder, IExecution { uint256 private _validUntil; constructor( - Types.OrderData memory _orderData, + Types.AdvancedOrderData memory _orderData, + Types.CommonExecutionData memory _executionData, CommonTypes.Coin[] memory maxKeychainFees, address scheduler, address registry ) - AbstractOrder(_orderData.signRequestData, _orderData.creatorDefinedTxFields, scheduler, registry) + AbstractOrder(_executionData.signRequestData, _executionData.creatorDefinedTxFields, scheduler, registry) { SLINKY_PRECOMPILE = ISlinky(ISLINKY_PRECOMPILE_ADDRESS); SLINKY_PRECOMPILE.getPrice(_orderData.pricePair.base, _orderData.pricePair.quote); @@ -39,13 +50,14 @@ contract AdvancedOrder is AbstractOrder, IExecution { } orderData = _orderData; + commonExecutionData = _executionData; _scheduler = scheduler; _callers.push(Caller.Scheduler); _validUntil = block.timestamp + 24 hours; } - function canExecute() external view override returns (bool) { - if(block.timestamp > _validUntil) { + function canExecute() public view override returns (bool) { + if (block.timestamp > _validUntil) { return false; } // TODO: @@ -69,7 +81,11 @@ contract AdvancedOrder is AbstractOrder, IExecution { uint256, uint256 maxPriorityFeePerGas, uint256 maxFeePerGas - ) external override returns (bool, bytes32) { + ) + external + override + returns (bool, bytes32) + { if (msg.sender != _scheduler) { revert Unauthorized(); } @@ -84,14 +100,14 @@ contract AdvancedOrder is AbstractOrder, IExecution { bytes[] memory emptyAccessList = new bytes[](0); (bytes memory unsignedTx, bytes32 txHash) = this.encodeUnsignedEIP1559( - nonce, gas, maxPriorityFeePerGas, maxFeePerGas, emptyAccessList, orderData.creatorDefinedTxFields + nonce, gas, maxPriorityFeePerGas, maxFeePerGas, emptyAccessList, commonExecutionData.creatorDefinedTxFields ); _unsignedTx = unsignedTx; bytes memory signRequestInput = abi.encodePacked(txHash); - _executed = this.createSignRequest(orderData.signRequestData, signRequestInput, _coins); + _executed = this.createSignRequest(commonExecutionData.signRequestData, signRequestInput, _coins); if (_executed) { emit Executed(); @@ -102,20 +118,18 @@ contract AdvancedOrder is AbstractOrder, IExecution { REGISTRY.addTransaction(tx.origin, txHash); return (_executed, txHash); - } function callers() external view override returns (Caller[] memory callersList) { return _callers; } - function isExecuted() external view override returns (bool) { + function isExecuted() public view override returns (bool) { return _executed; } - function executionData() external view returns (ExecutionData memory data) { - data = this.buildExecutionData(orderData.creatorDefinedTxFields); + data = this.buildExecutionData(commonExecutionData.creatorDefinedTxFields); } function getTx() external view returns (bytes memory transaction) { @@ -125,4 +139,4 @@ contract AdvancedOrder is AbstractOrder, IExecution { transaction = _unsignedTx; } -} \ No newline at end of file +} diff --git a/solidity/orders/src/BasicOrder.sol b/solidity/orders/src/BasicOrder.sol index 22cff3d50..8aa7c86cd 100644 --- a/solidity/orders/src/BasicOrder.sol +++ b/solidity/orders/src/BasicOrder.sol @@ -18,7 +18,8 @@ error InvalidThresholdPrice(); event Executed(); contract BasicOrder is AbstractOrder, IExecution, ReentrancyGuard { - Types.OrderData public orderData; + Types.BasicOrderData public orderData; + Types.CommonExecutionData public commonExecutionData; ISlinky private immutable SLINKY_PRECOMPILE; Registry private immutable REGISTRY; @@ -30,12 +31,13 @@ contract BasicOrder is AbstractOrder, IExecution, ReentrancyGuard { // solhint-disable-next-line constructor( - Types.OrderData memory _orderData, + Types.BasicOrderData memory _orderData, + Types.CommonExecutionData memory _executionData, CommonTypes.Coin[] memory maxKeychainFees, address scheduler, address registry ) - AbstractOrder(_orderData.signRequestData, _orderData.creatorDefinedTxFields, scheduler, registry) + AbstractOrder(_executionData.signRequestData, _executionData.creatorDefinedTxFields, scheduler, registry) { if (_orderData.thresholdPrice == 0) { revert InvalidThresholdPrice(); @@ -51,6 +53,7 @@ contract BasicOrder is AbstractOrder, IExecution, ReentrancyGuard { } orderData = _orderData; + commonExecutionData = _executionData; _scheduler = scheduler; _callers.push(Caller.Scheduler); } @@ -93,14 +96,14 @@ contract BasicOrder is AbstractOrder, IExecution, ReentrancyGuard { bytes[] memory emptyAccessList = new bytes[](0); (bytes memory unsignedTx, bytes32 txHash) = this.encodeUnsignedEIP1559( - nonce, gas, maxPriorityFeePerGas, maxFeePerGas, emptyAccessList, orderData.creatorDefinedTxFields + nonce, gas, maxPriorityFeePerGas, maxFeePerGas, emptyAccessList, commonExecutionData.creatorDefinedTxFields ); _unsignedTx = unsignedTx; bytes memory signRequestInput = abi.encodePacked(txHash); - _executed = this.createSignRequest(orderData.signRequestData, signRequestInput, _coins); + _executed = this.createSignRequest(commonExecutionData.signRequestData, signRequestInput, _coins); if (_executed) { emit Executed(); @@ -122,7 +125,7 @@ contract BasicOrder is AbstractOrder, IExecution, ReentrancyGuard { } function executionData() external view returns (ExecutionData memory data) { - data = this.buildExecutionData(orderData.creatorDefinedTxFields); + data = this.buildExecutionData(commonExecutionData.creatorDefinedTxFields); } function getTx() external view returns (bytes memory transaction) { diff --git a/solidity/orders/src/OrderFactory.sol b/solidity/orders/src/OrderFactory.sol index 24567e549..c190e3cf0 100644 --- a/solidity/orders/src/OrderFactory.sol +++ b/solidity/orders/src/OrderFactory.sol @@ -5,6 +5,7 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { Types } from "./Types.sol"; import { Types as CommonTypes } from "precompile-common/Types.sol"; import { BasicOrder } from "./BasicOrder.sol"; +import { AdvancedOrder } from "./AdvancedOrder.sol"; import { Registry } from "./Registry.sol"; import { Create3 } from "@0xsequence/create3/contracts/Create3.sol"; import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; @@ -75,7 +76,8 @@ contract OrderFactory is Ownable, ReentrancyGuard { * @return order The address of the newly created order */ function createOrder( - Types.OrderData calldata _orderData, + bytes calldata _orderData, + Types.CommonExecutionData calldata _executionData, CommonTypes.Coin[] calldata maxKeychainFees, OrderType orderType, bytes32 salt @@ -98,9 +100,11 @@ contract OrderFactory is Ownable, ReentrancyGuard { emit SaltUsed(guardedSalt, origin); if (orderType == OrderType.Basic) { - return _createBasicOrder(guardedSalt, _orderData, maxKeychainFees, scheduler); + Types.BasicOrderData memory basicOrderData = abi.decode(_orderData, (Types.BasicOrderData)); + return _createBasicOrder(guardedSalt, basicOrderData, _executionData, maxKeychainFees, scheduler); } else if (orderType == OrderType.Advanced) { - return _createAdvancedOrder(guardedSalt, _orderData, maxKeychainFees); + Types.AdvancedOrderData memory advancedOrderData = abi.decode(_orderData, (Types.AdvancedOrderData)); + return _createAdvancedOrder(guardedSalt, advancedOrderData, _executionData, maxKeychainFees, scheduler); } else { revert UnsupportedOrder(); } @@ -123,20 +127,22 @@ contract OrderFactory is Ownable, ReentrancyGuard { * @notice Internal function to create a BasicOrder using CREATE3 * @param salt The unique salt provided by the frontend * @param _orderData The data required to create the order + * @param _executionData The data required for order execution * @param maxKeychainFees The maximum fees allowed * @param _scheduler The scheduler address * @return The address of the newly created BasicOrder */ function _createBasicOrder( bytes32 salt, - Types.OrderData calldata _orderData, + Types.BasicOrderData memory _orderData, + Types.CommonExecutionData calldata _executionData, CommonTypes.Coin[] calldata maxKeychainFees, address _scheduler ) internal returns (address) { - bytes memory bytecode = getBasicOrderBytecode(_orderData, maxKeychainFees, _scheduler); + bytes memory bytecode = getBasicOrderBytecode(_orderData, _executionData, maxKeychainFees, _scheduler); address orderAddress = Create3.create3(salt, bytecode); @@ -155,26 +161,68 @@ contract OrderFactory is Ownable, ReentrancyGuard { } function _createAdvancedOrder( - bytes32, - Types.OrderData calldata, - CommonTypes.Coin[] calldata + bytes32 salt, + Types.AdvancedOrderData memory _orderData, + Types.CommonExecutionData calldata _executionData, + CommonTypes.Coin[] calldata maxKeychainFees, + address _scheduler ) internal - pure returns (address) { - revert Unimplemented(); + bytes memory bytecode = getAdvancedOrderBytecode(_orderData, _executionData, maxKeychainFees, _scheduler); + + address orderAddress = Create3.create3(salt, bytecode); + + address expectedAddress = Create3.addressOf(salt); + if (orderAddress == address(0) || orderAddress != expectedAddress) { + revert OrderDeploymentFailed(salt); + } + + orders[orderAddress] = msg.sender; + + REGISTRY.register(orderAddress); + + emit OrderCreated(msg.sender, OrderType.Advanced, orderAddress); + + return orderAddress; } /** * @notice Prepares the creation bytecode for BasicOrder * @param _orderData The data required to create the order + * @param _executionData The data required for order execution * @param maxKeychainFees The maximum fees allowed * @param _scheduler The scheduler address * @return The bytecode for deploying BasicOrder */ function getBasicOrderBytecode( - Types.OrderData calldata _orderData, + Types.BasicOrderData memory _orderData, + Types.CommonExecutionData calldata _executionData, + CommonTypes.Coin[] calldata maxKeychainFees, + address _scheduler + ) + internal + view + returns (bytes memory) + { + return abi.encodePacked( + type(BasicOrder).creationCode, + abi.encode(_orderData, _executionData, maxKeychainFees, _scheduler, address(REGISTRY)) + ); + } + + /** + * @notice Prepares the creation bytecode for AdvancedOrder + * @param _orderData The data required to create the order + * @param _executionData The data required for order execution + * @param maxKeychainFees The maximum fees allowed + * @param _scheduler The scheduler address + * @return The bytecode for deploying AdvancedOrder + */ + function getAdvancedOrderBytecode( + Types.AdvancedOrderData memory _orderData, + Types.CommonExecutionData calldata _executionData, CommonTypes.Coin[] calldata maxKeychainFees, address _scheduler ) @@ -183,7 +231,8 @@ contract OrderFactory is Ownable, ReentrancyGuard { returns (bytes memory) { return abi.encodePacked( - type(BasicOrder).creationCode, abi.encode(_orderData, maxKeychainFees, _scheduler, address(REGISTRY)) + type(AdvancedOrder).creationCode, + abi.encode(_orderData, _executionData, maxKeychainFees, _scheduler, address(REGISTRY)) ); } } diff --git a/solidity/orders/src/Types.sol b/solidity/orders/src/Types.sol index 6c0fc0006..ad3fbd7f8 100644 --- a/solidity/orders/src/Types.sol +++ b/solidity/orders/src/Types.sol @@ -18,11 +18,22 @@ library Types { GTE } - // Data for execution - struct OrderData { + // Data for basic order creation + struct BasicOrderData { uint256 thresholdPrice; PriceCondition priceCondition; PricePair pricePair; + } + + // Data for advanced order creation + struct AdvancedOrderData { + uint64 futureId; + PriceCondition priceCondition; + PricePair pricePair; + } + + // Data for execution + struct CommonExecutionData { CreatorDefinedTxFields creatorDefinedTxFields; SignRequestData signRequestData; } diff --git a/solidity/orders/test/BasicOrder.t.sol b/solidity/orders/test/BasicOrder.t.sol index 74137a08e..9d2de20e1 100644 --- a/solidity/orders/test/BasicOrder.t.sol +++ b/solidity/orders/test/BasicOrder.t.sol @@ -48,7 +48,8 @@ struct TestData { contract BasicOrderTest is Test { TestData private _testData; - Types.OrderData private _orderData; + Types.BasicOrderData private _orderData; + Types.CommonExecutionData private _executionData; IExecution private _order; Caller[] private _expectedCallers; bytes32 private _txHash; @@ -148,10 +149,13 @@ contract BasicOrderTest is Test { // Initialize _orderData with valid values bytes[] memory analyzers; - _orderData = Types.OrderData({ + _orderData = Types.BasicOrderData({ thresholdPrice: _testData.thresholdPrice, priceCondition: Types.PriceCondition.LTE, - pricePair: _testData.pricePair, + pricePair: _testData.pricePair + }); + + _executionData = Types.CommonExecutionData({ signRequestData: Types.SignRequestData({ keyId: _testData.goodKeyId, analyzers: analyzers, @@ -196,10 +200,12 @@ contract BasicOrderTest is Test { } bytes memory data = getTestSwapData(); - Types.OrderData memory orderData = Types.OrderData({ + Types.BasicOrderData memory orderData = Types.BasicOrderData({ thresholdPrice: _testData.thresholdPrice, priceCondition: cond, - pricePair: _testData.pricePair, + pricePair: _testData.pricePair + }); + Types.CommonExecutionData memory executionData = Types.CommonExecutionData({ signRequestData: Types.SignRequestData({ keyId: keyId, analyzers: analyzers, @@ -226,8 +232,9 @@ contract BasicOrderTest is Test { vm.expectEmit(true, true, false, false); emit OrderCreated(address(this), OrderType.Basic, address(this)); - address orderAddress = - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, orderSalt); + address orderAddress = _testData.orderFactory.createOrder( + abi.encode(orderData), executionData, maxKeychainFees, OrderType.Basic, orderSalt + ); assertEq(address(_testData.orderFactory), _testData.registry.executions(orderAddress)); assertEq(address(this), _testData.orderFactory.orders(orderAddress)); @@ -314,10 +321,13 @@ contract BasicOrderTest is Test { bytes[] memory analyzers; bytes memory encryptionKey; bytes memory data = getTestSwapData(); - Types.OrderData memory orderData = Types.OrderData({ + Types.BasicOrderData memory orderData = Types.BasicOrderData({ thresholdPrice: _testData.thresholdPrice, priceCondition: Types.PriceCondition.LTE, - pricePair: _testData.pricePair, + pricePair: _testData.pricePair + }); + + Types.CommonExecutionData memory executionData = Types.CommonExecutionData({ signRequestData: Types.SignRequestData({ keyId: _testData.goodKeyId, analyzers: analyzers, @@ -336,6 +346,7 @@ contract BasicOrderTest is Test { }); _orderData = orderData; + _executionData = executionData; } function test_BasicOrderRevertWhenInvalidScheduler() public { @@ -343,25 +354,29 @@ contract BasicOrderTest is Test { vm.expectRevert(InvalidScheduler.selector); - new BasicOrder(_orderData, maxKeychainFees, address(0), address(_testData.registry)); + new BasicOrder(_orderData, _executionData, maxKeychainFees, address(0), address(_testData.registry)); } function test_BasicOrderRevertWhenInvalidExpectedApproveExpression() public { CommonTypes.Coin[] memory maxKeychainFees; - _orderData.signRequestData.expectedApproveExpression = ""; + _executionData.signRequestData.expectedApproveExpression = ""; vm.expectRevert(Create3.ErrorCreatingContract.selector); bytes32 orderSalt = keccak256(abi.encodePacked(address(this), block.number, "InvalidApproveExpression")); - _testData.orderFactory.createOrder(_orderData, maxKeychainFees, OrderType.Basic, orderSalt); + _testData.orderFactory.createOrder( + abi.encode(_orderData), _executionData, maxKeychainFees, OrderType.Basic, orderSalt + ); } function test_BasicOrderRevertWhenInvalidExpectedRejectExpression() public { CommonTypes.Coin[] memory maxKeychainFees; - _orderData.signRequestData.expectedRejectExpression = ""; + _executionData.signRequestData.expectedRejectExpression = ""; vm.expectRevert(Create3.ErrorCreatingContract.selector); bytes32 orderSalt = keccak256(abi.encodePacked(address(this), block.number, "InvalidRejectExpression")); - _testData.orderFactory.createOrder(_orderData, maxKeychainFees, OrderType.Basic, orderSalt); + _testData.orderFactory.createOrder( + abi.encode(_orderData), _executionData, maxKeychainFees, OrderType.Basic, orderSalt + ); } function test_BasicOrderRevertWhenInvalidThresholdPrice() public { @@ -370,16 +385,20 @@ contract BasicOrderTest is Test { vm.expectRevert(Create3.ErrorCreatingContract.selector); bytes32 orderSalt = keccak256(abi.encodePacked(address(this), block.number, "InvalidThresholdPrice")); - _testData.orderFactory.createOrder(_orderData, maxKeychainFees, OrderType.Basic, orderSalt); + _testData.orderFactory.createOrder( + abi.encode(_orderData), _executionData, maxKeychainFees, OrderType.Basic, orderSalt + ); } function test_BasicOrderRevertWhenInvalidTxTo() public { CommonTypes.Coin[] memory maxKeychainFees; - _orderData.creatorDefinedTxFields.to = address(0); + _executionData.creatorDefinedTxFields.to = address(0); vm.expectRevert(Create3.ErrorCreatingContract.selector); bytes32 orderSalt = keccak256(abi.encodePacked(address(this), block.number, "InvalidTxTo")); - _testData.orderFactory.createOrder(_orderData, maxKeychainFees, OrderType.Basic, orderSalt); + _testData.orderFactory.createOrder( + abi.encode(_orderData), _executionData, maxKeychainFees, OrderType.Basic, orderSalt + ); } function test_FactoryConstructorRevertWhenInvalidRegistry() public { @@ -474,9 +493,11 @@ contract BasicOrderTest is Test { address computedAddress = _testData.orderFactory.computeOrderAddress(tx.origin, salt); // Create the order - Types.OrderData memory orderData = _orderData; + bytes memory orderData = abi.encode(_orderData); + Types.CommonExecutionData memory executionData = _executionData; CommonTypes.Coin[] memory maxKeychainFees; - address orderAddress = _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + address orderAddress = + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); // Assert that the computed address matches the deployed order address assertEq(computedAddress, orderAddress, "Computed address does not match deployed order address"); @@ -498,9 +519,10 @@ contract BasicOrderTest is Test { assertEq(computedAddress.code.length, 0, "Order address should not be deployed yet"); // Create the order - Types.OrderData memory orderData = _orderData; + bytes memory orderData = abi.encode(_orderData); + Types.CommonExecutionData memory executionData = _executionData; CommonTypes.Coin[] memory maxKeychainFees; - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); // Now, the contract should be deployed assertEq(computedAddress.code.length > 0, true, "Order contract was not deployed at computed address"); @@ -510,29 +532,31 @@ contract BasicOrderTest is Test { bytes32 salt = keccak256(abi.encodePacked("reused_salt")); // First creation should succeed - Types.OrderData memory orderData = _orderData; + bytes memory orderData = abi.encode(_orderData); + Types.CommonExecutionData memory executionData = _executionData; CommonTypes.Coin[] memory maxKeychainFees; - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); // Expect revert when using the same salt again vm.expectRevert(SaltAlreadyUsed.selector); - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); } function test_createOrderWithDifferentSenderCanUseSameSalt() public { bytes32 salt = keccak256(abi.encodePacked("shared_salt")); // Create order with original sender - Types.OrderData memory orderData = _orderData; + bytes memory orderData = abi.encode(_orderData); + Types.CommonExecutionData memory executionData = _executionData; CommonTypes.Coin[] memory maxKeychainFees; - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); // Change the caller to a different address address newSender = address(0xBEEF); vm.prank(address(this), newSender); // This should succeed because the salt is guarded by msg.sender - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); } function test_computeOrderAddressGuardedBySender() public { @@ -543,10 +567,11 @@ contract BasicOrderTest is Test { address computedAddressOriginal = _testData.orderFactory.computeOrderAddress(tx.origin, salt); // Create order with original sender - Types.OrderData memory orderData = _orderData; + bytes memory orderData = abi.encode(_orderData); + Types.CommonExecutionData memory executionData = _executionData; CommonTypes.Coin[] memory maxKeychainFees; address orderAddressOriginal = - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); // Assert that the computed address matches the deployed address for original sender assertEq( @@ -562,7 +587,7 @@ contract BasicOrderTest is Test { // Create order with different sender vm.prank(address(this), differentSender); address orderAddressDifferent = - _testData.orderFactory.createOrder(orderData, maxKeychainFees, OrderType.Basic, salt); + _testData.orderFactory.createOrder(orderData, executionData, maxKeychainFees, OrderType.Basic, salt); // Assert that the computed address matches the deployed address for different sender assertEq(