Contract Name:
UniV3LiquidityLocker
Contract Source Code:
File 1 of 1 : UniV3LiquidityLocker
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC721 {
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function ownerOf(uint256 tokenId) external view returns (address);
function approve(address to, uint256 tokenId) external;
}
abstract contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
_transferOwnership(initialOwner);
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == msg.sender, "Ownable: caller is not the owner");
_;
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
interface INonfungiblePositionManager is IERC721 {
}
contract UniV3LiquidityLocker is Ownable {
INonfungiblePositionManager public immutable uniswapV3NFT;
struct LockedPosition {
address owner;
uint256 unlockTime;
}
mapping(uint256 => LockedPosition) public lockedPositions;
event LiquidityLocked(address indexed user, uint256 indexed tokenId, uint256 unlockTime);
event LiquidityUnlocked(address indexed user, uint256 indexed tokenId);
constructor(address _uniswapV3NFT) Ownable(msg.sender) {
uniswapV3NFT = INonfungiblePositionManager(_uniswapV3NFT);
}
function lockLiquidity(uint256 tokenId, uint256 lockDuration) external {
require(lockDuration >= 1 days, "Minimum lock duration is 1 day");
require(uniswapV3NFT.ownerOf(tokenId) == msg.sender, "You must own the LP NFT");
uniswapV3NFT.safeTransferFrom(msg.sender, address(this), tokenId);
lockedPositions[tokenId] = LockedPosition({
owner: msg.sender,
unlockTime: block.timestamp + lockDuration
});
emit LiquidityLocked(msg.sender, tokenId, block.timestamp + lockDuration);
}
function unlockLiquidity(uint256 tokenId) external {
LockedPosition storage position = lockedPositions[tokenId];
require(position.owner == msg.sender, "Not the owner of this NFT");
require(block.timestamp >= position.unlockTime, "Liquidity is still locked");
uniswapV3NFT.safeTransferFrom(address(this), msg.sender, tokenId);
delete lockedPositions[tokenId];
emit LiquidityUnlocked(msg.sender, tokenId);
}
}