For the complete documentation index, see llms.txt. This page is also available as Markdown.

Convex Frax Staking (cvxFXS)

The Convex-Frax staking platform lets users trustlessly stake positions on the Frax Finance gauge system while borrowing Convex's boosting power via veFXS. The Convex system creates a unique proxy vault for each (pool, user) pair which only that user can operate for principal changes. This isolates deposits and keeps the user in control of their funds. Each vault is given permission to share in Convex's veFXS boost, which increases farming efficiency. In return, Convex takes a percentage of the FXS farmed and routes it via FeeDepositV2 to the configured receivers — see the Fee flow section below.

GitHub: https://github.com/convex-eth/frax-cvx-platform

Core architecture

Unlike the mainnet platform's shared-reward-pool model, the Frax platform is vault-per-user:

Contract
Role

VoterProxy (voteProxy)

holds the protocol's veFXS; is the source of boosting power

Booster

management entry point; creates vaults, manages pools, fees, and roles

PoolRegistry

pool configuration (implementation, staking address, staking token)

StakingProxyBase / StakingProxyERC20 / StakingProxyUniV3

per-user vault implementations (proxy to the Frax gauge)

MultiRewards

extra rewards contract for a pool (outside the gauge)

FeeRegistry

holds the fee split used when fees are applied

FeeDepositV2

receives farmed FXS fees and routes them to receivers

cvxFxs

the Convex-Frax token (receipt for deposited FXS that is veFXS-locked)

cvxFxsStaking

staking contract for cvxFXS

cvxFXS/FXS pool

the canonical liquidity for cvxFXS (on the Convex platform)

Vault-per-user model

  1. Convex creates a vault implementation — an implementation contract that is a proxy staking interface to the Frax gauge. Different implementations adapt to different staking products (StakingProxyERC20, StakingProxyConvex, StakingProxyUniV3, joint/temple variants).

  2. Convex creates a pool and assigns an implementation — via the Booster/PoolRegistry (fields: implementation, staking address, staking token). A MultiRewards contract is also created for extra rewards outside the gauge.

  3. A user creates their own vault — booster.createVault(_pid) clones the pool's implementation and assigns the caller as owner (initialize(_owner, _stakingAddress, _stakingToken, _rewardsAddress)). One vault per (pool, user); only the owner can perform principal operations (deposit/withdraw/stake).

  4. Convex enables the vault to use the protocol's veFXS boost at creation time by telling the Frax staking contract the vault may share Convex's boosting power.

  5. The user stakes through their vault exactly as they would interact with the main Frax staking contract (stakeLocked, lockAdditional, lockLonger, withdrawLocked).

  6. When rewards are claimed, a fee on FXS is applied (see below); the rest goes to the vault owner.

Because vaults are user owned, each user determines their own lock timing, and user funds are never co-mingled. Users interact with their vault as a proxy to the Frax gauge — no wrapper tokens are minted; the vault itself is the position.

Permission model to keep in mind: principal operations are owner-only, but reward claims are permissionless — the vault's getReward() is unguarded (anyone can trigger it; rewards flow to the configured destination/redirect), so integrators should not assume a single privileged caller. There is no separate earmark selector on the Frax vault; reward state is updated by the claim path itself.

Vault interface

Fee flow

The FeeRegistry (mainnet 0xC9aCB83ADa68413a6Aa57007BC720EE2E2b3C46D) defines the fee split in basis points. When a vault claims, the fee portion of FXS is sent to the fee deposit; the remainder goes to the vault owner. Current fee split:

Component
Fee (bps)
Destination

cvxFXS incentive

1000 (10%)

cvxfxsReceiver (operator-set — re-read on-chain)

cvx (vlCVX) incentive

500 (5%)

vlCVX via the vlCVX fee receiver (notifyRewardAmount(FXS))

platform

500 (5%)

platform fee receiver

Total

2000 (20%)

capped at maxFees = 2000 bps

Fees are routed via FeeDepositV2 (0x7A527d8bB09f7D70C148aB5DE919e9BF68a0d769), which forwards FXS to the configured receivers on distribute(): cvxfxsReceiver, vlcvxReceiver, and platformReceiver. The repo also contains a FeeReceiverCvxFxs contract intended to forward FXS to the cvxFxsStaking reward stream — note the live cvxfxsReceiver on FeeDepositV2 may differ (it is operator-set), so always read FeeDepositV2.cvxfxsReceiver() before describing the destination. The FeeRegistry.getFeeDepositor(_from) lookup supports per-source redirects.

Fee weights themselves are governance-adjustable — re-read the registry on-chain before publishing if you print them.

cvxFXS token

FxsDepositor.sol (0x8f55d7c21bDFf1A51AFAa60f3De7590222A3181e) lets users deposit FXS to receive cvxFXS. The deposited FXS is locked into the veFXS system (Escrow 0xc8418aF6358FFddA74e09Ca9CC3Fe03Ca6aDC5b0) and the resulting veFXS power is what boosts the Frax-platform user vaults. cvxFxs (0xFEEf77d3f69374f66429C91d732A244f074bdf74) is a standard ERC20 with operator-controlled mint/burn. cvxFXS can be staked in cvxFxsStaking for configured rewards, and trades against FXS in a Convex-managed liquidity pool — cvxFXS holders receive the value accrual of that yield/liquidity, not a direct per-holder boost.

Fraxtal / cross-chain

A related deployment lives on Fraxtal (cvxFXB, FraxtalBooster, FraxtalFxsDepositor, FraxtalVoterProxy) for Frax's own L2; see the contracts/fraxtal/ folder in the repo. Addresses for every deployment are in contracts/contracts.json (per-chain sections).

Mainnet key addresses: Booster 0xD8Bd5Cdd145ed2197CB16ddB172DF954e3F28659, PoolRegistry 0x41a5881c17185383e19Df6FA4EC158a6F4851A69, voteProxy 0x59CFCD384746ec3035299D90782Be065e466800B. Query poolLength() for the live pool count.

Last updated

Was this helpful?