11// SPDX-License-Identifier: MIT
22pragma solidity ^ 0.8.25 ;
33
4+ import "@openzeppelin/contracts/access/Ownable.sol " ;
5+ import "@openzeppelin/contracts/utils/ReentrancyGuard.sol " ;
6+
47/**
58 * @title LimitOrderBook
69 * @dev A contract for managing limit orders with off-chain execution
710 * @dev This contract is designed to be used on HyperEVM
811 * @notice Users can place limit orders which are executed by off-chain bots when price conditions are met
912 * @notice Executors can be authorized to mark orders as executed
1013 */
11- contract LimitOrderBook {
14+ contract LimitOrderBook is Ownable , ReentrancyGuard {
1215 /*//////////////////////////////////////////////////////////////
1316 ERRORS
1417 //////////////////////////////////////////////////////////////*/
1518
16- error InvalidPrice ();
17- error InvalidAmount ();
18- error OrderNotFound ();
19- error NotOrderOwner ();
20- error OrderAlreadyExecuted ();
21- error OrderNotExecutable ();
22- error UnauthorizedExecutor ();
23- error NotOwner ();
19+ error LimitOrderBook_InvalidPrice ();
20+ error LimitOrderBook_InvalidAmount ();
21+ error LimitOrderBook_OrderNotFound ();
22+ error LimitOrderBook_NotOrderOwner ();
23+ error LimitOrderBook_OrderAlreadyExecuted ();
24+ error LimitOrderBook_OrderNotExecutable ();
25+ error LimitOrderBook_UnauthorizedExecutor ();
2426
2527 /*//////////////////////////////////////////////////////////////
2628 TYPES
@@ -42,7 +44,6 @@ contract LimitOrderBook {
4244
4345 // Access control for executors
4446 mapping (address => bool ) public s_authorizedExecutors;
45- address public s_owner;
4647
4748 /*//////////////////////////////////////////////////////////////
4849 EVENTS
@@ -58,27 +59,21 @@ contract LimitOrderBook {
5859 MODIFIERS
5960 //////////////////////////////////////////////////////////////*/
6061
61- modifier onlyOwner () {
62- if (msg .sender != s_owner) revert NotOwner ();
63- _;
64- }
65-
6662 modifier onlyAuthorizedExecutor () {
67- if (! s_authorizedExecutors[msg .sender ]) revert UnauthorizedExecutor ();
63+ if (! s_authorizedExecutors[msg .sender ]) revert LimitOrderBook_UnauthorizedExecutor ();
6864 _;
6965 }
7066
7167 modifier validOrder (uint256 orderId ) {
72- if (s_orders[orderId].user == address (0 )) revert OrderNotFound ();
68+ if (s_orders[orderId].user == address (0 )) revert LimitOrderBook_OrderNotFound ();
7369 _;
7470 }
7571
7672 /*//////////////////////////////////////////////////////////////
7773 CONSTRUCTOR
7874 //////////////////////////////////////////////////////////////*/
7975
80- constructor () {
81- s_owner = msg .sender ;
76+ constructor (address initialOwner ) Ownable (initialOwner) {
8277 // Initially, allow anyone to execute (can be changed later)
8378 // This supports the permissionless bot execution model
8479 s_authorizedExecutors[address (0 )] = true ; // Flag to indicate permissionless execution
@@ -94,10 +89,10 @@ contract LimitOrderBook {
9489 * @param amount The amount/quantity for the order
9590 * @return orderId The unique identifier for the placed order
9691 */
97- function placeOrder (uint256 price , uint256 amount ) external returns (uint256 orderId ) {
92+ function placeOrder (uint256 price , uint256 amount ) external nonReentrant returns (uint256 orderId ) {
9893 // Validation
99- if (price == 0 ) revert InvalidPrice ();
100- if (amount == 0 ) revert InvalidAmount ();
94+ if (price == 0 ) revert LimitOrderBook_InvalidPrice ();
95+ if (amount == 0 ) revert LimitOrderBook_InvalidAmount ();
10196
10297 // Create order
10398 orderId = s_nextOrderId;
@@ -113,14 +108,14 @@ contract LimitOrderBook {
113108 * @notice Cancel an existing order
114109 * @param orderId The ID of the order to cancel
115110 */
116- function cancelOrder (uint256 orderId ) external validOrder (orderId) {
111+ function cancelOrder (uint256 orderId ) external nonReentrant validOrder (orderId) {
117112 Order storage order = s_orders[orderId];
118113
119114 // Verify ownership
120- if (order.user != msg .sender ) revert NotOrderOwner ();
115+ if (order.user != msg .sender ) revert LimitOrderBook_NotOrderOwner ();
121116
122117 // Verify not already executed
123- if (order.executed) revert OrderAlreadyExecuted ();
118+ if (order.executed) revert LimitOrderBook_OrderAlreadyExecuted ();
124119
125120 // Delete the order
126121 delete s_orders[orderId];
@@ -133,16 +128,16 @@ contract LimitOrderBook {
133128 * @param orderId The ID of the order to execute
134129 * @dev This function can be called by anyone initially, but access can be restricted
135130 */
136- function markExecuted (uint256 orderId ) external validOrder (orderId) {
131+ function markExecuted (uint256 orderId ) external nonReentrant validOrder (orderId) {
137132 Order storage order = s_orders[orderId];
138133
139134 // Verify not already executed
140- if (order.executed) revert OrderAlreadyExecuted ();
135+ if (order.executed) revert LimitOrderBook_OrderAlreadyExecuted ();
141136
142137 // If executor authorization is enabled, check permission
143138 // address(0) flag indicates if permissionless execution is allowed
144139 if (! s_authorizedExecutors[address (0 )] && ! s_authorizedExecutors[msg .sender ]) {
145- revert UnauthorizedExecutor ();
140+ revert LimitOrderBook_UnauthorizedExecutor ();
146141 }
147142
148143 // Mark as executed
@@ -169,14 +164,6 @@ contract LimitOrderBook {
169164 emit ExecutorRevoked (executor);
170165 }
171166
172- /**
173- * @notice Transfer ownership of the contract
174- * @param newOwner The new owner address
175- */
176- function transferOwnership (address newOwner ) external onlyOwner {
177- s_owner = newOwner;
178- }
179-
180167 /**
181168 * @notice Enable or disable executor authorization requirement
182169 * @param requireAuth True to require authorization, false for permissionless execution
0 commit comments