> 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/side-chain-implemention.md).

# Side Chain Implemention

The Convex system is also rolled out to non-Ethereum chains (the sidechain repo currently contains Arbitrum, Polygon, and Fraxtal deployment data). While the main flow is largely the same, there are a few changes to take note of.

Sidechain GitHub: <https://github.com/convex-eth/sidechain-platform>

Sidechain Deployed Addresses: <https://github.com/convex-eth/sidechain-platform/blob/main/contracts/contracts.json>

### ConvexRewardPool

The [ConvexRewardPool.sol](https://github.com/convex-eth/sidechain-platform/blob/main/contracts/contracts/ConvexRewardPool.sol) replaces the BaseRewardPool. Unlike the mainnet platform, deposits are wrapped and staked directly into this ConvexRewardPool and it is a tokenized erc-20 position (the reward pool itself is the deposit token).

The ConvexRewardPool typically does not linearly distribute over time: on most staking/claim actions it claims from its reward sources, then diffs reward-token balances and distributes the increase to users immediately. This lets the pool and rewards match the Curve gauges without a trailing period. Note some paths bypass the checkpoint — e.g. `emergencyWithdraw()` withdraws without checkpointing (see below). With the bundled `ExtraRewardPool` extra rewards happen to stream over seven days, but that is a property of that specific extra-reward contract, not a requirement — rewards can be added directly and are checkpointed.

The ConvexRewardPool is agnostic to rewards that can be added. Thus take note that the `earned()` function is a **mutative** function on sidechains: it will claim from all sources and check the differences before returning a user's claimable token amounts. Off-chain, query it with a view ABI via `eth_call` (a `STATICCALL` cannot execute the mutating code).

#### Reward hooks

Each pool can have a reward hook (`PoolRewardHook`) that is invoked when the pool claims rewards. The hook calls into configured extra reward contracts (managed through the `RewardManager`); it does **not** mint tokens itself:

* `setPoolRewardContract(pool, hook, rewardContract)` — wire an extra reward contract to a pool
* `setPoolRewardToken(pool, token)` / `setPoolInvalidateReward(pool, token)` — manage which tokens the pool tracks
* `setPoolWeight(rewardContract, pool, weight)` — a single extra reward contract (e.g. a **CVX** reward contract) can split its stream between multiple pools by weight
* `setPoolRewardHook(pool, hook)` — set the claim hook for a specific pool (`setPoolHook(hook)` is the default for future pools)

This replaces the mainnet "stash" model: extra rewards on sidechains are added through the reward manager + hook system rather than per-pool stash contracts. (Local-chain **CVX** minting, where present, is a separate operator-restricted mechanism — see `cvxToken.sol`.)

#### Withdrawing

Unlike mainnet, there is no "WithdrawAndUnwrap" option. The main withdraw functions are `withdraw(uint256 _amount, bool _claim)` and `withdrawAll(bool claim)`, returning the Curve LP token directly (much like "unwrap" on mainnet). There is also `emergencyWithdraw(uint256 _amount)` which bypasses checkpointing — use with care, as it may forfeit uncheckpointed rewards.

#### GetReward

There is only a singular claim that will claim all tokens. However there is now a `getReward(address _account, address _forwardTo)` option to forward claims to a different address when called. Take note though `getReward()` without the forward option is unguarded and can be called by anyone, so do not rely on all tokens being forwarded.

Pools that support it also allow you to automatically redirect claimed rewards to another address. To set this feature, use the following function. To disable, set the redirect address to zero. Using this feature will ensure that even the unguarded `getReward()` will transfer tokens to the desired address.

`function setRewardRedirect(address _to) external;`

### Booster

The PoolInfo struct has slightly changed

```
//mainnet
struct PoolInfo {
    address lptoken;
    address token;
    address gauge;
    address crvRewards;
    address stash;
    bool shutdown;
}
```

is now

```
//sidechains
struct PoolInfo {
    address lptoken;
    address gauge;
    address rewards;
    bool shutdown;
    address factory;
}
```

The deposit function also no longer needs a boolean "stake" option and has become simply:

`function deposit(uint256 _pid, uint256 _amount)`

### Pool management

Pool creation and reward wiring is handled by separate modules to keep the Booster small:

* **PoolManager** (`PoolManager.sol`): adds pools, passes the relevant Curve gauge factory to the Booster (the Booster references a single reward factory for creating reward contracts), and shuts down pools. It is a plain contract, not a mainnet-style proxy stack.
* **PoolUtilities** (`PoolUtilities.sol`): helper queries used by the system — e.g. reward-rate lookups, external-reward discovery and rates. It is a library of helpers, not a live-pool catalog.
* **VoterProxy** (`VoterProxy.sol`): holds and stakes the gauge positions (all staked positions consolidate to it), and performs staking/gauge interactions for the operator. On sidechains it does **not** hold a **veCRV** lock or vote lifecycle — there is no Curve voting on those chains; the Booster is the "operator" of the VoterProxy.

### Staking wrappers

The sidechain repo includes wrapper tooling, but it differs from mainnet. The sidechain `ConvexStakingWrapper` is **ERC-4626-style**: `deposit(_amount, _to)` pulls the Curve LP, deposits it into the Convex pool, and mints an ERC20 share for `_to`; `withdraw(_amount)` burns shares and returns the Curve LP directly. There is no separate `stake`/`withdrawAndUnwrap` two-step on the sidechain wrapper. Note `contracts/contracts.json` does not currently list a deployed wrapper/factory, so confirm whether a wrapper exists for the chain you target before building on this surface.

### Deployment addresses

The canonical address list for each chain lives in `contracts/contracts.json` (per-chain sections: arbitrum, polygon, fraxtal) — Booster, VoterProxy, pool manager, reward manager/hook, reward factory, fee deposit, **CVX** token, and pool utilities for each chain. Always read addresses from that file (or query the contracts) rather than hard-coding them into an integration. The JSON is a deployment record, not a complete current pool inventory — query `poolLength()`/`poolInfo()` for live pools.
