@@ -85,6 +85,9 @@ abstract contract BasicSwap7683 is Base7683 {
8585
8686 /**
8787 * @dev Settles multiple orders by dispatching the settlement instructions.
88+ * The proper status of all the orders (filled) is validated on the Base7683 before calling this function.
89+ * It assumes that all orders were originated in the same originDomain so it uses the the one from the first one for
90+ * dispatching the message, but if some order differs on the originDomain it can be re-settle later.
8891 * @param _orderIds The IDs of the orders to settle.
8992 * @param _ordersOriginData The original data of the orders.
9093 * @param _ordersFillerData The filler data for the orders.
@@ -98,85 +101,135 @@ abstract contract BasicSwap7683 is Base7683 {
98101 override
99102 {
100103 // at this point we are sure all orders are filled, use the first order to get the originDomain
101- // if some order differs on the originDomain ir can be re-settle later
104+ // if some order differs on the originDomain it can be re-settle later
102105 _dispatchSettle (OrderEncoder.decode (_ordersOriginData[0 ]).originDomain, _orderIds, _ordersFillerData);
103106 }
104107
105108 /**
106109 * @dev Refunds multiple OnchainCrossChain orders by dispatching refund instructions.
110+ * The proper status of all the orders (NOT filled and expired) is validated on the Base7683 before calling this
111+ * function.
112+ * It assumes that all orders were originated in the same originDomain so it uses the the one from the first one for
113+ * dispatching the message, but if some order differs on the originDomain it can be re-refunded later.
107114 * @param _orders The orders to refund.
108115 * @param _orderIds The IDs of the orders to refund.
109116 */
110117 function _refundOrders (OnchainCrossChainOrder[] memory _orders , bytes32 [] memory _orderIds ) internal override {
111- // at this point we are sure all orders are filled, use the first order to get the originDomain
112- // if some order differs on the originDomain ir can be re-refunded later
113118 _dispatchRefund (OrderEncoder.decode (_orders[0 ].orderData).originDomain, _orderIds);
114119 }
115120
116121 /**
117122 * @dev Refunds multiple GaslessCrossChain orders by dispatching refund instructions.
123+ * The proper status of all the orders (NOT filled and expired) is validated on the Base7683 before calling this
124+ * function.
125+ * It assumes that all orders were originated in the same originDomain so it uses the the one from the first one for
126+ * dispatching the message, but if some order differs on the originDomain it can be re-refunded later.
118127 * @param _orders The orders to refund.
119128 * @param _orderIds The IDs of the orders to refund.
120129 */
121130 function _refundOrders (GaslessCrossChainOrder[] memory _orders , bytes32 [] memory _orderIds ) internal override {
122- // at this point we are sure all orders are filled, use the first order to get the originDomain
123- // if some order differs on the originDomain ir can be re-refunded later
124131 _dispatchRefund (OrderEncoder.decode (_orders[0 ].orderData).originDomain, _orderIds);
125132 }
126133
127134 /**
128135 * @dev Handles settling an individual order, should be called by the inheriting contract when receiving a setting
129136 * instruction from a remote chain.
137+ * @param _messageOrigin The domain from which the message originates.
138+ * @param _messageSender The address of the sender on the origin domain.
130139 * @param _orderId The ID of the order to settle.
131140 * @param _receiver The receiver address (encoded as bytes32).
132141 */
133- function _handleSettleOrder (bytes32 _orderId , bytes32 _receiver ) internal virtual {
134- // check if the order is opened to ensure it belongs to this domain, skip otherwise
135- if (orderStatus[_orderId] != OPENED) return ;
136-
137- (,bytes memory _orderData ) = abi.decode (openOrders[_orderId], (bytes32 , bytes ));
138- OrderData memory orderData = OrderEncoder.decode (_orderData);
142+ function _handleSettleOrder (
143+ uint32 _messageOrigin ,
144+ bytes32 _messageSender ,
145+ bytes32 _orderId ,
146+ bytes32 _receiver
147+ ) internal virtual {
148+ (
149+ bool isEligible ,
150+ OrderData memory orderData
151+ ) = _checkOrderEligibility (_messageOrigin, _messageSender, _orderId);
152+
153+ if (! isEligible) return ;
139154
140155 orderStatus[_orderId] = SETTLED;
141156
142157 address receiver = TypeCasts.bytes32ToAddress (_receiver);
143158 address inputToken = TypeCasts.bytes32ToAddress (orderData.inputToken);
144159
145- if (inputToken == address (0 )) {
146- Address.sendValue (payable (receiver), orderData.amountIn);
147- } else {
148- IERC20 (inputToken).safeTransfer (receiver, orderData.amountIn);
149- }
160+ _transferTokenOut (inputToken, receiver, orderData.amountIn);
150161
151162 emit Settled (_orderId, receiver);
152163 }
153164
154165 /**
155166 * @dev Handles refunding an individual order, should be called by the inheriting contract when receiving a
156167 * refunding instruction from a remote chain.
168+ * @param _messageOrigin The domain from which the message originates.
169+ * @param _messageSender The address of the sender on the origin domain.
157170 * @param _orderId The ID of the order to refund.
158171 */
159- function _handleRefundOrder (bytes32 _orderId ) internal virtual {
160- // check if the order is opened to ensure it belongs to this domain, skip otherwise
161- if (orderStatus[_orderId] != OPENED) return ;
172+ function _handleRefundOrder (uint32 _messageOrigin , bytes32 _messageSender , bytes32 _orderId ) internal virtual {
173+ (
174+ bool isEligible ,
175+ OrderData memory orderData
176+ ) = _checkOrderEligibility (_messageOrigin, _messageSender, _orderId);
162177
163- (,bytes memory _orderData ) = abi.decode (openOrders[_orderId], (bytes32 , bytes ));
164- OrderData memory orderData = OrderEncoder.decode (_orderData);
178+ if (! isEligible) return ;
165179
166180 orderStatus[_orderId] = REFUNDED;
167181
168182 address orderSender = TypeCasts.bytes32ToAddress (orderData.sender);
169183 address inputToken = TypeCasts.bytes32ToAddress (orderData.inputToken);
170184
171- if (inputToken == address (0 )) {
172- Address.sendValue (payable (orderSender), orderData.amountIn);
173- } else {
174- IERC20 (inputToken).safeTransfer (orderSender, orderData.amountIn);
175- }
185+ _transferTokenOut (inputToken, orderSender, orderData.amountIn);
176186
177187 emit Refunded (_orderId, orderSender);
178188 }
179189
190+ /**
191+ * @notice Checks if order is eligible for settlement or refund .
192+ * @dev Order must be OPENED and the message was sent from the appropriated chain and contract.
193+ * @param _messageOrigin The origin domain of the message.
194+ * @param _messageSender The sender identifier of the message.
195+ * @param _orderId The unique identifier of the order.
196+ * @return A boolean indicating if the order is valid, and the decoded OrderData structure.
197+ */
198+ function _checkOrderEligibility (
199+ uint32 _messageOrigin ,
200+ bytes32 _messageSender ,
201+ bytes32 _orderId
202+ ) internal virtual returns (bool , OrderData memory ) {
203+ OrderData memory orderData;
204+
205+ // check if the order is opened to ensure it belongs to this domain, skip otherwise
206+ if (orderStatus[_orderId] != OPENED) return (false , orderData);
207+
208+ (,bytes memory _orderData ) = abi.decode (openOrders[_orderId], (bytes32 , bytes ));
209+ orderData = OrderEncoder.decode (_orderData);
210+
211+ if (orderData.destinationDomain != _messageOrigin || orderData.destinationSettler != _messageSender)
212+ return (false , orderData);
213+
214+ return (true , orderData);
215+ }
216+
217+ /**
218+ * @notice Transfers tokens or ETH out of the contract.
219+ * @dev If _token is the zero address, transfers ETH using a safe method; otherwise, performs an ERC20 token
220+ * transfer.
221+ * @param _token The address of the token to transfer (use address(0) for ETH).
222+ * @param _to The recipient address.
223+ * @param _amount The amount of tokens or ETH to transfer.
224+ */
225+ function _transferTokenOut (address _token , address _to , uint256 _amount ) internal {
226+ if (_token == address (0 )) {
227+ Address.sendValue (payable (_to), _amount);
228+ } else {
229+ IERC20 (_token).safeTransfer (_to, _amount);
230+ }
231+ }
232+
180233 /**
181234 * @dev Gets the ID of a GaslessCrossChainOrder.
182235 * @param _order The GaslessCrossChainOrder to compute the ID for.
0 commit comments