> 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/staking-wrappers.md).

# Staking Wrappers

Convex staking wrappers let protocols and services tokenize a staked Convex position as a transferable ERC20 receipt. This is the standard integration surface for yield aggregators, lending protocols, and vaults that want to deposit into Convex while keeping a liquid, transferable representation of the position.

### ConvexStakingWrapper

[ConvexStakingWrapper.sol](https://github.com/convex-eth/platform/blob/main/contracts/contracts/wrappers/ConvexStakingWrapper.sol) (mainnet) wraps a single Convex pool (by pid). It is an ERC20 whose supply equals the amount staked in the underlying pool. It is based on Curve's gauge wrapper implementations.

#### How it works

1. A wrapper is created for a pool id and initialized (cloned via the `WrapperFactory`, see below).
2. `deposit(_amount, _to)`: pulls the pool's Curve LP token, deposits into the Booster and stakes into the pool's reward contract, and mints wrapper ERC20 to `_to`.
3. `stake(_amount, _to)`: same but expects the caller to already hold the Convex deposit token (use when the caller has raw deposit tokens from `booster.deposit(pid, amount, false)`).
4. `withdraw(_amount)`: burns wrapper tokens and returns Convex deposit tokens to the caller.
5. `withdrawAndUnwrap(_amount)`: burns wrapper tokens and returns the underlying Curve LP token directly (unwrap via the Booster).

```javascript
//create a wrapper for pool n (permissionless on mainnet)
let tx = await wrapperFactory.CreateWrapper( n )
//obtain the wrapper address from the WrapperCreated(wrapper, pid) event in the receipt
let wrapper = <address from event>

//deposit LP tokens and mint wrapper shares
await wrapper.deposit( amount, to )

//withdraw, receiving the Convex deposit token
await wrapper.withdraw( amount )

//withdraw, unwrapping to the underlying Curve LP token
await wrapper.withdrawAndUnwrap( amount )
```

Note: `CreateWrapper()` is a state-changing call — it returns a transaction, not the Solidity return value. Read the wrapper address from the `WrapperCreated(address _wrapper, uint256 _pid)` event in the receipt (or use `eth_call` against a fresh clone for simulation).

#### Rewards

The wrapper mirrors the rewards of the underlying Convex pool. It tracks **CRV** and **CVX** rewards itself (indexes 0/1) plus any extra rewards added via `addTokenReward(_token)`. Key functions:

* `earned(_account)` — returns claimable `EarnedData[]`; note this is **mutative** (it checkpoints claimable rewards first); cast it as a view in your ABI when calling off-chain via `eth_call`.
* `getReward(_account)` / `getReward(_account, _forwardTo)` — claim rewards for an account or forward them.
* `setRewardRedirect(_to)` — route rewards to an address; **mutable** — the account can change it or disable it with `address(0)` at any time.
* `user_checkpoint(_account)` — checkpoint an account's rewards (safe to call before reads).
* `addTokenReward(_token)` / `invalidateReward(_token)` — owner-managed extra reward tokens.
* `setHook(_hook)` — optional `IRewardHook` the wrapper calls after claiming (useful for compounding into the wrapper).
* `earmarkRewards()` — triggers the Booster earmark for the wrapped pool so reward balances are current.

#### Ownership & management

* The wrapper has an owner that controls reward-token management, shutdown, and hooks. When created through the factory, `initialize(_poolId)` is called by the **factory**, so a generic factory-created clone's owner is the factory contract — there is no wrapper-admin forwarding/ownership-handoff inside the generic factory, which limits how a protocol can manage a factory-created wrapper. Review the specialized variants below for ownership models better suited to managed integrations.
* The owner **cannot** touch user funds.
* `shutdown()` — owner can shut the wrapper down; after shutdown, deposits are blocked and users can still withdraw.

### WrapperFactory

[WrapperFactory.sol](https://github.com/convex-eth/platform/blob/main/contracts/contracts/wrappers/WrapperFactory.sol) clones the wrapper implementation per pool:

* `CreateWrapper(_pid)` — **permissionless** on mainnet: anyone can clone the current `wrapperImplementation` for a pid and initialize it. Only implementation/ownership changes are owner-restricted.
* `setImplementation(_imp)` — owner updates the implementation used for future clones.

### StashTokenWrapper (pool reward tokens for newer pools)

For some newer pools, the `VirtualBalanceRewardPool`'s `rewardToken` is a [StashTokenWrapper.sol](https://github.com/convex-eth/platform/blob/main/contracts/contracts/StashTokenWrapper.sol) facade rather than the raw incentive token. The `StashTokenWrapper` is a **minimal facade, not an ERC20 that mints per-user receipts**: it reports a balance only for the reward pool, and when the reward pool calls `transfer(recipient, amount)`, the wrapper simply forwards the **raw underlying incentive token** to the recipient. So "**claiming**" the wrapper-credited reward means calling `getReward()` on the VirtualBalanceRewardPool, which unwinds through the wrapper to the raw token. Don't attempt to `transferFrom` or mint from a `StashTokenWrapper` — it has neither.

### Specialized wrappers

Convex maintains purpose-built wrapper variants. They do **not** all share an identical surface — check each implementation before integrating:

* `ConvexStakingWrapperAbra` — for Abracadabra Cauldron positions (`abrapools` in contracts.json)
* `ConvexStakingWrapperFrax` / `ConvexStakingWrapperFraxLend` — for Frax gauge / FraxLend collateral
* `ConvexStakingWrapperMorpho` — for Morpho lending; the generic `deposit/stake/withdraw` are no-ops and it uses its own `depositFor`-style entry plus collateral management
* `ConvexStakingWrapperOhmSync` — standalone wrapper for Olympus/OHM sync positions (not a subclass of the generic wrapper)
* `CvxCrvStakingWrapper` — standalone ERC20 staking wrapper over the staked cvxCRV/cvxCRV-fees position (own reward accounting; not ERC-4626)

Check `contracts.json` (`abrapools`, `raripools`, `fraxlend`, and the `masterFraxWrapper`/`factoryAbraWrapper` entries) for the listed deployed/historical instances. Note it is a deployment record, not a complete wrapper registry — generic, Morpho and OhmSync wrapper instances are not all catalogued there.
