33pragma solidity ^ 0.8.20 ;
44
55import {Signature, Route, MAX_PAYLOAD_SIZE} from "../Primitives.sol " ;
6- import {EnumerableSet, Pointer} from "../utils/EnumerableSet.sol " ;
7- import {BranchlessMath} from "../utils/BranchlessMath.sol " ;
8- import {StoragePtr} from "../utils/Pointer.sol " ;
6+ import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol " ;
97import {GasUtils} from "../GasUtils.sol " ;
108
119/**
1210 * @dev EIP-7201 Route's Storage
1311 */
1412library RouteStore {
15- using Pointer for StoragePtr;
16- using Pointer for uint256 ;
17- using EnumerableSet for EnumerableSet.Map;
18- using BranchlessMath for uint256 ;
13+ using EnumerableMap for EnumerableMap.UintToUintMap;
1914
2015 /**
2116 * @dev Namespace of the routes storage `analog.one.gateway.routes`.
@@ -69,32 +64,26 @@ library RouteStore {
6964 * @custom:storage-location erc7201:analog.one.gateway.routes
7065 */
7166 struct MainStorage {
72- EnumerableSet.Map routes;
67+ EnumerableMap.UintToUintMap routeIds;
68+ mapping (uint16 => NetworkInfo) routes;
7369 }
7470
7571 error RouteNotExists (uint16 id );
7672 error IndexOutOfBounds (uint256 index );
73+ error ZeroGatewayForNewRoute ();
74+ error InvalidRouteParameters ();
7775
7876 function getMainStorage () internal pure returns (MainStorage storage $) {
7977 assembly {
8078 $.slot := _EIP7201_NAMESPACE
8179 }
8280 }
8381
84- /**
85- * @dev Converts a `StoragePtr` into an `NetworkInfo`.
86- */
87- function pointerToRoute (StoragePtr ptr ) private pure returns (NetworkInfo storage route ) {
88- assembly {
89- route.slot := ptr
90- }
91- }
92-
9382 /**
9483 * @dev Returns true if the value is in the set. O(1).
9584 */
9685 function has (MainStorage storage store , uint16 networkId ) internal view returns (bool ) {
97- return store.routes. has ( bytes32 ( uint256 (networkId) ));
86+ return store.routeIds. contains ( uint256 (networkId));
9887 }
9988
10089 /**
@@ -104,8 +93,11 @@ library RouteStore {
10493 * already present.
10594 */
10695 function getOrAdd (MainStorage storage store , uint16 networkId ) private returns (bool , NetworkInfo storage ) {
107- (bool success , StoragePtr ptr ) = store.routes.tryAdd (bytes32 (uint256 (networkId)));
108- return (success, pointerToRoute (ptr));
96+ bool exists = store.routeIds.contains (uint256 (networkId));
97+ if (! exists) {
98+ store.routeIds.set (uint256 (networkId), 1 );
99+ }
100+ return (! exists, store.routes[networkId]);
109101 }
110102
111103 /**
@@ -115,18 +107,18 @@ library RouteStore {
115107 * present.
116108 */
117109 function remove (MainStorage storage store , uint16 id ) internal returns (bool ) {
118- StoragePtr ptr = store.routes .remove (bytes32 ( uint256 (id) ));
119- if (ptr. isNull () ) {
120- return false ;
110+ bool existed = store.routeIds .remove (uint256 (id));
111+ if (existed ) {
112+ delete store.routes[id] ;
121113 }
122- return true ;
114+ return existed ;
123115 }
124116
125117 /**
126118 * @dev Returns the number of values on the set. O(1).
127119 */
128120 function length (MainStorage storage store ) internal view returns (uint256 ) {
129- return store.routes .length ();
121+ return store.routeIds .length ();
130122 }
131123
132124 /**
@@ -140,11 +132,12 @@ library RouteStore {
140132 * - `index` must be strictly less than {length}.
141133 */
142134 function at (MainStorage storage store , uint256 index ) internal view returns (uint16 , NetworkInfo storage ) {
143- (bytes32 key , StoragePtr value ) = store.routes.at (index);
144- if (value.isNull ()) {
135+ if (index >= store.routeIds.length ()) {
145136 revert IndexOutOfBounds (index);
146137 }
147- return (uint16 (uint256 (key)), pointerToRoute (value));
138+ (uint256 key ,) = store.routeIds.at (index);
139+ uint16 networkId = uint16 (key);
140+ return (networkId, store.routes[networkId]);
148141 }
149142
150143 /**
@@ -154,32 +147,27 @@ library RouteStore {
154147 * - `NetworkInfo` must be in the map.
155148 */
156149 function get (MainStorage storage store , uint16 id ) internal view returns (NetworkInfo storage ) {
157- StoragePtr ptr = store.routes.get (bytes32 (uint256 (id)));
158- if (ptr.isNull ()) {
150+ if (! store.routeIds.contains (uint256 (id))) {
159151 revert RouteNotExists (id);
160152 }
161- return pointerToRoute (ptr);
162- }
163-
164- /**
165- * @dev Returns the value associated with `NetworkInfo`. O(1).
166- */
167- function tryGet (MainStorage storage store , uint16 id ) internal view returns (bool , NetworkInfo storage ) {
168- (bool exists , StoragePtr ptr ) = store.routes.tryGet (bytes32 (uint256 (id)));
169- return (exists, pointerToRoute (ptr));
153+ return store.routes[id];
170154 }
171155
172156 function createOrUpdateRoute (MainStorage storage store , Route calldata route ) internal {
173- // Update network info
174157 (bool created , NetworkInfo storage stored ) = getOrAdd (store, route.networkId);
175- require ((created && route.gateway != bytes32 (0 )) || ! created, "domain separator cannot be zero " );
158+ if (created) {
159+ if (route.gateway == bytes32 (0 )) revert ZeroGatewayForNewRoute ();
160+ stored.gateway = route.gateway;
161+ }
176162
177- // Update gas limit if it's not zero
178- if (route.gasLimit > 0 ) {
179- stored.gasLimit = route.gasLimit;
163+ if (route.relativeGasPriceDenominator == 0 && route.relativeGasPriceNumerator > 0 ) {
164+ revert InvalidRouteParameters ();
180165 }
181166
182- // Update relative gas price and base fee if any of them are greater than zero
167+ // Update gas limit if it's not zero
168+ if (route.gasLimit > 0 ) stored.gasLimit = route.gasLimit;
169+
170+ // Update relative gas price and base fee if denominator is greater than zero
183171 if (route.relativeGasPriceDenominator > 0 ) {
184172 stored.relativeGasPriceNumerator = route.relativeGasPriceNumerator;
185173 stored.relativeGasPriceDenominator = route.relativeGasPriceDenominator;
@@ -208,12 +196,14 @@ library RouteStore {
208196 * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
209197 */
210198 function listRoutes (MainStorage storage store ) internal view returns (Route[] memory ) {
211- bytes32 [] memory idx = store.routes.keys;
212- Route[] memory routes = new Route [](idx.length );
213- for (uint256 i = 0 ; i < idx.length ; i++ ) {
214- uint16 networkId = uint16 (uint256 (idx[i]));
215- (bool success , NetworkInfo storage route ) = tryGet (store, networkId);
216- require (success, "route not found " );
199+ uint256 len = store.routeIds.length ();
200+ Route[] memory routes = new Route [](len);
201+
202+ for (uint256 i = 0 ; i < len; i++ ) {
203+ (uint256 key ,) = store.routeIds.at (i);
204+ uint16 networkId = uint16 (key);
205+ NetworkInfo storage route = store.routes[networkId];
206+
217207 routes[i] = Route ({
218208 networkId: networkId,
219209 gasLimit: route.gasLimit,
0 commit comments