Locking v3 Positions

Locking v3 Position and claiming fee functionality

There is NO WARRANTY provided with this code reference. The concept here is to transfer a Koi Finance v3 position NFT into this contract which permanently locks liquidity, yet allows the deployed owner to collect trading fees on this position in perpetuity until the owner is relinquished. When calling collect, the recipient param should be the account that is receiving the fees.

pragma solidity =0.7.6;
pragma abicoder v2;

/// @title V3 Locker & Fee Claimer
contract V3PositionLocker {
    address public owner;
    address public immutable nonfungiblePositionManager;

    constructor(address _nonfungiblePositionManager) {
        owner = msg.sender;
        nonfungiblePositionManager = _nonfungiblePositionManager;
    }

    function setOwner(address _owner) external {
        require(msg.sender == owner);
        owner = _owner;
    }

    function collect(INonfungiblePositionManager.CollectParams calldata params) external {
        require(msg.sender == owner, "Not owner");

        (uint256 amount0, uint256 amount1) = INonfungiblePositionManager(nonfungiblePositionManager).collect(params);
    }

    function saveToken(address _token, address _destination, uint _amount) external {
        require(msg.sender == owner, "Not owner");
        IERC20(_token).transfer(_destination, _amount);
    }
}

interface INonfungiblePositionManager {
    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    /// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient
    /// @param params tokenId The ID of the NFT for which tokens are being collected,
    /// recipient The account that should receive the tokens,
    /// amount0Max The maximum amount of token0 to collect,
    /// amount1Max The maximum amount of token1 to collect
    /// @return amount0 The amount of fees collected in token0
    /// @return amount1 The amount of fees collected in token1
    function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);
}

interface IERC20 {
    function transfer(address recipient, uint256 amount) external returns (bool);
}

Last updated

2023 mute.io