Skip to main content

Documentation

Context

Structured reference
TOC available

Subscriber

Context​

This page describes subscriber contracts in the current FewToken + Uniswap v4 integration environment. It should be read as integration guidance, not as documentation for a separate native v4 AMM.

For developers looking to support custom external position tracking, Subscriber contracts can be used to receive notifications about position modifications or transfers.

Guide​

1. Implement the ISubscriber interface​

Can also refer to MockSubscriber for an actual implementation example.

import {ISubscriber} from "v4-periphery/src/interfaces/ISubscriber.sol";

contract MySubscriber is ISubscriber {
uint256 public notifySubscribeCount;
uint256 public notifyUnsubscribeCount;
uint256 public notifyModifyLiquidityCount;
uint256 public notifyBurnCount;
// other implementations...

function notifySubscribe(uint256, bytes memory) external onlyByPosm {
notifySubscribeCount++;
}

function notifyUnsubscribe(uint256) external onlyByPosm {
notifyUnsubscribeCount++;
}

function notifyModifyLiquidity(uint256, int256, BalanceDelta) external onlyByPosm {
notifyModifyLiquidityCount++;
}

function notifyBurn(uint256, address, PositionInfo, uint256, BalanceDelta)
external
onlyByPosm
{
notifyBurnCount++;
}
}

2. A caveat on unsubscribe()​

To prevent gas griefing during unsubscription, this v4 integration stack uses a fixed unsubscribeGasLimit when calling a subscriber’s notifyUnsubscribe() function.

Without this limit, malicious subscribers could prevent liquidity providers from unsubscribing. If notifyUnsubscribe() were to consume too much gas, it would cause the unsubscription transaction to revert, thus leading to a denial-of-service

With the gas limit in place, if the subscriber’s notification fails, the unsubscription will still succeed and only the notification to the subscriber is skipped.

From _unsubscribe() on Notifier:

if (address(_subscriber).code.length > 0) {
// require that the remaining gas is sufficient to notify the subscriber
// otherwise, users can select a gas limit where .notifyUnsubscribe hits OutOfGas yet the
// transaction/unsubscription can still succee
if (gasleft() < unsubscribeGasLimit) GasLimitTooLow.selector.revertWith();
try _subscriber.notifyUnsubscribe{gas: unsubscribeGasLimit}(tokenId) {} catch {}
}

3. Opt-in to a subscriber contract​

To opt-in to a subscriber contract, call subscribe() on PositionManager.

import {IPositionManager} from "v4-periphery/src/interfaces/IPositionManager.sol";

IPositionManager posm = IPositionManager(<address>);
ISubscriber mySubscriber = ISubscriber(<address>);

bytes memory optionalData = ...;
posm.subscribe(tokenId, mySubscriber, optionalData);