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

Convex f(x) Staking (cvxFXN)

The Convex-f(x) staking platform lets users trustlessly stake positions on the f(x) gauge system while borrowing Convex's boosting power via veFXN. As with the Convex-Frax platform, Convex creates a unique proxy vault per (pool, user) pair which only the user can operate for principal changes, isolating deposits and keeping users in control of their funds. The vault is granted permission to share in Convex's veFXN boost, increasing farming efficiency. In return, Convex takes a percentage of the FXN farmed as a fee.

GitHub: https://github.com/convex-eth/function_x

Core architecture

Contract
Role

FxnVoterProxy (voteProxy)

holds the protocol's veFXN; source of boosting power

Booster

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

PoolRegistry (poolReg)

pool configuration (implementation, gauges, staking tokens)

StakingProxyBase / StakingProxyERC20 / StakingProxyRebalancePool

per-user vault implementations

MultiRewards

extra rewards for a pool outside the gauge

FeeRegistry (feeReg)

holds the fee % applied on claimed FXN

FeeDepositV2

receives collected FXN fees, routes to platform + cvxFXN

cvxFxn

the Convex-Function(X) token

cvxFxnStaking

staking contract for cvxFXN (reward-token set managed on-chain)

FxnDepositor

deposits FXN → veFXN and mints cvxFXN

Burner

burns cvxFXN (no token conversion)

LpRewardHook

asks the current Booster to claimFees() for LPs (not an LP reward claimer itself)

Vault-per-user model

Identical in shape to the cvxFXS platform:

  1. Convex creates vault implementation contracts — proxy staking interfaces to the underlying Function(X) gauge (StakingProxyERC20 for Curve-convex LPs, StakingProxyRebalancePool for rebalance pools).

  2. Convex creates a pool and assigns an implementation — addPool(implementation, stakingAddress, stakingToken) on the Booster/PoolRegistry; a MultiRewards contract is created for extra rewards. Pools can be marked inactive to halt new vault creation (existing vaults remain operable).

  3. A user creates their own vault — booster.createVault(_pid) clones the implementation (initialize(_owner, _pid)). One vault per (pool, user); only the owner can perform principal operations (deposit/withdraw).

  4. Convex enables the vault to use the protocol's veFXN boost at creation time via setVeFXNProxy.

  5. The user stakes/claims through their vault — deposit(_amount), withdraw(_amount), earned(), getReward(bool _claim, address[] _tokenList).

Reward claims are not exclusively owner-callable: earned()/un-guarded getReward() are public. Principal operations are owner-only. FXN claimed through the vault has the fee applied and sent to the Convex system for distribution. On StakingProxyERC20, tokens other than FXN returned by the gauge are claimed directly to the vault owner via the gauge's setRewardReceiver() mechanism; rebalance-pool vaults instead claim to the vault itself and transfer active non-FXN rewards to the owner.

Vault interface

Note: _claim only toggles whether the underlying gauge claim (and any related mint) is invoked — there is no conversion/redeposit step. transferTokens deliberately skips FXN (fee must be applied) and the gauge token.

Fee flow

The FXN fee is a flat rate from the FeeRegistry (0x4f258feCc91b2ff162cA702c2Bd9ABf2AF089611), applied as fxnBalance * totalFees / 10000. Current settings: totalFees = 1700 (17%), capped at maxFees = 2000, denominator 10000. When a vault claims, that fraction of the FXN balance is transferred to feeRegistry.getFeeDepositor(...) and the remainder goes to the vault owner.

The collected FXN sits in FeeDepositV2 (0x8133F7D5CD1A1E184228C373F5bEFa98Fa01395D) and is split on processFees() between the receivers:

Receiver
Split of the fee pot
Notes

platform

platformIncentive = 5000 bps (50%)

→ platformReceiver (Convex treasury)

vlCVX

vlcvxIncentive = 0 bps

configurable; → vlcvxReceiver

cvxFXN

remainder (50%)

→ cvxfxnReceiver (FeeReceiverCvxFxn), which notifies into the cvxFXN staking reward stream

So of a gross 17% fee, the current default is ~8.5% to platform and ~8.5% into the cvxFXN staking reward stream (0% to vlCVX). This is a direct FXN reward stream for staked cvxFXN.

These setters are restricted to the registry owner (the veFXN voter proxy). Do not assume a current Booster provides a working external forwarding path to these — check the Booster ABI (its own encoded fee setters target different signatures).

cvxFXN token & staking

FxnDepositor.sol (0x56B3c8eF8A095f8637B6A84942aA898326B82b91) accepts FXN (0x365AccFCa291e7D3914637ABf1F7635dB165Bb09), locks it into veFXN (via Escrow 0xEC6B8A3F3605B083F7044C0F31f2cac0caf1d469), and mints cvxFxn (0x183395DbD0B5e93323a7286D1973150697FFFCB3). The mint itself is always 1:1. A separate, conditional platformHolding diversion can apply on top: after minting, if amount + cvxFxn.totalSupply() <= veFXN.locked(staker) (i.e. total minted cvxFXN stays within the veFXN backing), up to platformHolding bps of the user's incoming FXN is instead transferred to platformDeposit (a governance-set address/rate — read the live values before integrating). Deposits support _lock=false (deferred locking) and _lock=true (immediate lock).

cvxFxnStaking (0xEC60Cd4a5866fb3B0DD317A46d3B474a24e06beF) is the staking/reward contract for cvxFXN. It exposes the standard triad — stake/deposit, withdraw, getReward(address, forwardTo) — plus setRewardRedirect(address), notifyRewardAmount, and reward-token management. Query rewardTokenLength()/rewardTokens(i) for the current reward-token set (a governance-managed list, not a fixed inventory).

Design decisions (from the repo)

  • User funds are controlled solely by user-owned vaults; Convex admin never has direct access to funds.

  • Vault functions that admin does control relate to boost (which veFXN proxy a vault uses) and fees, with hard-coded upper limits on fees.

  • Creating a vault requires an extra initial transaction, but vaults keep funds un-co-mingled and rewards directly linked to the vault — no trailing reward structure or harvesting is required.

  • Vaults allow users to execute arbitrary functions within limits (e.g. claim an airdrop on gauge interactions).

Addresses

Mainnet: Booster 0xAffe966B27ba3E4Ebb8A0eC124C7b7019CC762f8, PoolRegistry 0xdB95d646012bB87aC2E6CD63eAb2C42323c1F5AF, voteProxy 0xd11a4Ee017cA0BECA8FA45fF2abFe9C6267b7881. contracts/contracts.json lists the registered pools (implementation, staking address/token, rewards) — query PoolRegistry.poolLength() for the live count; per-user vault addresses are created per user and not catalogued there.

Last updated

Was this helpful?