IntegrationsQuick StartBurn And Delegate Fees

Functions

The DelegatedPositionVault allows liquidity providers to permanently lock their Hyperswap V2/V3 positions and delegate fee collection rights via NFTs. This guide explains how to integrate with the…

Overview

The DelegatedPositionVault allows liquidity providers to permanently lock their Hyperswap V2/V3 positions and delegate fee collection rights via NFTs. This guide explains how to integrate with the vault contract.

Contract Address

HyperEVM: 0x744C89B7b7F8Cb1E955B1Dcd842A5378d75c96Dc

Key Concepts

  • Permanent Lock: Once positions are delegated, the underlying liquidity is locked forever
  • Fee Collection NFTs: Users receive ERC721 NFTs that grant the right to claim accumulated fees
  • No Principal Withdrawal: Only fees can be claimed - the original liquidity remains permanently staked

Integration Steps

1. Approve the Vault

Before delegating positions, users must approve the vault to transfer their assets:

For V3 Positions:

// Approve the vault to transfer your V3 NFT
INonfungiblePositionManager(NFPM).approve(VAULT_ADDRESS, tokenId);

For V2 Positions:

// Approve the vault to transfer your LP tokens
IERC20(pairAddress).approve(VAULT_ADDRESS, amount);

2. Delegate Positions

Delegating V3 Positions:

// Burn V3 position and mint fee collection NFT
uint256 delegatedTokenId = vault.burnV3(
    tokenId,        // V3 position NFT token ID
    feeCollector    // Address to receive the fee collection NFT
);

Delegating V2 Positions:

// Burn V2 LP tokens and mint fee collection NFT
uint256 delegatedTokenId = vault.burnV2(
    pair,           // IHyperswapV2Pair contract
    amount,         // Amount of LP tokens to delegate
    feeCollector    // Address to receive the fee collection NFT
);

3. Claim Fees

Only the owner of the delegated position NFT can claim fees:

// Claim fees from a single position
vault.claim(delegatedTokenId);

// Claim fees from multiple positions at once
uint256[] memory tokenIds = [tokenId1, tokenId2, tokenId3];
vault.bulkClaim(tokenIds);

Integration Examples

Example 1: Simple Fee Delegation

contract SimpleDelegation {
    address public constant VAULT = 0xfB04F2679962484ef7bCeC75598E169888a67fBb;

    // Delegate V3 position to yourself
    function delegateV3Position(uint256 v3TokenId) external {
        // Approve vault
        INonfungiblePositionManager(NFPM).approve(VAULT, v3TokenId);

        // Delegate position, receiving NFT to same address
        uint256 delegatedId = IDelegatedPositionVault(VAULT).burnV3(
            v3TokenId,
            msg.sender
        );

        emit V3PositionDelegated(v3TokenId, delegatedId);
    }

    // Delegate V2 LP tokens to yourself
    function delegateV2Position(address pairAddress, uint256 lpAmount) external {
        // Approve vault to transfer LP tokens
        IERC20(pairAddress).approve(VAULT, lpAmount);

        // Delegate LP tokens, receiving NFT to same address
        uint256 delegatedId = IDelegatedPositionVault(VAULT).burnV2(
            pairAddress,
            lpAmount,
            msg.sender
        );

        emit V2PositionDelegated(pairAddress, lpAmount, delegatedId);
    }

    // Claim fees from your delegated position
    function claimMyFees(uint256 delegatedId) external {
        // Only the NFT owner can claim
        IDelegatedPositionVault(VAULT).claim(delegatedId);
    }
}

Events to Monitor

// Emitted when a position is delegated
event Burn(
    uint256 indexed tokenId,
    uint256 indexed positionIdOrAmountLpTokens,
    PositionType positionType
);

// Emitted when fees are claimed
event Claim(
    uint256 indexed tokenId,
    uint256 indexed positionIdOrAmountLpTokens,
    PositionType positionType,
    uint256 amount0,
    uint256 amount1
);

Important Considerations

  1. Irreversible Action: Delegating positions is permanent - ensure users understand this
  2. Fee Accumulation: Fees continue to accumulate even if not claimed regularly
  3. NFT Ownership: Only the NFT holder can claim fees - losing the NFT means losing fee rights
  4. Gas Optimization: Use bulkClaim for multiple positions to save gas
  5. Emergency Pause: The contract can be paused by the owner in emergencies

Complete Contract Interface

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

interface IDelegatedPositionVault {
    // Enums
    enum PositionType { V3, V2 }

    // Events
    event Burn(
        uint256 indexed tokenId,
        uint256 indexed positionIdOrAmountLpTokens,
        PositionType positionType
    );

    event Claim(
        uint256 indexed tokenId,
        uint256 indexed positionIdOrAmountLpTokens,
        PositionType positionType,
        uint256 amount0,
        uint256 amount1
    );

    // Core Functions
    function burnV3(uint256 tokenId, address feeCollector)
        external returns (uint256 positionId);

    function burnV2(address pair, uint256 amount, address feeCollector)
        external returns (uint256 positionId);

    function claim(uint256 tokenId) external;

    function bulkClaim(uint256[] calldata tokenIds) external;

    // Admin Functions
    function pause() external;
    function unpause() external;

    // View Functions
    function delegatedPositions(uint256 tokenId) external view returns (
        PositionType positionType,
        uint256 tokenIdOrAmountLpTokens,
        address pair,
        address token0,
        address token1,
        uint24 fee,
        uint256 sqrtK,
        bool exists
    );

    function tokenIdCounter() external view returns (uint256);
    function paused() external view returns (bool);
    function owner() external view returns (address);

    // ERC721 Functions
    function ownerOf(uint256 tokenId) external view returns (address);
    function balanceOf(address owner) external view returns (uint256);
    function approve(address to, uint256 tokenId) external;
    function getApproved(uint256 tokenId) external view returns (address);
    function setApprovalForAll(address operator, bool approved) external;
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    function transferFrom(address from, address to, uint256 tokenId) external;
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

Security Best Practices

  1. Always verify the vault contract address
  2. Ensure proper approval amounts (use exact amounts, not max)
  3. Implement access controls if building a fee collection system
  4. Monitor the paused() state before operations
  5. Handle reverts gracefully in your integration

On this page