# 质押合约

⚠️ 本页面仅适用于非常早期的流动性挖矿池，尽管许多新农场共享功能和名称 ⚠️

基于 Synthetix 的质押合约：

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

### **描述**

Frax 用户能够在选定的 Uniswap 流动性池代币中质押，以换取 FXS 奖励。未来的池和激励措施可以由治理添加。

### **部署** <a href="#deployment" id="deployment"></a>

*流动性池代币（LP）*&#x20;

Uniswap FRAX/WETH LP: `0xFD0A40Bc83C5faE4203DEc7e5929B446b07d1C76`

Uniswap FRAX/USDC LP: `0x97C4adc5d28A86f9470C70DD91Dc6CC2f20d2d4D`

Uniswap FRAX/FXS LP: `0xE1573B9D29e2183B1AF0e743Dc2754979A40D237`

Uniswap FXS/WETH LP: `0xecBa967D84fCF0405F6b32Bc45F4d36BfDBB2E81`

*质押合约*&#x20;

Uniswap FRAX/WETH staking: `0xD875628B942f8970De3CcEaf6417005F68540d4f`

Uniswap FRAX/USDC staking: `0xa29367a3f057F3191b62bd4055845a33411892b6`

Uniswap FRAX/FXS staking: `0xda2c338350a0E59Ce71CDCED9679A3A590Dd9BEC`

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

## **状态变量**

```
FRAXStablecoin private FRAX
```

FRAX合约的实例。

```
ERC20 public rewardsToken
```

奖励代币的实例。

```
ERC20 public stakingToken
```

质押代币的实例。

```
uint256 public periodFinish
```

质押周期结束的区块。

```
uint256 public rewardRate
```

每秒最大奖励。

```
uint256 public rewardsDuration
```

奖励周期，以秒为单位。

```
uint256 public lastUpdateTime
```

合约最后一次更新或状态改变的时间戳。

```
uint256 public rewardPerTokenStored
```

当前周期内每个代币的实际奖励。

```
uint256 public locked_stake_max_multiplier
```

锁定质押的最大提升/权重倍增器。

```
uint256 public locked_stake_time_for_max_multiplier
```

达到 `locked_stake_max_multiplier` 的时间（以秒为单位）。

```
uint256 public locked_stake_min_time
```

锁定质押的最低质押时间（以秒为单位）。

```
string public locked_stake_min_time_str
```

字符串版本为 `locked_stake_min_time_str`。

```
uint256 public cr_boost_max_multiplier
```

来自抵押比例（CR）的最大提升/权重乘数。这适用于锁定和未锁定的质押。

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

记录某个地址上次领取奖励的时间。如果他们在之后的某个时间领取奖励，他们将获得正确的奖励金额，因为 `rewardPerTokenStored` 是在不断变化的。

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

给定地址的当前奖励余额。

```
uint256 private _staking_token_supply
```

质押的池代币总量。

```
uint256 private _staking_token_boosted_supply
```

考虑了时间和CR加成的 `_staking_token_supply`。这不是实际的池代币数量，而是一个“加权分母”。

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

给定地址质押的池代币余额。

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

考虑了时间和CR加成的 `_balances`，类似于 `_staking_token_boosted_supply`。

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

提供给定地址的锁定质押批次列表。

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

一个锁定的质押“批次”。

## **查看函数**

**totalSupply**

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

获取质押的流动性池代币总数。

**stakingMultiplier**

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

根据质押的秒数获取基于时间的质押倍增器。

**crBoostMultiplier**

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

获取基于抵押比率（CR）的质押倍增器。

**stakingTokenSupply**

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

与 `totalSupply()` 相同。

**balanceOf**

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

获取给定账户质押的流动性池代币数量。

**boostedBalanceOf**

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

获取给定账户质押的流动性池代币的加成数量。加成考虑了抵押比率（CR）和基于时间的倍增器。

**lockedBalanceOf**

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

获取给定账户锁定的质押流动性池代币数量。

**unlockedBalanceOf**

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

获取给定账户解锁的/自由的质押流动性池代币数量。

**lockedStakesOf**

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

返回给定账户的所有锁定质押“批次”的数组。

**stakingDecimals**

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

返回 `stakingToken` 的小数位数 (`decimals()`)。

**rewardsFor**

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

获取给定账户的 FXS 奖励数量。

**lastTimeRewardApplicable**

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

在内部用于跟踪 `rewardPerTokenStored`。

**rewardPerToken**

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

当前质押流动性池代币的 FXS 奖励数量。

**earned**

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

返回给定账户的未领取 FXS 奖励数量。

**getRewardForDuration**

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

计算给定奖励持续时间（`rewardsDuration`）内的 FXS 奖励。

## **变更函数**

**stake**

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

质押一些 Uniswap 流动性池代币。这些代币可以自由提取，仅受 `crBoostMultiplier()` 的加成。

**stakeLocked**

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

质押一些 Uniswap 流动性池代币，并将其锁定指定的秒数。作为锁定代币的回报，质押者的基础金额将通过线性时间倍增器进行乘法计算，该倍增器在 `secs = 0` 时为 1，在 `locked_stake_time_for_max_multiplier` 时为 `locked_stake_max_multiplier`。质押的价值还会乘以 `crBoostMultiplier()`。这个乘积值会被加到 `_boosted_balances` 中，并在计算质押者在给定奖励周期中的份额时作为加权金额。

**withdraw**

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

提取解锁的 Uniswap 流动性池代币。

**withdrawLocked**

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

提取锁定的 Uniswap 流动性池代币。如果特定 `kek_id` 质押批次的质押时间尚未到期，则会失败。

**getReward**

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

零取 FXS 奖励。

**exit**

```
exit() external override
```

提取所有解锁的池代币并领取奖励。

**renewIfApplicable**

```
renewIfApplicable() external
```

如果奖励周期的结束时间已到，则续期奖励周期。调用 `retroCatchUp()`。

**retroCatchUp**

```
retroCatchUp() internal
```

续期并更新 `periodFinish`、`rewardPerTokenStored` 和 `lastUpdateTime`。

## **受限函数**

**notifyRewardAmount**

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

通过事件 `RewardAdded` 通知人们奖励正在被更改。

**recoverERC20**

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

添加此功能以支持从其他系统恢复流动性池奖励，并将其分发给持有者。

**setRewardsDuration**

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

设置奖励周期的持续时间。

**setLockedStakeMaxMultiplierUpdated**

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

设置锁定质押的最大倍增器。

**setLockedStakeTimeForMaxMultiplier**

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

设置锁定质押倍增器达到 `locked_stake_max_multiplier` 的时间（以秒为单位）。

**setLockedStakeMinTime**

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

设置锁定质押的最短时间（以秒为单位）。

**setMaxCRBoostMultiplier**

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

**initializeDefault**

```
initializeDefault() external onlyOwner
```

仅在合约生命周期中调用一次。初始化 `lastUpdateTime` 和 `periodFinish`。

## **修饰符**

**updateReward**

```
updateReward(address account)
```

调用 `retroCatchUp()`（如果适用），否则同步 `rewardPerTokenStored` 和 `lastUpdateTime`。此外，还会同步提供账户的奖励和 `userRewardPerTokenPaid`。
