DePool

## What DePool is?

DePool is a Smart Contract / Smart\_contracts which is used in the free TON ecosystem to create investment pools in stakes that are returned with an interest after a certain time.

## How does It Work?

To check the validity of each block to be written on-chain there are nodes of the network (validators) that perform this task and are remunerated. Validators can use the DePool contract to create associations between them with the aim of increasing the decentralization, use and reputation of the blockchain.
Any blockchain user can become a validator but must invest a substantial amount of tokens. These validators ' stakes are paid as a guarantee of their good faith in the validation process and may be forfeited, in whole or in part, if they fail to properly apply the protocols to reach consent for validation.
Free Ton's proof of Stake (PoS) protocol does not require the implementation and use of complicated hardware architectures and allows each investor in a DePool to obtain significant rewards without having to be a validator.

## Comparison with other blockchains

Wanting to make some comparative considerations with other blockchains that use smart contracts, some significant differences in terms of decentralization and performance appear evident. POW (Proof of Work) networks such as Bitcoin and Ethereum, still suffer from the big problems regarding the centralization of mining and hashrate, respectively. The applications released on these networks create congestion and exponential increase in the costs, in GAS, of operations. This does not happen in a free TON environment since DePool runs on basechain, not congesting the workchain and taking advantage of lower costs for operations

## Not just decentralized finance

Another use case of the DePool contract that is currently under consideration by the developer community concerns the governance of the Free TON ecosystem itself. A contest will be promoted between all Free TON users to develop a software resource that, through the use of the DePool contract, can guarantee a process of evaluation and management in the same community.
From the words of Mitya Goroshevsky, technical director of TON Labs:
“We can think of the contest as a block of the chain, the participations in the contest as the transactions and the judges as the validators" “
In this perspective we have all the necessary figures to apply the DePool contract to the choice of judges and to the evaluation of their work. They will be interested in acting correctly because they will risk their quotas and subject themselves to the judgment of the community through the work of fishermen, literally fishermen, who want to carry out audits of judgments, risking their quotas too.

## DePool and decentralization

The DePool smart contract is of particular importance in the free TON ecosystem, which, at this moment, already counts on the active participation of about 400 validator servers, having achieved, in fact, a great goal in view of the decentralization of the governance.
Soon, each Free TON user will have the power to use their tokens to cast their vote by actively taking part in the governance, as an individual staking investor or as a validator, also being able to choose to partner with other validators to increase decentralization, support for network nodes and network reputation.
The free TON blockchain supports several high level languages, such as C / C++ and Solidity, and provides developers with many tools to measure the pulse of their on-chain applications. TON.live, TON SDK and TestSuite4, for example, are powerful tools for programming and debugging. It is an Open Source environment and software solutions are being studied that allow to adequately remunerate the developers with a part of the validators ' stake revenues.

## Terminology

**Elector** — system-level smart contract deployed in the masterchain from zero state. Periodically elects a validator.

**DePool Proxy** (proxy) — smart contract that delivers messages between DePool and Elector.

**Participant** — smart contract investing in DePool.

**Validator** — software that launches a blockchain node. Each DePool works with only one node, which must be a participant of the DePool.

**Validator's wallet** — smart contract that is used by the validator to send selective requests to DePool and receive the validator's reward. The validator's wallet must be a Multisig contract with 3 custodians.

**DePool Helper** — smart contract that stores the address of the current DePool contract and works with the Timer contract.

**Global Validators Set (GVS)** — the current list of validators selected in the last election.

**Validation period** — the time period for which the GVS is elected.

**Investment round** — the period of time between a Participant's investing a stake in DePool and receiving it back (with or without interest).

**Timer** — smart contract that can periodically call other smart contracts.

## DePool architecture

1. DePool is designed to receive investment stakes from the Participants, distribute pool funds to the validator to participate in the GVS elections and, after the end of the validation cycle, distribute stakes with certain rewards back to the Participants.
2. DePool is deployed to basechain. But it cannot directly interact with Elector, because Elector rejects messages from non-masterchain contracts. In this way, there are DePool proxies that deploy to the masterchain and deliver messages from DePool to Elector and back. It is also important that the fee for gas and storage in the basechain is 10 times less than in the masterchain.
3. DePool is open to Participants' stakes at any time, however there is a deadline for participation in the upcoming elections. The term depends on the Elector timer. After the specified period, the incoming stakes will be accumulated for participation in the next elections.
4. DePool distinguishes stakes, received before the deadline and after the deadline, so it stores information about the stakes players in individual **investment rounds**, one for each election in order to facilitate the subsequent distribution of stakes and awards. To distribute the communication with Elector, DePool uses 2 proxies: one for even rounds and one for odd rounds.
5. To call DePool used contract Timer. DePool Helper asks Timer to call it periodically and passes each call from Timer to DePool. The interval between calls is selected according to the selection interval.
6. DePool must be linked to the validator's wallet in order to participate in elections on behalf of the latter. This validator wallet address is specified during DePool deployment and cannot be changed afterwards. When an election starts, DePool waits for signed election requests from the linked wallet, then attaches the round's stake to the request and passes it to Elector.
7. A validator can validate multiple DePools using 1 validator wallet. The reputation of the Validator's wallet is available and, over time, can be analyzed.
8. In order for the validator to correctly perform its functions (it was always online and did not "lie" to other validators), the validator's wallet must become a Participant and invest in each round of investments at least **20%** of the minimum total stake of the round (**minRoundStake**), which is initialized in the DePool constructor.
9. When Elector unfreezes validator stakes, DePool returns its stake with round rewards. Some of these rewards (**25%**) go to the balance of the Validator's wallet, which can be withdrawn from the wallet at any time. The other part (**5%**) goes to DePool itself to cover gas and storage fees. And the last part (**70%**) is distributed among all Participants of the investment round. All these parts are initialized when DePool is deployed.
10. DePool keeps the balance of each Participant and can automatically reinvest the Participant's stake in the last investment round if the corresponding flag is set.
11. A Participant can transfer part of his common stake to another Participant's stake in the DePool storage. This feature allows you to ensure the liquidity of the stakes.

## Special types of stakes

Along with the basic regular stake, which functions according to the rules described above, there are two types of specialty stakes: Vesting and Lock.

### Vesting stake

Stake is broken into pieces. Each of the next part of the stake is made available to the validator only after the next transition. At the stage of completion of each round, DePool decides how many pieces of stake should be unlocked and subtracted from the stake and will be available to the validator.

Example: address A makes a 120 TON stake for 1 year with a period of 1 month and designates address B as the recipient of the stake. This means that after 1 month, 10 TONs become available for address B, and 110 TONs are still blocked in the round. After 1 year, the vesting stake will be 0, and the last 10 TONs will become available to the validator.

### Lock stake

Funds (whole stake) are locked in DePool for a certain period. At the end of the period, the blocked stake is returned. Lock stake cannot be divided, moved, or voted on.

One participant can only own one Vesting Stake and one Lock Stake. When a stake of any of these types is created, it is divided equally into the last two rounds, which means that the minimum value for such a stake is 2 \* minStake + commission.

## Specification

### Data structure

The DePool contract uses a library and inherits from a few simple base pins to separate functions and make it easier to develop and debug the contract. Contains the following data:

`DePoolLib.sol`

```
 // Describes contract who deposits stakes in DePool
    struct Participant {
        // Quantity of rounds in which participant takes a part
        uint8 roundQty;
        // Sum of all rewards from completed rounds (for logging)
        uint64 reward;
        // Flag whether participant has a vesting stake.
        bool haveVesting;
        // Flag whether participant has a lock stake.
        bool haveLock;
        // Flag whether to reinvest ordinary stakes and rewards
        bool reinvest;
        // Target tons that will be transferred to participant after rounds are completed.
        // After each round this value is decreased
        uint64 withdrawValue;
    }

    // Request for elections from validator wallet.
    struct Request {
        // Random query id.
        uint64 queryId;
        // Validator's public key that will be used as validator key if validator will win elections.
        uint256 validatorKey;
        // current election id.
        uint32 stakeAt;
        // Validator's stake factor.
        uint32 maxFactor;
        // Validator's address in adnl overlay network.
        uint256 adnlAddr;
        // Ed25519 signature of above values.
        bytes signature;
    }

```

`DePoolRounds.sol`

```
 // Describes vesting or lock stake
    struct InvestParams {
        // Flag whether this stake was invested
        bool isActive;
        // Size of vesting/lock stake
        uint64 amount;
        // Unix time in seconds of the last payment
        uint64 lastWithdrawalTime;
        // Period in seconds after which `withdrawalValue` nanotons are unlocked
        uint32 withdrawalPeriod;
        // Amount of nanotons which are unlocked after `withdrawalPeriod` second
        uint64 withdrawalValue;
        // Address of creator of vesting/lock
        address owner;
    }

    // Describes different stakes, that participant gets reward from
    struct StakeValue {
        // Size of usual stake
        uint64 ordinary;
        // Optional vesting and lock stakes
        optional(InvestParams) vesting;
        optional(InvestParams) lock;
    }

    // Investment round information
    struct Round {
        // Sequence id (0, 1, 2, ...)
        uint64 id;
        // Supposed time of validation start (Real time can be greater. Elections could be postponed)
        uint32 supposedElectedAt;
        // Time when stake will be unfreezed. Set when validation phase is ended
        uint32 unfreeze;
        // Round step
        RoundStep step;
        // Status code why round is completed.
        CompletionReason completionReason;
        // Number of participants in round.
        uint32 participantQty;
        // Round total stake
        uint64 stake;
        // Participant's stakes in round
        mapping(address => StakeValue) stakes;
        // Round rewards
        uint64 rewards;
        // Request from validator
        DePoolLib.Request validatorRequest;
        // Address of elector
        address elector;
        // Hash of validation set (config param 34) when round was in election phase
        uint256 vsetHashInElectionPhase;
        // Address of proxy used to interactive with elector
        address proxy;

        // Unixtime when round was created (just for logging)
        uint32 start;
        // Unixtime when round switched to step Completing (just for logging)
        uint32 end;
        // Unused stake cut-off by elector (just for logging)
        uint64 unused;
    }

    // m_rounds[m_roundQty - 1] - pooling
    // m_rounds[m_roundQty - 2] - election or validation
    // m_rounds[m_roundQty - 3] - validation or investigation
    mapping(uint64 => Round) m_rounds;

    // Quantity of created rounds
    uint64 m_roundQty = 0;

    // This is round struct without some fields. Used in get-methods for returning round information.
    struct TruncatedRound {
        uint64 id;
        uint32 supposedElectedAt;
        uint32 unfreeze;
        RoundStep step;
        CompletionReason completionReason;
        uint32 participantQty;
        uint64 stake;
        uint64 rewards;
        uint64 unused;
        uint64 start;
        uint64 end;
        uint256 vsetHash;
    }

```

`DePoolBase.sol`

```
// Dictionary of participants for active rounds.
    mapping (address => DePoolLib.Participant) m_participants;

    // Address of the validator wallet
    address m_validatorWallet;

    // Array of proxies addresses.
    address[] m_proxies;

```

`DePool.sol`

```
  // Indicates that pool is closed. Closed pool doesn't accept stakes from other contracts.
    bool m_poolClosed;

    // Min stake accepted to the pool in nTon (for gas efficiency reasons): 10 tons is recommended.
    uint64 m_minStake;

    // Minimum round total stake
    uint64 m_minRoundStake;

    // DePool annual interest, this value is recalculated after each round with reward.
    uint64 m_lastRoundInterest;

```

### DePool initialization

On deployment, the DePool constructor is called with the following parameters:

```
constructor(
        uint64 minRoundStake,
        address proxy0,
        address proxy1,
        address validatorWallet,
        uint64 minStake
    )
        ValidatorBase(validatorWallet)
        ProxyBase(proxy0, proxy1)
        public;

```

1. `minRoundStake` — the minimum value for the sum of all stakes in a round. If less - stakes can be reinvested in the next round;
2. `proxy0, proxy1` — proxy addresses;
3. `validatorWallet` — wallet address of the validator linked to DePool;
4. `minStake` — the minimum stake that the Participant can send to DePool.

### Participant functions

DePool stores each Participant's stake in a dictionary (`m_participants`), where the key is the participant's address and the value is the participant's structure.

Participant functions perform checks and, in case of failure, send a `receiveAnswer` message to the caller with an error code and comment. If all conditions are met, DePool sends an acknowledgment message (`receiveAnswer` with status 0) back to the caller.

All functions can only be called by internal messages.

1. `addOrdinaryStake (bool reinvest)` - allows you to make a regular stake in the current round of the pool. The original address of the message is taken as the participant's address. The total stake of the Participant is increased by the amount (`msg.value- ADD_STAKE_FEE`).

Parameters:

* reinvest — reinvestment flag.

The function checks that:

* value of the incoming message ≥ (m\_minStake + ADD\_STAKE\_FEE);
* pool is not closed (m\_poolClosed ≠ true).

2. `addVestingStake (address beneficiary, uint32 withdrawalPeriod, uint32 totalPeriod)` — add a Vesting stake for the validator.

Parameters:

* `beneficiary` — validator address;
* `withdrawalPeriod` — the period in seconds after which the next part of the stake is unlocked;
* `totalPeriod` — total period in seconds.

The function checks that:

* `beneficiary` — is `addr_std`. If it is zero, the `beneficiary` is set to `msg.sender`;
* incoming `msg.value` ≥ (`m_minStake` + `ADD_STAKE_FEE`);
* pool is not closed (`m_poolClosed` ≠ true);
* `withdrawalPeriod` ≠ 0;
* `withdrawalPeriod` ≤ totalPeriod;
* `totalPeriod` % `outputPeriod` = 0;
* `totalPeriod` < 18 years;
* stake / (`totalPeriod` / `withdrawalPeriod`) ≠ 0;
* `beneficiary` has no vesting stake.

3. `addLockStake(address beneficiary, uint32 withdrawalPeriod, uint32 totalPeriod)` — adding a Lock stake.

Has the same parameters and checks as addVestingStake.

4. `removeOrdinaryStake (uint64 removewValue)` — allows you to remove the Participant's stake from the current round.

Parameters:

* `withdrawValue` — the desired amount of stake to be removed.

The function checks that:

* incoming `msg.sender` address — is the address of an existing participant;
* value `msg.value` ≥ REMOVE\_ORDINARY\_STAKE\_FEE;
* pool is not closed (`m_poolClosed` ≠ true).

If the remaining stake in the round is less than `m_minStake`, then the entire stake is transferred to the Participant.

If the Participant's remaining total stake is 0, it is removed from the dictionary `m_stakeholder`.

5. `withdrawPartAfterCompleting(uint64 withdrawValue)` — allows the Participant to schedule the withdrawal of a portion of the stake.

Parameters:

* withdrawValue — the desired amount of stake.

The function checks that:

* incoming `msg.sender` address — is the address of an existing participant;
* value `msg.sender` ≥ WITHDRAW\_PART\_AFTER\_COMPLETING\_FEE;
* pool is not closed (`m_poolClosed` ≠ true).

If the remaining stake in the round is less than `m_minStake`, then the entire stake is transferred to the Participant.

If the Participant's remaining total stake is 0, it is removed from the dictionary `m_stakeholder`.

6. `withdrawAllAfterCompleting(bool doWithdrawAll)` — allows the Participant to set a flag, which means that DePool should return the Participant's stake after the round ends.

The function checks that:

* incoming `msg.sender` address — is the address of an existing participant;
* value `msg.sender` ≥ WITHDRAW\_ALL\_AFTER\_COMPLETING\_FEE;
* pool is not closed (`m_poolClosed` ≠ true).

After translation of the entire stake, the Participant will be removed from the m\_stakeholder dictionary.

7. `transferStake(address dest, uint64 amount)` — allows you to transfer a stake from the Participant (`msg.sender`) to the Participant (`dest`) inside the DePool storage.

The function checks that:

`msg.sender` ≠ `dest`; incoming `msg.sender` address — is the address of an existing participant; `destination` — nonzero value addr\_std; value `msg.value` ≥ TRANSFER\_STAKE\_FEE; pool is not closed (`m_poolClosed` ≠ true); the desired (`amount`) can be transferred, and the transfer does not leave a stake less than m\_minStake.

If successful, DePool sends a notification by calling the `onTransfer`function.

### Callback-functions of the participants

These functions are called DePool to send notifications to the Participant.

1. `receiveAnswer (uint32 errcode, uint64 comment)` — a function that is called as a response from DePool to the Participant.

```
    uint8 constant STATUS_SUCCESS                                        =  0;
    uint8 constant STATUS_STAKE_TOO_SMALL                                =  1;
    uint8 constant STATUS_DEPOOL_CLOSED                                  =  3;
    uint8 constant STATUS_ROUND_STAKE_LIMIT                              =  4;
    uint8 constant STATUS_MSG_VAL_TOO_SMALL                              =  5;
    uint8 constant STATUS_NO_PARTICIPANT                                 =  6;
    uint8 constant STATUS_NO_TRANSFER_WHILE_PENDING_ROUND                =  8;
    uint8 constant STATUS_PARTICIPANT_HAVE_ALREADY_VESTING               =  9;
    uint8 constant STATUS_WITHDRAWAL_PERIOD_GREATER_TOTAL_PERIOD         = 10;
    uint8 constant STATUS_TOTAL_PERIOD_MORE_18YEARS                      = 11;
    uint8 constant STATUS_WITHDRAWAL_PERIOD_IS_ZERO                      = 12;
    uint8 constant STATUS_TOTAL_PERIOD_IS_NOT_DIVED_BY_WITHDRAWAL_PERIOD = 13;
    uint8 constant STATUS_PERIOD_PAYMENT_IS_ZERO                         = 14;
    uint8 constant STATUS_REMAINING_STAKE_LESS_THAN_MINIMAL              = 16;
    uint8 constant STATUS_PARTICIPANT_HAVE_ALREADY_LOCK                  = 17;
    uint8 constant STATUS_TRANSFER_AMOUNT_IS_TOO_BIG                     = 18;
    uint8 constant STATUS_TRANSFER_SELF

```

* comment — error content.

2. `onTransfer (source addresses, the amount of uint128)` — a function that is called after a successful `transferStake` to inform the receiving Participant.

Arguments:

* `source` — sender Participant;
* `amount` — transaction amount.

3. `onRoundComplete (uint64 roundId, uint64 reward, uint64 normalStake, uint64 vestingStake, bool reinvest, uint8 reason)` — called to send a notification from DePool to the Participant at the end of the round:

* `roundId` — round identifier (Unix-start time of the set of validators selected in this round);
* `reward` — participant's reward in the round (in nanoTONs). Can be 0 if the round ends without participation and victory in the elections;
* `ordinaryStake` — regular stake invested in the next round (nanotokens) with `rewards` rewards minus the `fee`;
* `vestingStake` — vesting stake nested in the next round;
* `reinvest` — flag indicating whether the stake was added to the last round or transferred back;
* `reason` — status code, reason for the end of the round.

### Developments

* `dePoolPoolClosed ()` — the event generated when the pool is closed.
* `roundStakeIsAccepted (uint64 queryId, uint32 comment)` — event generated when the Elector takes stake.
* roundStakeIsRejected (uint64 queryId, uint32 comment) — event generated when the Elector rejects stake.
* `RoundCompleted (TruncatedRound round)` — an event generated when a round ends.
* `stackSigningRequested (uint32 selectionId, address proxy)` — an event generated when the round switches to the STEP\_WAITING\_REQUESTS step, indicating that DePool is waiting for a signed election request from the validator wallet.

### Get methods

* `getParticipantInfo (address addr)` — returns information about the Participant in all investment rounds.
* `getDePoolInfo ()` — returns parameters and constants of the DePool configuration.
* `getRounds ()` — returns information about all rounds (step, total stake, number of stakeholders, round ID).

DePool does not store the public keys of the validator or ADNL address because, according to the official TON guideline, the validator generates a new key pair and ADNL for every election. Only the validator's wallet address is stored in the contract.

### Function status updates

`ticktock()` does the following:

* if necessary, creates a new round and removes old;
* updates the `supposedElectedAt` ID of the last active round (that is, the round in which stakes are accepted) after the start of the current round of elections;
* switches the steps of active rounds and calls various internal functions if certain conditions are met, that is, it sends requests for elections to Elector, receives responses and rewards from Elector, etc.

Provides a multi-stage flow with a new active round accepting stakes after the start of validator elections.

To improve storage efficiency, the `ticktock` function has implemented an investment round queue to store only the last 3 active rounds in the DePool storage.

`ticktock()` does not accept external incoming messages and can only be called from other contracts.

### Elections in several rounds at the same time

DePool can have 3 concurrently active **investment rounds** that have a minimum total stake, which are set in the DePool constructor when the contract is deployed.

**Pay attention** that our model uses the following round naming convention: last round, last but one (lb1 - last but one) round, and oldest round. After the last round is completed, it is deleted and a new one is created. The entire sequence moves accordingly. Each round takes place in several stages:

1. Initial (RoundStep.Pooling) - the round is ready to receive stakes from the Participants.

2. "Waiting for Elector's request" step (RoundStep.WaitingValidatorRequest) - the round switches to this step when the validator elections begin. The round is waiting for a signed election request from the validator wallet. See the `process_new_stake` function in Elector to correctly generate an election request.

**Important:** the validator's wallet must also be a Participant and invest a stake in the round. The minimum threshold for this stake is 0.2 \*`m_minRoundStake`. The investment round will not participate in the election if the minimum stake condition is not met and will switch to the "WaitingUnfreeze" stage.

3. "Waiting for stake acceptance" (RoundStep.WaitingIfStakeAccepted) - the Validator's wallet called the function `ParticipInElections` and a request for elections was received. DePool (`ParticipationInElections`) attaches the round stake to the request and passes it to Elector, and then waits for a response. Elector calls the DePool function `onStakeAccept`, if the election request is accepted successfully, or `onStakeReject` in case of an error.

4. "Waiting for the start of validation" (RoundStep.WaitingValidationStart) - the onStakeAccept call means that our stake has been accepted. The validator became a candidate. Now the DePool is waiting for the start of validation to find out if our validator won the election.

5. "Waiting for election results" (RoundStep.WaitingIfValidatorWinElections) - the round switches to this step after the election is over. DePool checks the result of the election by calling the Elector function `recover_stake` (with `queryId` = 0). If the validator wins the election, Elector freezes its stake, and `recover_stake` returns an error (message with operation ID 0xfffffffe in the body) or returns the unused portion of the stake back to DePool (unused stake <accepted stake>). If the validator loses the election, Elector returns the total accepted stake.

6. "Waiting for stack unfreeze" (RoundStep.WaitingUnfreeze) - DePool waits for Elector to unfreeze its stake. Round switches to this step on error or after receiving a response to a call to `recover_stake`. In case of an error, the round sets the parameter `completionReason`.

7. "Waiting for reward" (RoundStep.WaitingReward) - the defrost period is over. DePool sends Elector a request to restore the stake and waits for a response from him, which will contain the stake + reward (`onSuccessToRecoverStake`), or will call `onFailToRecoverStake`, which means the validator has been blocked.

8. "Completion" (RoundStep.Completing) - at this step DePool ends the round by sending itself a message that calls the function `completeRound`. In this function, DePool processes all the round's stakes. It sends an message `onRoundComplete` to each Participant in the round, and then, depending on the reinvestment flag, reinvests the stake in the last round or transfers it to the Participant. Also at this stage, DePool recalculates vesting and lock-stakes and changes them if necessary.

9. “Completed” (RoundStep.Completed) - the round goes to this step after processing all Participants of the round.

### End of the round

When the round enters the "end" stage (function `completeRound`), DePool starts to cycle through all the stakes of the round. If the Participant's reinvestment flag is `false`, DePool sends it back to the Participant, otherwise - adds it to the last round. DePool also sends a notification (`onRoundComplete`) to the Participant, receiving `RET_OR_REINV_FEE` for this operation from the Participant's reward.

DePool looks at all Vesting and Lock stakes of the final round and checks if the withdrawal period for the current stake has expired. If yes, DePool modifies the stake, transferring part of it to the Participants' regular stake (in the case of Vesting) or transferring part of the stake back to the owner (in the case of Lock).

If there are more than `MAX_MSGS_PER_TR` bids in a round, then reinvestment cannot be performed in one transaction (due to the gas limit). In this case, DePool calls the function `completeRoundWithChunk`. In this way, the end of the round is split across multiple transactions. The `completeRoundWithChunk` function continues to reinvest (or return) the stakes per round, but no more than `MAX_MSGS_PER_TR` at a time.

**Note:** if there are 15,000 bets in the round, then the contract must split the completion into 375 transactions by sending 375 `completePendingRound` messages to itself. All these transactions fit in 1-2 blocks, and the whole operation will take about 5-20 seconds.

### Pool close function

`terminator()` **[only external message]** - DePool closing method. All stakes from all rounds return in several stages:

1. immediately return the stakes from the last round (which is at the initial stage).
2. `m_poolClosed` = true;
3. all other rounds return stakes after the completion stage.

**Important:** only the one who deployed DePool can call `terminator`, since it must be signed with the deploy key pair.

## DePool Decentralization

1. There is no built-in way to replace the contract code (no SETCODE);
2. There is no built-in way to transfer an arbitrary amount from DePool;
3. Any contract can call the ticktock () function to update the DePool state;
4. No one has any special privileges, except for the one who deployed DePool. He can close DePool and begin the procedure for returning all the stakes back to the Participants;
5. Commissions cannot be changed after the contract is deployed;
6. The validator's wallet must be a participant in order to also share risks with other participants.

## DePool contract commission

* DePool charges a commission for calling the following functions `addOrdinaryStake/addVestingStake/addLockStake/removeStake/setReinvest/pauseStake/transferStake`. Use `getDePoolInfo`to get the commission values.
* Whoever calls the ticktock function must pay for the consumed gas. Unused post value is refunded when ticktock is over.
* DePool takes `RET_OR_REINV_FEE` from the Participant's reward to send a message notifying about the end of the investment round.

## Links

1. DePool Specifications
2. DePool contract on github
3. DePool. Deployment instructions
4. Catalog of DePools

de:DePool
el:DePool
es:DePool
fr:DePool
it:DePool
pt:DePool
ru:DePool
tr:DePool
uk:DePool