> For the complete documentation index, see [llms.txt](https://betfin.gitbook.io/betfin-public/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://betfin.gitbook.io/betfin-public/smartcontracts-description/dynamic-staking.md).

# Dynamic Staking

### Overview <a href="#overview" id="overview"></a>

The **Dynamic Staking** contract is a sophisticated staking mechanism built on the Ethereum blockchain. It allows users to stake BET tokens in a dynamic environment where profits and losses are calculated over cycles. The contract supports creating new staking pools, staking tokens, withdrawing tokens, and distributing profits or losses.

<mark style="color:$warning;">Legacy dynamic pools are bridged via the DynamicPoolWrapper. This allows existing pools to continue providing reserves for house games while receiving a proportional share of new revenue.</mark>

**Note: Users cannot create new stakes in these pools. All new liquidity provision must be routed through the primary Liquidity Pool (V2).**

#### Key Features <a href="#key-features" id="key-features"></a>

* **Dynamic Staking Pools:** Supports the creation of new pools for staking tokens.
* **Profit and Loss Calculation:** Calculates profits and losses at the end of each cycle and distributes them accordingly.
* **Invitee Staking:** Tracks the total stakes made by invitees of a staker.
* **Non-Reentrant:** Ensures that functions cannot be re-entered, mitigating potential security risks.
* **Access Control:** Utilizes roles for managing permissions within the contract.

#### Key Components <a href="#key-components" id="key-components"></a>

<table><thead><tr><th width="244">Component</th><th>Description</th></tr></thead><tbody><tr><td><strong>ERC20 Token</strong></td><td>The contract interacts with ERC20 tokens for staking and rewards.</td></tr><tr><td><strong>DynamicStakingPool</strong></td><td>Represents each staking pool within the contract.</td></tr><tr><td><strong>Core</strong></td><td>The core logic for token management and access control.</td></tr><tr><td><strong>Calculation Window</strong></td><td>A predefined time window for calculating profits/losses and distributing them.</td></tr></tbody></table>

Users can stake tokens by invoking the `stake` function. The amount to be staked must be greater than or equal to the minimum allowed amount.

`function stake(address staker, uint256 amount) external onlyRole(CORE) nonReentrant`

**Requirements:**

* Not within the calculation window (`DS04` error).
* The amount is at least the minimum allowed amount (`DS01` error).
* The amount is divisible by 2 (`DS09` error).

#### Withdraw Tokens <a href="#withdraw-tokens" id="withdraw-tokens"></a>

Tokens can be withdrawn from a pool by calling the `withdraw` function. This is only allowed during the calculation time and if the pool is fully distributed.

`function withdraw(address pool) external`

**Requirements:**

* Must be calculation time (`DS03` error).
* Pool must be active and successfully distributed in the current cycle (`DS08`, `DS10`, `DS11` errors).

#### Calculate Profit or Loss <a href="#calculate-profit-or-loss" id="calculate-profit-or-loss"></a>

This function calculates and distributes the profit or loss for each cycle. It must be called at least once per cycle based on the active pool count.

`function calculateProfit(uint256 offset, uint256 count) external nonReentrant`

**Requirement:**

* Must be calculation time (`DS03` error).

#### Reserve Funds <a href="#reserve-funds" id="reserve-funds"></a>

Allows game contracts to reserve funds from the staking contract.

`function reserveFunds(uint256 amount) external onlyRole(GAME)`

**Requirements:**

* Not within the calculation window (`DS04` error).
* Sufficient balance to reserve (`DS06` error).

#### Adjust Settings <a href="#adjust-settings" id="adjust-settings"></a>

The contract allows adjusting the minimum allowed staking amount and the calculation window through the following functions, controlled by the `TIMELOCK` role.

* `setMinAllowedAmount(uint256 _amount)`: Adjusts the minimum staking amount.
* `setCalculatingWindow(uint256 _window)`: Adjusts the calculation window.

#### Events <a href="#events" id="events"></a>

Various events are emitted for tracking activities within the contract, such as `PoolOpened`, `PoolClosed`, `Staked`, `Withdraw`, `NewMinAllowedAmount`, and `NewCalculationWindow`.

### Conclusion <a href="#conclusion" id="conclusion"></a>

The **Dynamic Staking** smart contract introduces a flexible and dynamic approach to staking on the Ethereum blockchain. By leveraging calculation cycles, dynamic pools, and robust access control, it offers a comprehensive staking solution for users.
