> For the complete documentation index, see [llms.txt](https://docs.convexfinance.com/convexfinanceintegration/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convexfinance.com/convexfinanceintegration/convex-f-x-staking-cvxfxn.md).

# 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

```javascript
await booster.createVault( pid )               //state-changing; read the vault from PoolRegistry.vaultMap(pid, user)
await vault.deposit( amount )
await vault.withdraw( amount )
await vault.earned()                            //returns (tokens[], amounts[])
await vault.getReward(true)                     //claim (toggle: also invoke the gauge claim/mint)
await vault.getReward(false, tokenList)         //claim; tokenList filters Convex MultiRewards, not the gauge claim
await vault.transferTokens( tokenList )         //owner pulls non-FXN, non-gauge tokens off the vault
```

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**.

```javascript
//owner-only setters (owner = veFXN voter proxy at the FeeRegistry)
await feeReg.setFees( totalFees )          //flat fee bps
await feeDeposit.setPlatformIncentive( bps )
await feeDeposit.setvlCvxIncentive( bps )  //remainder automatically flows to the cvxFXN receiver
```

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](https://github.com/convex-eth/function_x/blob/main/contracts/contracts/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.
