# Smart Contract

{% embed url="<https://github.com/stacks-degens/de-stacking>" %}

## Stacking Pool Smart Contract Flow

Because of the Liquidity Provider role in the project, no user has access to the funds or rewards of the others. The rewards are sent to the liquidity provider. He already locked an amount of STX in the smart contract which should be more than the amount that will be rewarded in that cycle. When the liquidity provider is rewarded an amount, the pool's smart contract can check what amount was he rewarded and give the equivalent to the participants of the pool, according to AlexGo STX-xBTC exchange rate.The smart contract keeps track of who stacked through it in the current cycle and the rewards are distributed according to the amount each user stacked. The liquidity &#x20;

When the Stacking Pool Smart Contract is deployed, the deployers become the **liquidity provider** of the Smart Contract. The liquidity provider’s main job inside the pool is to provide liquidity in order to ensure the future pool participants that the reward according to each participant’s weight is safely covered in advance.

Note: Initially, a ***1k*** STX minimum amount is set and it may be modified before deployment changing the `minimum-deposit-amount-liquidity-provider` variable’s value.

Note: Initially, a **return-div** value of **20** (meaning the liquidity provider is ready to support a **5%, or** ***20***^(-1) return of the locked sum). We suggest this variable to be a **maximum** of **20** (the liquidity provider should support a minimum of 5%).

### Remarkable constants

* `PREPARE_CYCLE_LENGTH` → one prepare cycle’s length according to the pox-2 contract
* `REWARD_CYCLE_LENGTH` → one cycle’s length according to the pox-2 contract

### Remarkable variables

* `sc-total-balance` → total amount of microSTX (STX \* 10^-6) inside the Smart Contract
* `sc-owned-balance` → total amount of microSTX which is not reserved for future rewards
* `sc-reserved-balance` → total amount of microSTX reserved for future stackers’ rewards
* `sc-delegated-balance` → total amount delegated by users for the current reward cycle
* `sc-locked-balance` → total amount locked by the pool on behalf of users for the current cycle
* `return-div` → the uint number we have to divide the `sc-locked-balance` in order to calculate the return
* `stackers-list` → the list of stackers who participate in the stacking pool
* `liquidity-provider`
* `minimum-deposit-amount-liquidity-provider` → minimum amount for the liquidity provider to transfer after deploy in microSTX
* `pool-pox-address` → the `liquidity-provider`’s reward Bitcoin address

### Deployer first steps

After the deployer publishes the Smart Contract, he has to deposit funds into the Smart Contract. To ensure the stackers that their rewards are fully covered, the deposited funds need to be reserved inside the Smart Contract.

Steps:

1. deploy the Smart Contract
2. call `deposit-stx-liquidity-provider` function to deposit Stacks into the Smart Contract
3. call `reserve-funds-future-rewards` function in order to lock the funds so the expected reward is covered and locked for the stackers

### Participant steps

As a participant, the first requirement to stack in a pool is to allow the desired pool contract caller to perform operations inside the pox-2 contract. After this, the stacker can join the stacking pool in order to delegate STX to the stacking pool.

Steps:

1. call **pox-2** contract `allow-contract-caller` function providing the arguments:
   * Smart Contract address: principal
   * until burn height: optional uint (e.g. none / some u4200)
2. call `join-stacking-pool` function
3. call `delegate-stx` function in order to delegate funds and authority to the Smart Contract
   * arguments:
     * amount in micro STX: uint
   * this function will also:
     * lock ***the maximum amount the user owns***, lower or equal to the ***delegated amount***
     * ***extend*** the lock period if necessary
     * ***increase*** the delegated and the locked amount for a user if the provided amount is greater than the previously delegated one

### Revoking a delegation as a stacker and quitting the pool

When one stacker wants to quit the stacking pool, or just to revoke the delegation temporarily, he has to first disallow the pool contract caller, then revoke the delegation or directly quitting the pool.

Steps:

1. call **pox-2** contract `disallow-contract-caller` function providing the argument:
   * caller: principal
2. call `revoke-delegate-stx` function to revoke the delegation (if the stacker wants to also quit the stacking pool, he can directly jump to the 3rd step)
3. call `quit-stacking-pool`

### Recalculating contract balances every Prepare Phase

This is a **REALLY IMPORTANT** step of the whole stacking process. It establishes the contract balances (`locked-balance`, `delegated-balance`) and based on this, calculates stackers’ weights inside the pool for the prepare phase’s corresponding reward cycle. Not calling this function would make the **reward distribution for that specific reward cycle impossible**!

1. call `update-sc-balances`
   * NOTE: have to be called during the ***first half of the prepare phase***, otherwise an error will be returned. That is the proper moment when a recalculation has to happen.
   * this function will also calculate the participants’ weights inside the pool
   * based on the calculated weights, the participants will receive their cut of the total pool’s reward

### Reward Distribution

At the moment of the rewards distribution, the **Smart Contract balance should have been updated** and the **stackers' weights calculated**. This function is responsible for:

* checking if the block provided as an argument was won by the pool
* checking if the block provided wasn’t rewarded before
* transferring the rewards to all the stackers corresponding to their weight inside the pool

Steps:

1. call `reward-distribution` function providing the argument:
   * rewarded-burn-block: uint → the height of the Bitcoin block for which the reward should be calculated and transferred

### Liquidity provider recalling extra funds and withdrawing STX

As the liquidity provider could have deposited more funds than necessary, he may recall the extra balance and switch it from **reserved** to **owned** inside the Smart Contract. This step will make the actual **withdrawal possible** for the liquidity provider. The extra amount is calculated inside the Smart Contract and the equation used grants that the remaining reserved funds cover the return the liquidity provider has ensured the stackers with (a minimum of 5% described above).

1. call `unlock-extra-reserved-funds`
   * this will make sure all the liquidity provider’s `return` is covered and the difference can be removed safely from the in-contract `reserved-balance` and added to the contract’s `owned-balance`
2. call `withdraw-stx-liquidity-provider`
   * arguments:
     * amount: uint
   * this will transfer funds from the pool contract to the liquidity provider if there are enough funds


---

# 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.degenlab.io/decentralized-stacking-pool/smart-contract.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.
