chore: replace transient storage Locker with sstore/sload variant#106
chore: replace transient storage Locker with sstore/sload variant#106Khrafts wants to merge 1 commit into
Conversation
Add local Locker library using sstore/sload instead of tstore/tload for compatibility with pre-Cancun chains. Use Uniswap version when deploying to chains that support transient storage.
Changes to gas cost
🧾 Summary (20% most significant diffs)
Full diff report 👇
|
LCOV of commit
|
There was a problem hiding this comment.
Pull request overview
This PR replaces the dependency on Uniswap’s transient-storage Locker with a locally vendored Locker implementation that uses sstore/sload, improving compatibility with pre-Cancun chains.
Changes:
- Added a local
Lockerlibrary that stores/loads the lock holder from a fixed storage slot viasstore/sload. - Updated
ReentrancyLockto import the new localLockerinstead of the Uniswap periphery version.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/swap/libs/Locker.sol |
Introduces a local Locker library using persistent storage for lock state. |
src/swap/ReentrancyLock.sol |
Switches the Locker import to the new local library. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| pragma solidity 0.8.26; | ||
|
|
||
| import { Locker } from "../../lib/uniswap-v4-periphery/src/libraries/Locker.sol"; | ||
| import { Locker } from "./libs/Locker.sol"; |
There was a problem hiding this comment.
Switching the Locker import to the local sstore/sload implementation means the lock is no longer based on transient storage. The contract still documents itself as a "transient reentrancy lock"; please update the NatSpec/commentary in this file to reflect the persistent-storage implementation to avoid misleading integrators/auditors.
| bytes32 constant LOCKED_BY_SLOT = 0x0aedd6bde10e3aa2adec092b02a3e3e805795516cda41f27aa145b8f300af87a; | ||
|
|
||
| function set(address locker) internal { | ||
| assembly { | ||
| sstore(LOCKED_BY_SLOT, locker) | ||
| } | ||
| } | ||
|
|
||
| function get() internal view returns (address locker) { | ||
| assembly { | ||
| locker := sload(LOCKED_BY_SLOT) | ||
| } |
There was a problem hiding this comment.
This Locker library writes to a hard-coded storage slot via inline assembly, which bypasses the ERC-7201 namespaced storage-location pattern used throughout the codebase (e.g., ReentrancyLockStorageLayout and FreezableStorageLayout). Consider moving the lock state into the existing ReentrancyLockStorageStruct (or introducing an ERC-7201 storage location for Locker) to reduce storage-collision risk and keep upgradeable storage access consistent.
| bytes32 constant LOCKED_BY_SLOT = 0x0aedd6bde10e3aa2adec092b02a3e3e805795516cda41f27aa145b8f300af87a; | |
| function set(address locker) internal { | |
| assembly { | |
| sstore(LOCKED_BY_SLOT, locker) | |
| } | |
| } | |
| function get() internal view returns (address locker) { | |
| assembly { | |
| locker := sload(LOCKED_BY_SLOT) | |
| } | |
| bytes32 internal constant LOCKER_STORAGE_LOCATION = | |
| 0x0aedd6bde10e3aa2adec092b02a3e3e805795516cda41f27aa145b8f300af87a; | |
| struct LockerStorageLayout { | |
| address lockedBy; | |
| } | |
| function layout() private pure returns (LockerStorageLayout storage $) { | |
| bytes32 slot = LOCKER_STORAGE_LOCATION; | |
| assembly { | |
| $.slot := slot | |
| } | |
| } | |
| function set(address locker) internal { | |
| layout().lockedBy = locker; | |
| } | |
| function get() internal view returns (address locker) { | |
| locker = layout().lockedBy; |
|
Do we also need to update foundry.toml file here with evm_version = "london" |
We could do that, however the Uniswap v4 periphery lib uses tstore/tload (Cancun opcodes) in its Locker.sol. Setting evm_version = "london" causes compilation to fail because the compiler rejects those opcodes — and Foundry's skip config doesn't prevent lib files from being compiled. |
|
This change is already present in this branch: #49 |
Add local Locker library using sstore/sload instead of tstore/tload for compatibility with pre-Cancun chains. Use Uniswap version when deploying to chains that support transient storage.