@@ -14,6 +14,7 @@ import { Errors } from "../libraries/Errors.sol";
1414import { EIP712Alien } from "../mocks/EIP712Alien.sol " ;
1515import { OrderLib, IOrderMixin } from "../OrderLib.sol " ;
1616
17+ // This contract is owning makers' funds for native orders
1718contract NativeOrderImpl is IERC1271 , EIP712Alien , OnlyWethReceiver {
1819 using Clones for address ;
1920 using AddressLib for Address;
@@ -22,40 +23,45 @@ contract NativeOrderImpl is IERC1271, EIP712Alien, OnlyWethReceiver {
2223 using OrderLib for IOrderMixin.Order;
2324 using MakerTraitsLib for MakerTraits;
2425
25- event NativeOrderCancelled (bytes32 orderHash , uint256 balance );
26- event NativeOrderCancelledByResolver (bytes32 orderHash , uint256 balance , uint256 resolverReward );
26+ event NativeOrderCancelled (uint256 balance );
27+ event NativeOrderCancelledByResolver (uint256 balance , uint256 resolverReward );
2728
28- error OnlyLimitOrderProtocolViolation (address sender , address limitOrderProtocol );
2929 error OnlyFactoryViolation (address sender , address factory );
30- error OnlyMakerViolation (address sender , address maker );
30+ error OnlyMakerViolation (address sender , uint80 makerTail );
3131 error ResolverAccessTokenMissing (address resolver , address accessToken );
32- error OrderIsIncorrect (address expected , address actual );
3332 error OrderShouldBeExpired (uint256 currentTime , uint256 expirationTime );
3433 error CanNotCancelForZeroBalance ();
35- error RescueFundsTooMuch (uint256 requested , uint256 available );
3634 error CancellationDelayViolation (uint256 timePassedSinceExpiration , uint256 requiredDelay );
35+ error WrongMakerArgument (address maker , uint80 expectedTail );
3736
3837 uint256 private constant _CANCEL_GAS_LOWER_BOUND = 70_000 ;
3938
4039 IWETH private immutable _WETH;
4140 address private immutable _LOP;
42- address private immutable _IMPLEMENTATION = address (this );
4341 address private immutable _FACTORY;
4442 IERC20 private immutable _ACCESS_TOKEN;
4543 uint256 private immutable _CANCELLATION_DELAY;
4644
45+ struct Purpose {
46+ uint80 orderHashTail;
47+ uint80 makerTail;
48+ uint40 expiration;
49+ }
50+
51+ Purpose public purpose;
52+
4753 modifier onlyFactory {
4854 if (msg .sender != _FACTORY) revert OnlyFactoryViolation (msg .sender , _FACTORY);
4955 _;
5056 }
5157
52- modifier onlyResolver {
53- if (_ACCESS_TOKEN. balanceOf ( msg .sender ) == 0 ) revert ResolverAccessTokenMissing (msg .sender , address (_ACCESS_TOKEN) );
58+ modifier onlyMaker {
59+ if (uint80 ( uint160 ( msg .sender )) != purpose.makerTail ) revert OnlyMakerViolation (msg .sender , purpose.makerTail );
5460 _;
5561 }
5662
57- modifier onlyMaker ( address maker ) {
58- if (msg .sender != maker ) revert OnlyMakerViolation (msg .sender , maker );
63+ modifier onlyResolver {
64+ if (_ACCESS_TOKEN. balanceOf ( msg .sender ) == 0 ) revert ResolverAccessTokenMissing (msg .sender , address (_ACCESS_TOKEN) );
5965 _;
6066 }
6167
@@ -78,89 +84,63 @@ contract NativeOrderImpl is IERC1271, EIP712Alien, OnlyWethReceiver {
7884 _CANCELLATION_DELAY = cancellationDelay;
7985 }
8086
81- function depositAndApprove () external payable onlyFactory {
87+ function deposit (address maker , bytes32 orderHash , uint40 expiration ) external payable onlyFactory {
88+ purpose = Purpose ({
89+ orderHashTail: uint80 (uint256 (orderHash)),
90+ makerTail: uint80 (uint160 (maker)),
91+ expiration: expiration
92+ });
8293 _WETH.safeDeposit (msg .value );
8394 _WETH.forceApprove (_LOP, msg .value );
8495 }
8596
86- function isValidSignature (bytes32 hash , bytes calldata signature ) external view returns (bytes4 ) {
87- // Extract order from signature via calldata type casting
88- IOrderMixin.Order calldata makerOrder ;
89- assembly ( "memory-safe" ) { // solhint-disable-line no-inline-assembly
90- makerOrder := signature.offset
97+ function isValidSignature (bytes32 hash , bytes calldata /* signature */ ) external view returns (bytes4 ) {
98+ uint80 orderHashTail = purpose.orderHashTail;
99+ uint256 expiration = purpose.expiration ;
100+ if ( uint80 ( uint256 (hash)) != orderHashTail) {
101+ return 0xffffffff ;
91102 }
92-
93- // Check order args by CREATE2 salt validation
94- bytes32 makerOrderHash = makerOrder.hash (_domainSeparatorV4 ());
95- address clone = _IMPLEMENTATION.predictDeterministicAddress (makerOrderHash, _FACTORY);
96- if (clone != address (this )) {
97- return bytes4 (0 );
98- }
99-
100- // Check if patched order from signature matches LOP filling order
101- bytes32 orderHash = _patchOrderMakerAndHash (makerOrder);
102- if (orderHash != hash) {
103- return bytes4 (0 );
103+ if (block .timestamp >= expiration) {
104+ return 0xffffffff ;
104105 }
105-
106106 return this .isValidSignature.selector ;
107107 }
108108
109- function cancelOrder (IOrderMixin.Order calldata makerOrder ) external onlyMaker (makerOrder.maker. get ()) {
110- uint256 balance = _cancelOrder (makerOrder, 0 );
111- bytes32 orderHash = _patchOrderMakerAndHash (makerOrder );
112- emit NativeOrderCancelled (orderHash, balance);
109+ function cancelOrder () external onlyMaker {
110+ uint256 balance = _WETH. safeBalanceOf ( address ( this ) );
111+ _WETH. safeWithdrawTo (balance, msg . sender );
112+ emit NativeOrderCancelled (balance);
113113 }
114114
115- function cancelExpiredOrderByResolver (IOrderMixin.Order calldata makerOrder , uint256 rewardLimit ) external onlyResolver {
116- uint256 orderExpiration = makerOrder.makerTraits.getExpirationTime ();
117- if (! makerOrder.makerTraits.isExpired ()) revert OrderShouldBeExpired (block .timestamp , orderExpiration);
118-
119- uint256 resolverReward = 0 ;
120- if (rewardLimit > 0 ) {
121- if (block .timestamp - orderExpiration < _CANCELLATION_DELAY) revert CancellationDelayViolation (block .timestamp - orderExpiration, _CANCELLATION_DELAY);
122- resolverReward = Math.min (rewardLimit, block .basefee * _CANCEL_GAS_LOWER_BOUND * 1.1e18 / 1e18 );
115+ function rescueFunds (address token , address to , uint256 amount ) external onlyMaker {
116+ if (token == address (0 )) {
117+ (bool success , ) = to.call { value: amount }("" );
118+ if (! success) revert Errors.ETHTransferFailed ();
119+ } else {
120+ IERC20 (token).safeTransfer (to, amount);
123121 }
124- uint256 balance = _cancelOrder (makerOrder, resolverReward);
125- bytes32 orderHash = _patchOrderMakerAndHash (makerOrder);
126- emit NativeOrderCancelledByResolver (orderHash, balance, resolverReward);
127122 }
128123
129- function _cancelOrder (IOrderMixin.Order calldata makerOrder , uint256 resolverReward ) private returns (uint256 balance ) {
130- bytes32 makerOrderHash = makerOrder.hash (_domainSeparatorV4 ());
131- address clone = _IMPLEMENTATION.predictDeterministicAddress (makerOrderHash, _FACTORY);
132- if (clone != address (this )) revert OrderIsIncorrect (clone, address (this ));
124+ function cancelExpiredOrderByResolver (address maker , uint256 rewardLimit ) external onlyResolver {
125+ uint80 makerTail = purpose.makerTail;
126+ uint256 purposeExpiration = purpose.expiration;
127+ if (uint80 (uint160 (maker)) != makerTail) revert WrongMakerArgument (maker, makerTail);
128+ if (block .timestamp < purposeExpiration) revert OrderShouldBeExpired (block .timestamp , purposeExpiration);
133129
134- balance = _WETH.safeBalanceOf (address (this ));
130+ uint256 balance = _WETH.safeBalanceOf (address (this ));
135131 if (balance == 0 ) revert CanNotCancelForZeroBalance ();
136-
137- _WETH.safeWithdraw (balance);
138- if (resolverReward > 0 ) {
132+ uint256 resolverReward;
133+ if (rewardLimit > 0 ) {
134+ if (block .timestamp - purposeExpiration < _CANCELLATION_DELAY) revert CancellationDelayViolation (block .timestamp - purposeExpiration, _CANCELLATION_DELAY);
135+ resolverReward = Math.min (rewardLimit, block .basefee * _CANCEL_GAS_LOWER_BOUND * 1.1e18 / 1e18 ); // base fee + 10%
139136 balance -= resolverReward;
140137 (bool success , ) = msg .sender .call { value: resolverReward }("" );
141138 if (! success) revert Errors.ETHTransferFailed ();
142139 }
143140 if (balance > 0 ) {
144- (bool success , ) = makerOrder. maker. get () .call { value: balance }("" );
141+ (bool success , ) = maker.call { value: balance }("" );
145142 if (! success) revert Errors.ETHTransferFailed ();
146143 }
147- }
148-
149- function rescueFunds (address token , address to , uint256 amount ) external onlyResolver {
150- if (token == address (0 )) {
151- payable (to).transfer (amount);
152- } else if (IWETH (token) == _WETH) {
153- uint256 remainingOrderAmount = _WETH.allowance (address (this ), _LOP);
154- uint256 extraAmount = _WETH.safeBalanceOf (address (this )) - remainingOrderAmount;
155- if (amount > extraAmount) revert RescueFundsTooMuch (amount, extraAmount);
156- _WETH.safeTransfer (to, amount);
157- } else {
158- IERC20 (token).safeTransfer (to, amount);
159- }
160- }
161-
162- function _patchOrderMakerAndHash (IOrderMixin.Order memory order ) private view returns (bytes32 ) {
163- order.maker = Address.wrap (uint160 (address (this )));
164- return order.hashMemory (_domainSeparatorV4 ());
144+ emit NativeOrderCancelledByResolver (balance, resolverReward);
165145 }
166146}
0 commit comments