Creating a Lock

Overview

The Curvance Voting Escrow (veCVE) system allows users to lock their CVE tokens for a fixed period of 1 year in exchange for veCVE tokens. These tokens provide governance rights and enhanced protocol rewards. This document focuses specifically on the lock creation mechanism.

Technical Details

Lock Duration

Unlike traditional voting escrow systems that offer variable lock durations, veCVE implements a standardized lock period of exactly 1 year. This design choice facilitates a unified point system across multiple chains.

Technically, the lock duration is defined as:

  • LOCK_DURATION_EPOCHS = 26 (number of epochs in a lock period)

  • lockDuration = epochDuration * LOCK_DURATION_EPOCHS (duration in seconds)

An epoch is a fixed time interval defined in the Curvance protocol (typically 2 weeks).

Lock Types

veCVE offers two lock modes:

  • Standard Lock: Locks tokens for exactly 1 year

  • Continuous Lock: Automatically extends the lock indefinitely until manually disabled

For continuous locks, the unlockTime is set to CONTINUOUS_LOCK_VALUE (maximum value of uint40).

Core Data Structures

struct Lock {
    uint216 amount;  // Amount of CVE locked
    uint40 unlockTime;  // Timestamp when lock expires or CONTINUOUS_LOCK_VALUE
}

Storage Variables

  • userLocks: Maps user addresses to an array of Lock structures

  • userPoints: Tracks the "points" a user has (1:1 with locked amount, or multiplied for continuous locks)

  • chainPoints: Total points on the chain

  • userUnlocksByEpoch: Tracks when a user's locks will unlock

  • chainUnlocksByEpoch: Tracks when locks will unlock chain-wide

Key Mechanisms

When creating a lock:

  1. The system transfers CVE tokens from the user to the contract

  2. A new Lock structure is created and added to userLocks[user]

  3. The user receives veCVE tokens (1:1 with locked CVE)

  4. Points are updated:

    • For standard locks: points = amount

    • For continuous locks: points = amount CL_POINT_MULTIPLIER (2x)

  5. For standard locks, unlock data is recorded for future epoch tracking

User Functions

createLock()

Creates a new lock by transferring CVE tokens from the caller to the contract.

Function signature:

function createLock(
    uint256 amount,
    bool continuousLock,
    RewardsData calldata rewardsData,
    bytes calldata params,
    uint256 aux
) external nonReentrant
Parameter
Type
Description

amount

uint256

Amount of CVE tokens to lock (minimum 1 CVE)

continuousLock

bool

Whether the lock should be continuous (auto-extending)

rewardsData

RewardsData

Data for claiming any pending rewards

params

bytes

Additional parameters for reward claiming

aux

uint256

Auxiliary data for reward claiming

createLockFor()

Allows a permissioned address (like a protocol contract) to create a lock on behalf of another user.

Function signature:

function createLockFor(
    address recipient,
    uint256 amount,
    bool continuousLock,
    RewardsData calldata rewardsData,
    bytes calldata params,
    uint256 aux
) external nonReentrant
Parameter
Type
Description

recipient

address

The address to create the lock for

amount

uint256

Amount of CVE tokens to lock (minimum 1 CVE)

continuousLock

bool

Whether the lock should be continuous (auto-extending)

rewardsData

RewardsData

Data for claiming any pending rewards

params

bytes

Additional parameters for reward claiming

aux

uint256

Auxiliary data for reward claiming

compoundRewardsIntoLock()

Used by the RewardManager to compound protocol rewards directly into a user's lock.

Function signature:

function compoundRewardsIntoLock(
    address recipient,
    uint256 amount,
    uint256 lockIndex,
    bool isFreshLock,
    bool isContinuousLock
) external
Parameter
Type
Description

recipient

address

The address to lock CVE tokens for

amount

uint256

Amount of CVE tokens to lock

lockIndex

uint256

The index of the lock to extend (only used if not a fresh lock)

isFreshLock

bool

Whether to create a new lock or add to an existing one

isContinuousLock

bool

Whether the lock should be continuous

Event Signatures

// Emitted when a lock is created
event Locked(address indexed user, uint256 amount);

Benefits of Locking

When a user locks CVE tokens:

  1. They receive veCVE tokens 1:1 with their locked CVE

  2. They earn increased protocol rewards based on their lock duration

  3. Continuous locks receive 2x points (controlled by CL_POINT_MULTIPLIER), providing enhanced rewards

  4. They gain voting power in governance proportional to their veCVE balance

Restrictions

The locking system has several restrictions:

  • Minimum lock amount is 1 CVE (in WAD format)

  • Locks cannot be created during blackout periods around epoch transitions

  • Early withdrawals are possible but subject to penalties

By choosing to lock their CVE tokens, users become active participants in the Curvance protocol with enhanced rewards and governance rights.

Last updated