Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Neverland-Money/neverland-v3-staker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Neverland - Uniswap V3 Staker

Built on Uniswap V3 Staker
Expanded by Revert Finance

Special thanks to Uniswap and Revert Finance for creating the foundational liquidity incentives infrastructure.

This repository contains the deployment configuration and scripts for Neverland's Uniswap V3 Staker, a liquidity incentives protocol on Monad. The codebase extends Uniswap's canonical staking contract and Revert Finance's enhancements with custom deployment tooling, network support, and operational infrastructure specific to Neverland's requirements.

Table of Contents

Key Differences from Uniswap

  1. Monad Native: Built for Monad's parallel execution environment
  2. Enhanced Deployment: Complete Hardhat-based deployment system with artifact management
  3. Network Integration: Native support for Monad testnet and mainnet
  4. Flexible Configuration: Customizable incentive parameters (lead time, duration, lockups)
  5. Extendable Epochs: Refundee can extend incentives in rolling windows (each extension is bounded by maxIncentiveDuration, but total lifetime can exceed the original duration)
  6. Production Ready: Comprehensive testing and verification infrastructure
  7. Neverland Specific: Optimized for Neverland's DUST/MON liquidity incentives with perpetual extensions, lockups, and harvest‑while‑staked flows

Key Features

Features

  • Proportional Rewards: Time-weighted liquidity rewards based on position size and duration
  • Vesting Support: Configurable vesting periods for locked incentives (per position, enforced on harvest)
  • Lockup Periods: Optional lockup periods preventing early unstaking while allowing harvesting
  • Rolling Extensions: Incentives can be extended multiple times; each extension respects maxIncentiveDuration from the extension moment but the overall program can continue indefinitely
  • Harvest-While-Staked: LPs can harvest rewards without exiting once vesting is satisfied
  • Multi-Incentive Staking: Single positions can participate in multiple concurrent incentives
  • Per-stake vesting memory: Once a stake satisfies vesting, subsequent harvests/unstakes on that stake do not reapply vesting unless the position is unstaked and restaked
  • Locked reward sweep: Refundee can collect vesting penalties (totalRewardLocked) mid-program; unclaimed rewards stay in the contract
  • Permissionless: Anyone can create liquidity incentives
  • ERC20 Agnostic: Support for any reward token (with security considerations)

Operational Notes

  • Vesting semantics: Vesting is time-in-range based. Once a stake vests, future harvests/unstakes skip vesting until the stake is exited and re-entered.
  • Refundee powers: After endTime, refundee can force-unstake positions (lockup bypass). At any time, refundee can sweep totalRewardLocked (forfeited rewards); totalRewardUnclaimed is untouched.
  • Lockup grace: A 1-hour grace window after staking allows the owner to unstake even if lockup is set (to correct misconfigured/out-of-range positions). After that, lockup applies until expiry.
  • Timing helper: getStakeTiming exposes grace/lockup endpoints, time-in-range accrued, vesting remaining, and vesting status for frontends.
  • Extensions: Extending changes the forward reward rate depending on how much reward is added vs. how much time is added; past accruals are unaffected.
  • ERC20 Rewards: Designed for standard ERC20 reward tokens only.

Requirements

  • Node.js >= 16
  • Private key or mnemonic for deployment account
  • RPC access to Monad networks
  • Block explorer API keys (Optional, for verification)

Getting Started

  1. Install dependencies:

    yarn install
    
  2. Compile contracts before running any other command:

    yarn compile
    

Deployment

Environment Setup

  1. Copy the .env.example to .env:

    cp .env.example .env
  2. Configure your .env file:

     # Etherscan API key for contract verification
     ETHERSCAN_API_KEY=your_etherscan_api_key_here
    
     # Private key for contract deployment
     PRIVATE_KEY=your_private_key_here
    
     # Monad Mainnet RPC URL
     MONAD_RPC_URL=your_monad_mainnet_rpc_url
    
     # Uniswap V3 Factory addresses
     UNISWAP_V3_FACTORY_MONAD=0x...
     UNISWAP_V3_POSITION_MANAGER_MONAD=0x...
    
     UNISWAP_V3_FACTORY_MONAD_TESTNET=0x...
     UNISWAP_V3_POSITION_MANAGER_MONAD_TESTNET=0x...

Deploy to Monad Testnet

# Full deployment with verification
npx hardhat deploy --network monad-testnet --verify

# Deploy without verification
npx hardhat deploy --network monad-testnet

Deploy to Monad Mainnet

# Deploy to mainnet
npx hardhat deploy --network monad --verify

Custom Deployment Parameters

Override default incentive configuration:

# Custom lead time and duration
npx hardhat deploy --network monad-testnet \
  --maxIncentiveStartLeadTime 2419200 \
  --maxIncentiveDuration 2592000 \
  --verify

Common Operations

View Deployment Status

# Check deployment artifacts
cat deployments-monad-testnet.json
cat deployments/monad-testnet/UniswapV3Staker.json

Create Incentives (Post-Deployment)

After deployment, incentives can be created using the deployed contract:

// Example: Create DUST/MON incentive with lockup period
const incentiveKey = {
    rewardToken: USDC_ADDRESS,
    pool: DUST_MON_POOL_ADDRESS,
    startTime: Math.floor(Date.now() / 1000) + 86400, // Tomorrow
    endTime: Math.floor(Date.now() / 1000) + 86400 * 7, // 7 days
    vestingPeriod: 86400 * 3, // 3 days vesting (full rewards after 3 days in range)
    lockupPeriod: 86400 * 2, // 2 days lockup (cannot unstake for 2 days)
    refundee: treasuryAddress,
};

await staker.createIncentive(incentiveKey, rewardAmount);

Stake Positions

// Approve NFT transfer
await positionManager.approve(stakerAddress, tokenId);

// Stake position
await positionManager.safeTransferFrom(
    userAddress,
    stakerAddress,
    tokenId,
    ethers.utils.defaultAbiCoder.encode(["tuple(...)"], [incentiveKey])
);

Contract Verification

Contracts are automatically verified during deployment when using the --verify flag.

Project Structure

├── contracts/           # Uniswap V3 Staker contract and interfaces
├── scripts/             # Deployment and utility scripts
│   ├── deploy.ts        # Main deployment script with artifact generation
│   └── deploy-config.ts # Network-specific configuration
├── test/                # Test suites and fixtures
├── docs/                # Documentation and design specifications
│   ├── Design.md        # Core contract design and mechanics
│   └── Neverland.md     # Neverland-specific deployment and configuration
├── deployments/         # Deployment artifacts per network
├── hardhat.config.ts    # Hardhat configuration
├── package.json         # Project dependencies and scripts
└── README.md            # This file

Note: maxIncentiveDuration limits how far into the future each extension may push the end time. Refundee can extend again after that window elapses, so total lifetime can exceed 28 days.

Incentive Structure

Each incentive is defined by an IncentiveKey with the following parameters:

  • Reward Token: ERC20 token used for rewards
  • Pool: Uniswap V3 pool address for the incentive
  • Start Time: When the incentive becomes active
  • End Time: When the incentive expires
  • Vesting Period: Time required in-range for full rewards (0 = immediate)
  • Lockup Period: Time before unstaking is allowed (0 = no lockup)
  • Refundee: Address that can refund unused rewards

Key Validation Rules

  • Start Time: Must be now or in the future, max 28 days ahead
  • Duration: End time - start time ≤ 28 days
  • Vesting: Must be ≤ incentive duration
  • Lockup: Must be ≤ incentive duration and either 0 or greater than the 1-hour grace window
  • Reward: Must be > 0
  • Refundee: Must be valid address

Vesting & Harvesting Semantics

  • Vesting is enforced per stake: a position must spend at least vestingPeriod seconds in range since its last harvest before it can harvest again.
  • If a user unstakes before vesting completes, the contract keeps the original behavior (partial rewards, remainder locked for refundee).
  • Harvesting after vesting completes resets the per-stake timer; users who want frequent harvests should set vestingPeriod = 0 (instant vesting).

Lockup & Perpetual Incentives

Neverland uses lockup periods and rolling extensions to stabilize liquidity:

  • During Lockup: Users can harvest rewards but cannot unstake positions
  • After Lockup: Normal unstaking behavior (subject to vesting penalties if applicable)
  • Independent of Vesting: Lockup controls unstaking, vesting controls reward harvesting
  • Refundee Override: Incentive creators can always unstake after incentive end, regardless of lockup
  • Post-Expiry Enforcement: Lockup timers continue to apply even if the incentive has ended; owners must satisfy the full lockup duration, while refunders can unstake immediately after the program ends (for clean-up scenarios).
  • On-Chain Data: incentives(incentiveId) now returns (totalRewardUnclaimed, totalRewardLocked, totalSecondsClaimedX128, numberOfStakes, endTime, vestingPeriod, lockupPeriod).

Deployments

Neverland v1.0.4

  • Added optional lockupPeriod parameter to prevent early unstaking
  • Added support for incentives extension by extLockupPeriod
  • Lockup periods work independently from vesting periods
  • Users can harvest rewards during lockup but cannot unstake
Network Status Address
Monad Production 0x...
Monad Testnet Testnet 0x...

Upstream v1.0.3

The main change compared to v1.0.2 is the addition of a new configuration value called vestingPeriod, which defines the minimal time a staked position needs to be in range to receive the full reward.

Network Status Address
Polygon Production 0x8c696deF6Db3104DF72F7843730784460795659a

Upstream v1.0.2

Network Status Address
Mainnet Production 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Rinkeby Testnet 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Kovan Testnet 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Ropsten Testnet 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Goerli Testnet 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Arbitrum Rinkeby Testnet 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Arbitrum One Production 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Optimism Production 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65
Optimism Kovan Testnet 0xe34139463bA50bD61336E0c446Bd8C0867c6fE65

DEPRECATED: For historical verification purposes only, the staker at tag v1.0.0 was deployed at the address: 0x1f98407aaB862CdDeF78Ed252D6f557aA5b0f00d

Links

License and Attribution

Uniswap V3 Staker is part of the Uniswap protocol, licensed under GPL-2.0-or-later.

Revert Finance Expansion extends the core functionality with the vestingPeriod.

Neverland Enhancement adds the lockupPeriod feature for enhanced incentive design flexibility and extLockupPeriod for incentives extension, while harvestRewards is created to allow users to harvest rewards during lockup periods without unstaking.

Attribution:

This repository builds on:

  • Uniswap V3 Staker: Core staking mechanics and reward distribution
  • Revert Finance: Enhanced reward distribution with vesting period
  • Neverland: Lockup periods for controlled unstaking, incentives extension and rewards claiming during lockup periods without unstaking.

For Uniswap governance and licensing questions, visit Uniswap Governance.


With respect and gratitude to the Uniswap and Revert Finance communities 💜

About

Canonical liquidity mining contract for Uniswap V3

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 13