# Staking Contracts

⚠️ This page only applies to very early farms, though many newer farms share features and function names ⚠️

Based on Synthetix's staking contract:&#x20;

<https://docs.synthetix.io/incentives/>

## Description

Frax users are able to stake in select Uniswap liquidity pool tokens in exchange for FXS rewards. Future pools and incentives can be added by governance.&#x20;

## Deployment

*Liquidity Pool Tokens (LP)*

Uniswap FRAX/WETH LP: `0xFD0A40Bc83C5faE4203DEc7e5929B446b07d1C76`

Uniswap FRAX/USDC LP: `0x97C4adc5d28A86f9470C70DD91Dc6CC2f20d2d4D`

Uniswap FRAX/FXS LP: `0xE1573B9D29e2183B1AF0e743Dc2754979A40D237`

Uniswap FXS/WETH LP: `0xecBa967D84fCF0405F6b32Bc45F4d36BfDBB2E81`

*Staking Contracts*&#x20;

Uniswap FRAX/WETH staking: `0xD875628B942f8970De3CcEaf6417005F68540d4f`

Uniswap FRAX/USDC staking: `0xa29367a3f057F3191b62bd4055845a33411892b6`

Uniswap FRAX/FXS staking: `0xda2c338350a0E59Ce71CDCED9679A3A590Dd9BEC`

Uniswap FXS/WETH staking (deprecated): `0xDc65f3514725206Dd83A8843AAE2aC3D99771C88`

## State Variables

```
FRAXStablecoin private FRAX
```

Instance of the FRAX contract.

```
ERC20 public rewardsToken
```

Instance for the reward token.

```
ERC20 public stakingToken
```

Instance for the staking token.

```
uint256 public periodFinish
```

Block when the staking period will finish.

```
uint256 public rewardRate
```

Maximum reward per second.

```
uint256 public rewardsDuration
```

Reward period, in seconds.

```
uint256 public lastUpdateTime
```

Last timestamp where the contract was updated / state change.

```
uint256 public rewardPerTokenStored
```

Actual reward per token in the current period.

```
uint256 public locked_stake_max_multiplier
```

Maximum boost / weight multiplier for locked stakes.

```
uint256 public locked_stake_time_for_max_multiplier
```

The time, in seconds, to reach `locked_stake_max_multiplier` .

```
uint256 public locked_stake_min_time
```

Minimum staking time for a locked staked, in seconds.

```
string public locked_stake_min_time_str
```

String version is `locked_stake_min_time_str` .

```
uint256 public cr_boost_max_multiplier
```

Maximum boost / weight multiplier from the collateral ratio (CR). This is applied to both locked and unlocked stakes.

```
mapping(address => uint256) public userRewardPerTokenPaid
```

Keeps track of when an address last collected a reward.  If they collect it some time later, they will get the correct amount because `rewardPerTokenStored` is constantly varying.

```
mapping(address => uint256) public rewards
```

Current rewards balance for a given address.

```
uint256 private _staking_token_supply
```

Total amount of pool tokens staked .

```
uint256 private _staking_token_boosted_supply
```

`_staking_token_supply` with the time and CR boosts accounted for. This is not an actual amount of pool tokens, but rather a 'weighed denominator'.

```
mapping(address => uint256) private _balances
```

Balance of pool tokens staked for a given address.

```
mapping(address => uint256) private _boosted_balances
```

`_balances` , but with the time and CR boosts accounted for, like `_staking_token_boosted_supply`.

```
mapping(address => LockedStake[]) private lockedStakes
```

Gives a list of locked stake lots for a given address.

```
struct LockedStake {
        bytes32 kek_id;
        uint256 start_timestamp;
        uint256 amount;
        uint256 ending_timestamp;
        uint256 multiplier; // 6 decimals of precision. 1x = 1000000
    }
```

A locked stake 'lot'.&#x20;

## **View Functions**

**totalSupply**

```
totalSupply() external override view returns (uint256)
```

Get the total number of staked liquidity pool tokens.

**stakingMultiplier**

```
stakingMultiplier(uint256 secs) public view returns (uint256)
```

Get the time-based staking multiplier, given the `secs` length of the stake.

**crBoostMultiplier**

```
crBoostMultiplier() public view returns (uint256)
```

Get the collateral ratio (CR) - based staking multiplier.

**stakingTokenSupply**

```
stakingTokenSupply() external view returns (uint256)
```

same as totalSupply().

**balanceOf**

```
balanceOf(address account) external override view returns (uint256)
```

Get the amount of staked liquidity pool tokens for a given `account`.

**boostedBalanceOf**

```
boostedBalanceOf(address account) external view returns (uint256)
```

Get the boosted amount of staked liquidity pool tokens for a given `account`. Boosted accounts for the CR and time-based multipliers.

**lockedBalanceOf**

```
lockedBalanceOf(address account) public view returns (uint256)
```

Get the amount of locked staked liquidity pool tokens for a given `account` .

**unlockedBalanceOf**

```
unlockedBalanceOf(address account) external view returns (uint256)
```

Get the amount of unlocked / free staked liquidity pool tokens for a given `account` .

**lockedStakesOf**

```
lockedStakesOf(address account) external view returns (LockedStake[] memory)
```

Return an array of all the locked stake 'lots' for&#x20;

**stakingDecimals**

```
stakingDecimals() external view returns (uint256)
```

Returns the `decimals()` for `stakingToken` .

**rewardsFor**

```
rewardsFor(address account) external view returns (uint256)
```

Get the amount of FXS rewards for a given `account` .

**lastTimeRewardApplicable**

```
lastTimeRewardApplicable() public override view returns (uint256)
```

Used internally to keep track of `rewardPerTokenStored` .

**rewardPerToken**

```
rewardPerToken() public override view returns (uint256)
```

The current amount of FXS rewards for staking a liquidity pool token.

**earned**

```
earned(address account) public override view returns (uint256)
```

Returns the amount of unclaimed FXS rewards for a given `account` .

**getRewardForDuration**

```
getRewardForDuration() external override view returns (uint256)
```

Calculates the FXS reward for a given `rewardsDuration` period.

## Mutative Functions

**stake**

```
stake(uint256 amount) external override nonReentrant notPaused updateReward(msg.sender)
```

Stakes some Uniswap liquidity pool tokens. These tokens are freely withdrawable and are only boosted by the `crBoostMultiplier()`**.**

**stakeLocked**

```
stakeLocked(uint256 amount, uint256 secs) external nonReentrant notPaused updateReward(msg.sender)
```

Stakes some Uniswap liquidity pool tokens and also locks them for the specified `secs` . In return for having their tokens locked, the staker's base `amount` will be multiplied by a linear time-based multiplier, which ranges from 1 at `secs` = 0 to  `locked_stake_max_multiplier` at `locked_stake_time_for_max_multiplier`**.** The staked value is also multiplied by the `crBoostMultiplier()` . This multiplied value is added to `_boosted_balances` and acts as a weighted amount when calculating the staker's share of a given period reward.

**withdraw**

```
withdraw(uint256 amount) public override nonReentrant updateReward(msg.sender)
```

Withdraw unlocked Uniswap liquidity pool tokens.

**withdrawLocked**

```
withdrawLocked(bytes32 kek_id) public nonReentrant updateReward(msg.sender)
```

Withdraw locked Uniswap liquidity pool tokens. Will fail if the staking time for the specific `kek_id` staking lot has not elapsed yet.

**getReward**

```
getReward() public override nonReentrant updateReward(msg.sender)
```

Claim FXS rewards.

**exit**

```
exit() external override
```

Withdraw all unlocked pool tokens and also collect rewards.

**renewIfApplicable**

```
renewIfApplicable() external
```

Renew a reward period if the period's finish time has completed. Calls `retroCatchUp()` .

**retroCatchUp**

```
retroCatchUp() internal
```

Renews the period and updates `periodFinish` , `rewardPerTokenStored` , and `lastUpdateTime` .

## Restricted Functions

**notifyRewardAmount**

```
notifyRewardAmount(uint256 reward) external override onlyRewardsDistribution updateReward(address(0))
```

This notifies people (via the event `RewardAdded` ) that the reward is being changed.

**recoverERC20**

```
recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner
```

Added to support recovering LP Rewards from other systems to be distributed to holders.

**setRewardsDuration**

```
setRewardsDuration(uint256 _rewardsDuration) external onlyOwner
```

Set the duration of the rewards period.

**setLockedStakeMaxMultiplierUpdated**

```
setLockedStakeMaxMultiplierUpdated(uint256 _locked_stake_max_multiplier) external onlyOwner
```

Set the maximum multiplier for locked stakes.

**setLockedStakeTimeForMaxMultiplier**

```
setLockedStakeTimeForMaxMultiplier(uint256 _locked_stake_time_for_max_multiplier) external onlyOwner
```

Set the time, in seconds, when the locked stake multiplier reaches `locked_stake_max_multiplier` .

**setLockedStakeMinTime**

```
setLockedStakeMinTime(uint256 _locked_stake_min_time) external onlyOwner
```

Set the minimum time, in seconds, of a locked stake.

**setMaxCRBoostMultiplier**

```
setMaxCRBoostMultiplier(uint256 _max_boost_multiplier) external onlyOwner
```

aaa

**initializeDefault**

```
initializeDefault() external onlyOwner
```

Intended to only be called once in the lifetime of the contract. Initializes `lastUpdateTime` and `periodFinish` .

## Modifiers

**updateReward**

```
updateReward(address account)
```

Calls `retroCatchUp()` , if applicable, and otherwise syncs `rewardPerTokenStored` and `lastUpdateTime` . Also, syncs the `rewards` and `userRewardPerTokenPaid` for the provided `account` .


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.frax.finance/frax-v1-original/staking.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
