# Staking

## Overview.

The [uos.finance](https://universal-operating-system.gitbook.io/universal-operating-system/tokenomics/www.uos.finance) staking application is a decentralized protocol that allows users to stake their liquidity provider (LP) tokens to earn rewards in the form of $uOS tokens. The system is built on Ethereum-compatible networks and implements a flexible rewards distribution mechanism.

### Smart Contract Architecture

#### Core Components

1. **StakingRewards Contract**
   * Main contract handling staking operations and rewards distribution
   * Implements OpenZeppelin's Ownable and ReentrancyGuard for security
   * Manages two token types:
     * Staking Token (LP tokens)
     * Rewards Token (uOS)

#### Key Features

**Staking Mechanism**

* Users can stake their LP tokens using the `stake(uint256 amount)` function
* Staked tokens arent locked and can be withdrawn everytime
* Users can withdraw their staked tokens at any time using `withdraw(uint256 amount)`
* The `exit()` function allows users to withdraw all staked tokens and claim rewards in one transaction

**Rewards Distribution**

* Rewards are distributed over a configurable duration (default: 1 week)
* The reward rate is calculated based on the total amount of rewards and the duration
* Rewards are distributed proportionally to the amount of tokens staked
* Users can claim their earned rewards using the `getReward()` function

**Administrative Functions**

* Contract owner can:
  * Set new reward amounts using `notifyRewardAmount(uint256 reward)`
  * Adjust the rewards duration using `setRewardsDuration(uint256 _rewardsDuration)`
  * Recover accidentally sent tokens using `recoverERC20(address tokenAddress, uint256 tokenAmount)`

#### State Variables

* `rewardsToken`: Address of the token used for rewards (uOS)
* `stakingToken`: Address of the token that can be staked (LP tokens)
* `periodFinish`: Timestamp when the current rewards period ends
* `rewardRate`: Rate at which rewards are distributed
* `rewardsDuration`: Duration of the rewards period
* `lastUpdateTime`: Last time rewards were updated
* `rewardPerTokenStored`: Accumulated rewards per token
* `_totalSupply`: Total amount of tokens staked
* `_balances`: Mapping of user addresses to their staked amounts

#### Events

* `RewardAdded(uint256 reward)`: Emitted when new rewards are added
* `Staked(address indexed user, uint256 amount)`: Emitted when a user stakes tokens
* `Withdrawn(address indexed user, uint256 amount)`: Emitted when a user withdraws tokens
* `RewardPaid(address indexed user, uint256 reward)`: Emitted when rewards are paid to a user
* `RewardsDurationUpdated(uint256 newDuration)`: Emitted when the rewards duration is updated
* `Recovered(address token, uint256 amount)`: Emitted when tokens are recovered

### Frontend Integration

The staking application includes a React-based frontend that interacts with the smart contracts using wagmi hooks. Key components include:

#### Hooks

**useStakingRewards**

* Manages staking-related operations and state
* Provides functions for:
  * Checking LP token balances
  * Managing staking allowances
  * Viewing staked balances
  * Tracking earned rewards
  * Monitoring total LP tokens in staking

#### Contract Interactions

The frontend interacts with the following contract functions:

* `balanceOf`: Check user's staked balance
* `earned`: Calculate earned rewards
* `stake`: Stake LP tokens
* `withdraw`: Withdraw staked tokens
* `getReward`: Claim earned rewards
* `exit`: Withdraw all tokens and claim rewards

### Security Features

1. **Reentrancy Protection**
   * Implements OpenZeppelin's ReentrancyGuard
   * Prevents reentrancy attacks on critical functions
2. **Access Control**
   * Owner-only functions for administrative tasks
   * SafeERC20 implementation for token transfers
3. **Reward Rate Protection**
   * Checks to prevent reward rate overflow
   * Validates reward amounts against contract balance

### Deployment

The staking contract can be deployed to different networks with specific token addresses:

```javascript
// Base Network

stakingToken = "0x1cc5e366ec89b0ca2a30a4b4440c1b1c0b5fb466"; // vAMM-WETH/uOS
rewardsToken = "0xbE8728795b935bf6E2a9253Ce7a2Ef6fA831f51E"; // uOS

// Sepolia Testnet
stakingToken = "0x61bbA7C573248Cc3CcE194E9F48d8396f5A7A9A5"; // UNI-V2
rewardsToken = "0xffC8B69CB5AdD5Ea25E371eB531D9727bCc27d9C"; // uOS
```


---

# 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://universal-operating-system.gitbook.io/universal-operating-system/tokenomics/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.
