Skip to content

Commit

Permalink
add lock check
Browse files Browse the repository at this point in the history
  • Loading branch information
snreynolds committed Oct 18, 2024
1 parent 0c162a0 commit 3daf662
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_subscribe.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
84348
88168
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_unsubscribe.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
59238
63058
9 changes: 8 additions & 1 deletion src/PositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ contract PositionManager is
_;
}

/// @notice Enforces that the PoolManager is locked.
/// @dev Reverts if the caller tries to transfer, subscribe, or unsubscribe the position while the PoolManager is unlocked.
modifier onlyIfPoolManagerLocked() override {
if (poolManager.isUnlocked()) revert PoolManagerMustBeLocked();
_;
}

function tokenURI(uint256 tokenId) public view override returns (string memory) {
return IPositionDescriptor(tokenDescriptor).tokenURI(this, tokenId);
}
Expand Down Expand Up @@ -431,7 +438,7 @@ contract PositionManager is
}

/// @dev overrides solmate transferFrom in case a notification to subscribers is needed
function transferFrom(address from, address to, uint256 id) public virtual override {
function transferFrom(address from, address to, uint256 id) public virtual override onlyIfPoolManagerLocked {
super.transferFrom(from, to, id);
if (positionInfo[id].hasSubscriber()) _notifyTransfer(id, from, to);
}
Expand Down
12 changes: 11 additions & 1 deletion src/base/Notifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ abstract contract Notifier is INotifier {
/// @param tokenId the tokenId of the position
modifier onlyIfApproved(address caller, uint256 tokenId) virtual;

/// @notice Enforces that the PoolManager is locked.
/// @dev Reverts if the caller tries to transfer, subscribe, or unsubscribe the position while the PoolManager is unlocked.
modifier onlyIfPoolManagerLocked() virtual;

function _setUnsubscribed(uint256 tokenId) internal virtual;

function _setSubscribed(uint256 tokenId) internal virtual;
Expand All @@ -37,6 +41,7 @@ abstract contract Notifier is INotifier {
function subscribe(uint256 tokenId, address newSubscriber, bytes calldata data)
external
payable
onlyIfPoolManagerLocked
onlyIfApproved(msg.sender, tokenId)
{
ISubscriber _subscriber = subscriber[tokenId];
Expand All @@ -56,7 +61,12 @@ abstract contract Notifier is INotifier {
}

/// @inheritdoc INotifier
function unsubscribe(uint256 tokenId) external payable onlyIfApproved(msg.sender, tokenId) {
function unsubscribe(uint256 tokenId)
external
payable
onlyIfPoolManagerLocked
onlyIfApproved(msg.sender, tokenId)
{
_unsubscribe(tokenId);
}

Expand Down
3 changes: 3 additions & 0 deletions src/interfaces/IPositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ interface IPositionManager is INotifier, IImmutableState {
error NotApproved(address caller);
/// @notice Thrown when the block.timestamp exceeds the user-provided deadline
error DeadlinePassed(uint256 deadline);
/// @notice Thrown when calling transfer, subscribe, or unsubscribe when the PoolManager is unlocked.
/// @dev This is to prevent hooks from being able to trigger notifications at the same time the position is being modified.
error PoolManagerMustBeLocked();

/// @notice Unlocks Uniswap v4 PoolManager and batches actions for modifying liquidity
/// @dev This is the standard entrypoint for the PositionManager
Expand Down

0 comments on commit 3daf662

Please sign in to comment.