---
# System prepended metadata

title: Протокол токенсейла с вестингом

---

# Протокол токенсейла с вестингом



## Общий интерфейс контракта
Протокол токенсейла с вестингом подразумевает единую точку входа для пользователя через контракт `Market`. Пользователь может купить через него токен на всех заявленных раундах и склеймить исходя из календаря вестинга, закрепленного за каждым раундом. Этот контракт используется как для клиентов, непосредственно купивших токены, либо импортированных через служебный итерфейс как покупателей, так и тн коммандных токенов, закрепляемых за коммандой в соответствии с токеномикой. 


```solidity
interface Market {
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    struct VestingSchedule {
        bool initialized;
        address beneficiary;
        uint256 cliff;
        uint256 start;
        uint256 duration;
        uint256 slicePeriodSeconds;
        bool revocable;
        uint256 amountTotal;
        uint256 released;
        bool revoked;
    }

    function DEFAULT_ADMIN_ROLE() external view returns (bytes32);
    function OPERATOR() external view returns (bytes32);
    function buy(uint256 _market, uint256 _amount, address _benefeciary) external;
    function calculateOrderPrice(uint256 _market, uint256 _amount) external view returns (uint256 _price);
    function calculateOrderSize(uint256 _market, uint256 _amount)
        external
        view
        returns (uint256 _tgeAmount, uint256 _vestingAmount);
    function claim() external;
    function claimForIndex(uint256 _index) external;
    function currency() external view returns (address);
    function currencyTreasury() external view returns (address);
    function deployMarket(
        uint256 _price,
        uint256 _minOrderSize,
        uint256 _maxOrderSize,
        uint256 _tgeRatio,
        uint256 _start,
        uint256 _cliff,
        uint256 _duration,
        uint256 _slicePeriod,
        bool _revocable,
        bool _permisionLess
    ) external;
    function getIndexCount() external view returns (uint256);
    function getRoleAdmin(bytes32 role) external view returns (bytes32);
    function getVestingScheduleForIndex(uint256 _index) external view returns (VestingSchedule memory);
    function getVestingSchedules() external view returns (VestingSchedule[] memory);
    function grantRole(bytes32 role, address account) external;
    function hasRole(bytes32 role, address account) external view returns (bool);
    function marketsCount() external view returns (uint256);
    function migrateUser(uint256 _market, uint256 _amount, address _benefeciary) external;
    function productTreasury() external view returns (address);
    function renounceRole(bytes32 role, address account) external;
    function revokeRole(bytes32 role, address account) external;
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

```
## Интерфейс получения данных

структура **VestingSchedule** обеспечивает данные по покупкам конкретного пользователя, а структура **MarketInfo** обеспечивает данные по конкретному раунду рынка. Для удобства в контракт введены функции с префиксом calculate, обеспечивающие расчет необходимых данных, на основе этих структур. 

> **инфа не доступная в контракте**: сколько токенов купил пользователь 
```solidity=
// Для указанного индекса покупки
VestingSchedule userInfoForIndex = market.getVestingScheduleForIndex(ROUND_NUM, BENEFECIARY)

// Для всех покупок, в которых пользователь учавствовал
VestingSchedule[] userInfo = market.getVestingSchedules(BENEFECIARY)

// сколько токенов уже склеймлено.
uint256 totalClaimed = userInfoForRound.amountTotal; 

// сколько доступно на данный момент
uint256 avaibleToClaim = market.avaibleToClaim(PURCHASE_INDEX, BENEFECIARY); 

// курс обмена, или цена 1 токена в валюте, за которую он продается
uint256 productPriceForOneToken = market.calculateOrderPrice(ROUND_NUM, 1e18);



```


## Покупка токенов

При покупке токенов пользователем часть токенов сразу уходит на кошелек пользователя, часть блокируется в соответствии с календарем вестинга

```solidity=
// ROUND_NUM - номер раунда 0..N
// PRODUCT_AMOUNT_TO_BUY - необходимое к покупке число токенов
// BENEFECIARY - адресс распорядителя токенов
//1. Получаем необходимую для аллокации пользователем сумму стейблкоиина
uint256 usdAmount = market.calculateOrderPrice(ROUND_NUM, PRODUCT_AMOUNT_TO_BUY);
//2. Апрувим поллученую сумму в адресс контракта токенсейла  
usdt.approve(address(market), usdAmount);
//3. Покупаем токены
market.buy(ROUND_NUM, PRODUCT_AMOUNT_TO_BUY, BENEFECIARY);

```

## Клейм токенов

В соответствии с календарем вестинга пользователю открывается доступ к сбору(клейму) токенов. Важно понимать, что пользователь может владеть обязательствами с разными каллендарями(например если он приобрел токены в разных раундах или является кошельком команды, чьи токены разблокируются на нескольких календарях). В связи с этим фактом сущевствует два варианта клейма токенов - непосредственно для конкретного раунда и для всех доступных пользователю раундов.

```solidity=
// Сбор для всех раундов - в случае большого количества раундов 
// может уперется в out of gas
market.claim();
// Сбор для конкретного раунда
market.claimForIndex(ROUND_NUM);

```

## Адреса контрактов

### Ethereum goerli
Контракт продукта(SHARK) : [0x7b8d1d0ca2d679ca8ffd37491c90b066d4511c12](https://goerli.etherscan.io/address/0x7b8d1d0ca2d679ca8ffd37491c90b066d4511c12)
Контракт валюты(TUSD) : [0x37bee9daecb30cd44305ff76fcdd44e471244efa](https://goerli.etherscan.io/address/0x37bee9daecb30cd44305ff76fcdd44e471244efa)

**Контракт магазина(MARKET)** :
https://goerli.etherscan.io/address/0x71d3b4779Fe591147db2013359A7B1A568535812

Контракт казначейства(TREASURY) :
https://goerli.etherscan.io/address/0xb4774da332416c26078ed39d4e3d64fd4cb34e75

### Binance testnet
Контракт продукта(SHARK) : [0x4fbd6fbd58045113ba7adf02034e0fcaa3e85396](https://testnet.bscscan.com/address/0x4fbd6fbd58045113ba7adf02034e0fcaa3e85396)

Контракт валюты(TUSD) : [0xbbf54ed533d1df95c201d0afd859c1707f7857ab](https://testnet.bscscan.com/address/0xbbf54ed533d1df95c201d0afd859c1707f7857ab)

**Контракт магазина(MARKET)** :
https://testnet.bscscan.com/address/0xf6b3fc7b787e1a5bbd9dfe530a0f6b02fc709733

Контракт казначейства(TREASURY) : https://testnet.bscscan.com/address/0x0C52135199590FB481b95Ff3cF82B87c3a34D16A


## Настройки сети

https://chainlist.org/chain/5


## Настройки раундов(SHARK)

TGE = сколько токенов доступно на старте
Cliff = период начальной блокировки
Duration = общий период вестинга
Slice = длинна периода еденичного разлока 
> `(Duration - Cliff ) / Slice = количество разлоков`

0-4 люди заходят через buy()
5-12 через migrateUser()

| Index | Description | Amount, pc | TGE, % | Cliff, weeks | Duration, weeks | Slice, weeks | Price, $ per token |
| -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
| 0 | Seed | 23.000.000 | 3 | 12 | 60 | 4 | 0.01 |
| 1 | Private | 33.800.000 | 5 | 12 | 60 | 4 | 0.012 |
| 2 | Strategic | 58.750.000 | 7 | 12 | 60 | 4 | 0.014 |
| 3 | Public | 24.450.000 | 40 | 0 | 24 | 4 | 0.020 |
| 4 | Whitelist | 10.000.000 | 25 | 0 | 32 | 4 | 0.017 |
| 5 | Liquidity | 55.000.000 | 27 | 0 | 32 | 4 | 0 |
| 6 | Giveaways | 1.400.000 | 33 | 0 | 8 | 4 | 0 |
| 7 | Rewards | 500.000 | 8.3 | 0 | 44 | 4 | 0 |
| 8 | Marketing | 100.000.000 | 5 | 0 | 44 | 4 | 0 |
| 9 | Advisors | 75.600.000 | 0 | 44 | 132 | 12 | 0 |
| 10 | Ecosystem & Partnership | 100.000.000 | 5 | 0 | 64 | 4 | 0 |
| 11 | Core Team | 100.000.000 | 0 | 48 | 144 | 4 | 0 |
| 12 | P2E In game liquidity | 417.500.000 | 0 | 16 | 144 | 4 | 0 |

## Настройка белого списка

В контракте market предусмотрен единый белый список, он задействуется в раундах с настройкой `permisionLess = false`.

TBA

## Фабрика

TBA

## DAO

TBA









 






 

