# 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.


---

# 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://betfin.gitbook.io/betfin-public/smartcontracts-description/dynamic-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.
