@@ -32,7 +32,7 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
3232 mapping (address user = > bool allowed ) public allowList;
3333
3434 /// @notice Whether whitelist is enabled
35- bool public allowListEnabled = true ;
35+ bool public allowListEnabled;
3636
3737 /// @notice Set of supported token IDs
3838 EnumerableSetUpgradeable.UintSet private supportedTokenSet;
@@ -45,7 +45,13 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
4545 * @notice Check if caller is in Allow List
4646 */
4747 modifier onlyAllowed () {
48- if (allowListEnabled && ! allowList[msg .sender ] && msg .sender != owner ()) {
48+ bool isOwner = msg .sender == owner ();
49+ bool isAllowedByList = allowListEnabled && allowList[msg .sender ];
50+
51+ // Owner always has access
52+ // When allowList is enabled, allowList users can access
53+ // When allowList is disabled, only owner can access
54+ if (! isOwner && ! isAllowedByList) {
4955 revert CallerNotAllowed ();
5056 }
5157 _;
@@ -215,8 +221,8 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
215221
216222 // Forbid zero ID and enforce uniqueness for both ID and address
217223 if (_tokenID == 0 ) revert InvalidTokenID ();
218- if (tokenRegistry[_tokenID].tokenAddress != address (0 )) revert TokenAlreadyRegistered ();
219- if (tokenRegistration[_tokenAddress] != 0 ) revert TokenAlreadyRegistered ();
224+ if (tokenRegistry[_tokenID].tokenAddress != address (0 )) revert TokenIDAlreadyRegistered ();
225+ if (tokenRegistration[_tokenAddress] != 0 ) revert TokenAddressAlreadyRegistered ();
220226
221227 // Validate scale is non-zero
222228 if (_scale == 0 ) revert InvalidScale ();
@@ -266,9 +272,12 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
266272 // Check new information
267273 if (_tokenAddress == address (0 )) revert InvalidTokenAddress ();
268274
275+ // Check new scale
276+ if (_scale == 0 ) revert InvalidScale ();
277+
269278 // Prevent address being shared across different tokenIDs
270279 uint16 existing = tokenRegistration[_tokenAddress];
271- if (existing != 0 && existing != _tokenID) revert TokenAlreadyRegistered ();
280+ if (existing != 0 && existing != _tokenID) revert TokenAddressAlreadyRegistered ();
272281
273282 // Get decimals from contract
274283 uint8 decimals = 18 ; // Default value
@@ -294,6 +303,10 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
294303 tokenRegistration[_tokenAddress] = _tokenID;
295304 }
296305
306+ // Reset priceRatio to 0 to ensure consistency
307+ // priceRatio depends on scale and decimals, so it must be recalculated after tokenInfo changes
308+ priceRatio[_tokenID] = 0 ;
309+
297310 // Note: tokenID should already be in supportedTokenSet from registration
298311 // No need to add again as EnumerableSet.add() is idempotent but wastes gas
299312
@@ -403,10 +416,7 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
403416 * @notice Calculate the corresponding token amount for a given ETH amount
404417 * @dev Calculation formula:
405418 * - ratio = tokenScale * (tokenPrice / ethPrice) * 10^(ethDecimals - tokenDecimals)
406- * - tokenAmount = (ethAmount * 10^tokenDecimals) / ratio
407- * - Substituting ratio: tokenAmount = (ethAmount * 10^tokenDecimals) / (tokenScale * (tokenPrice / ethPrice) * 10^(18 - tokenDecimals))
408- * - Simplified: tokenAmount = (ethAmount * 10^tokenDecimals * 10^tokenDecimals) / (tokenScale * tokenPrice * 10^18 / ethPrice)
409- * - Final: tokenAmount = (ethAmount * ethPrice * 10^tokenDecimals) / (tokenScale * tokenPrice * 10^18)
419+ * - tokenAmount = ⌈(ethAmount × tokenScale) / tokenRate⌉
410420 * - Note: Uses ceiling division to ensure users receive fair token amounts
411421 * @param _tokenID Token ID of the ERC20 token
412422 * @param _ethAmount ETH amount (unit: wei)
@@ -432,24 +442,27 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
432442 uint256 numerator = _ethAmount * uint256 (info.scale);
433443 tokenAmount = (numerator + ratio - 1 ) / ratio;
434444
435- if (tokenAmount == 0 ) revert InvalidPrice ();
445+ if (tokenAmount == 0 ) revert ZeroTokenAmount ();
436446
437447 return tokenAmount;
438448 }
439449
440450 /**
441451 * @notice Get token information
442452 * @param _tokenID Token ID
443- * @return TokenInfo structure with actual balanceSlot (automatically -1 from stored value)
453+ * @return info TokenInfo structure with actual balanceSlot (automatically -1 from stored value)
454+ * @return hasBalanceSlot Whether balanceSlot was stored with +1 offset (true = slot was adjusted)
444455 */
445- function getTokenInfo (uint16 _tokenID ) external view returns (TokenInfo memory ) {
456+ function getTokenInfo (uint16 _tokenID ) external view returns (TokenInfo memory info , bool hasBalanceSlot ) {
446457 if (tokenRegistry[_tokenID].tokenAddress == address (0 )) revert TokenNotFound ();
447458
448- TokenInfo memory info = tokenRegistry[_tokenID];
459+ info = tokenRegistry[_tokenID];
460+ // Check if balanceSlot was stored (non-zero means it was stored with +1 offset)
461+ hasBalanceSlot = info.balanceSlot != bytes32 (0 );
449462 // Convert stored balanceSlot to actual value
450463 info.balanceSlot = _toActualBalanceSlot (info.balanceSlot);
451464
452- return info;
465+ return ( info, hasBalanceSlot) ;
453466 }
454467
455468 /**
@@ -481,6 +494,10 @@ contract L2TokenRegistry is IL2TokenRegistry, OwnableUpgradeable, ReentrancyGuar
481494 if (_newScale == 0 ) revert InvalidScale ();
482495 tokenRegistry[_tokenID].scale = _newScale;
483496
497+ // Reset priceRatio to 0 to ensure consistency
498+ // priceRatio depends on scale, so it must be recalculated after scale changes
499+ priceRatio[_tokenID] = 0 ;
500+
484501 emit TokenScaleUpdated (_tokenID, _newScale);
485502 }
486503
0 commit comments