Collecting Fees
This section explains how to collect fees from a liquidity position on the Storyhunt V3 protocol.
Introduction
This section explains how to collect fees from a liquidity position on the Storyhunt V3 protocol. Liquidity positions accrue fees from trades made within the positionβs price range. Using the NonfungiblePositionManager
contract, we can collect these fees. The inputs include the tokens pooled, pool fee, and maximum accrued fees to collect for each token.
Setting Up Fee Collection
To begin, fetch the position details from the NonfungiblePositionManager
contract to determine the fees owed:
import { ethers } from 'ethers';
import JSBI from 'jsbi';
const nfpmContract = new ethers.Contract(
NONFUNGIBLE_POSITION_MANAGER_ADDRESS,
INONFUNGIBLE_POSITION_MANAGER.abi,
provider
);
const position = await nfpmContract.positions(positionId);
Next, construct a CollectOptions
object to specify the fee collection details:
import { CurrencyAmount } from '@storyhunt/sdk-core';
const collectOptions: CollectOptions = {
tokenId: positionId,
expectedCurrencyOwed0: CurrencyAmount.fromRawAmount(
CurrentConfig.tokens.token0,
JSBI.BigInt(position.tokensOwed0)
),
expectedCurrencyOwed1: CurrencyAmount.fromRawAmount(
CurrentConfig.tokens.token1,
JSBI.BigInt(position.tokensOwed1)
),
recipient: address,
};
Here:
tokenId
: The ID of the position.expectedCurrencyOwed0
andexpectedCurrencyOwed1
: The maximum amounts of each token expected to collect.recipient
: The wallet address to receive the collected fees.
You can fetch the tokensOwed0
and tokensOwed1
values using the positions
function of the NonfungiblePositionManager
contract:
const positionInfos = callResponses.map((position) => {
return {
tickLower: position.tickLower,
tickUpper: position.tickUpper,
liquidity: JSBI.BigInt(position.liquidity),
feeGrowthInside0LastX128: JSBI.BigInt(position.feeGrowthInside0LastX128),
feeGrowthInside1LastX128: JSBI.BigInt(position.feeGrowthInside1LastX128),
tokensOwed0: JSBI.BigInt(position.tokensOwed0),
tokensOwed1: JSBI.BigInt(position.tokensOwed1),
};
});
Submitting the Fee Collection Transaction
Use the NonfungiblePositionManager
to retrieve the call parameters required for the fee collection transaction:
const { calldata, value } =
NonfungiblePositionManager.collectCallParameters(collectOptions);
Construct and execute the transaction:
const transaction = {
data: calldata,
to: NONFUNGIBLE_POSITION_MANAGER_CONTRACT_ADDRESS,
value: value,
from: address,
maxFeePerGas: MAX_FEE_PER_GAS,
maxPriorityFeePerGas: MAX_PRIORITY_FEE_PER_GAS,
};
const txRes = await wallet.sendTransaction(transaction);
After the transaction is confirmed, the balances of the pooled tokens (e.g., USDC and WIP) will increase if fees have been accrued.