Интеграция с Sablier для линейных выплат и вестинга

Интеграция с Sablier для линейных выплат и вестинга Расчёт `vestedAmount` через `block.timestamp` — классическая ловушка при самописном вестинге. В момент отправки транзакции пользователь видит одну сумму, а при включении в блок через 30 секунд — другую. Разница может составлять до 5% от суммы —

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1452
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1270
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1011

Интеграция с Sablier для линейных выплат и вестинга

Расчёт vestedAmount через block.timestamp — классическая ловушка при самописном вестинге. В момент отправки транзакции пользователь видит одну сумму, а при включении в блок через 30 секунд — другую. Разница может составлять до 5% от суммы — при стриме на 10 000 токенов это даёт погрешность в 500 токенов. В проектах с высокими объёмами такие ошибки возникают регулярно, требуя ручной корректировки балансов.

Sablier решает эту проблему на уровне протокола: каждый поток — это детерминированная математическая модель, где streamedAmount рассчитывается on-chain с точностью до секунды. Мы предлагаем интеграцию Sablier под ключ для вашего dApp, включая смарт-контракты, фронтенд и мультисетевой деплой. Наша команда имеет многолетний опыт в разработке DeFi-протоколов и более 20 успешных интеграций Sablier. Свяжитесь с нами для анализа вашего кейса — подберём оптимальное решение.

Как Sablier решает проблему точных выплат?

Sablier v2 состоит из двух основных контрактов:

  • SablierV2LockupLinear — линейные потоки от точки A к точке B. Поддерживает cliff period и стриминг секунда в секунду с момента start time.
  • SablierV2LockupDynamic — динамические потоки с кастомными сегментами для произвольной кривой вестинга (экспоненциальной, stepped и т.д.).

Каждый поток — это NFT (ERC-721). Это ключевое решение: стрим можно передать другому адресу (transfer stream = transfer право на будущие выплаты), использовать как залог в lending-протоколе или отображать в NFT-маркетплейсе. Отправитель может отозвать поток (если создан как cancelable) — оставшиеся токены возвращаются.

Какие типы потоков доступны и как выбрать?

Тип потока Описание Когда использовать
LockupLinear Линейная разблокировка от startTime до endTime, опциональный cliff Тим вестинг, зарплаты, гранты с простой кривой
LockupDynamic Произвольные сегменты (разные скорости на разных отрезках) Сложная токеномика, экспоненциальный вестинг, multiple milestones

Выбор между LockupLinear и LockupDynamic зависит от вашей токеномики. Для классического team vesting (4 года с 1-летним cliff) подходит LockupLinear. Если нужно начислять бонусы ускоренными темпами или имитировать экспоненциальную кривую — используйте LockupDynamic с сегментами. Мы поможем спроектировать правильную конфигурацию на этапе анализа.

Интеграция смарт-контракта

Для dApp, который создаёт стримы программно (например, DAO выплачивает гранты, протокол начисляет rewards через Sablier вместо custom vesting).

import { ISablierV2LockupLinear } from "@sablier/v2-core/interfaces/ISablierV2LockupLinear.sol"; import { LockupLinear, Broker } from "@sablier/v2-core/types/DataTypes.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract VestingManager { ISablierV2LockupLinear public immutable sablier; IERC20 public immutable token; constructor(address _sablier, address _token) { sablier = ISablierV2LockupLinear(_sablier); token = IERC20(_token); } function createVestingStream( address recipient, uint128 totalAmount, uint40 cliffDuration, // секунды uint40 totalDuration // секунды ) external returns (uint256 streamId) { token.approve(address(sablier), totalAmount); LockupLinear.CreateWithDurations memory params = LockupLinear.CreateWithDurations({ sender: address(this), recipient: recipient, totalAmount: totalAmount, asset: token, cancelable: true, // DAO может отозвать transferable: false, // NFT нельзя передать (опционально) durations: LockupLinear.Durations({ cliff: cliffDuration, total: totalDuration }), broker: Broker({ account: address(0), fee: 0 }) }); streamId = sablier.createWithDurations(params); } } 

Важный момент: totalAmount — это gross amount. Если у токена есть tax, нужно учитывать deflationary transfer и передавать totalAmount с запасом, или использовать transferFrom с проверкой фактического received amount. Мы включаем такие edge cases в нашу интеграцию, чтобы избежать потерь.

Для отображения активных стримов используется The Graph. Пример запроса к subgraph для всех сетей:

query GetStreams($recipient: String!) { streams( where: { recipient: $recipient, status: STREAMING } orderBy: startTime orderDirection: desc ) { id asset { symbol, decimals } depositAmount withdrawnAmount startTime endTime cliffTime cancelable transferable } } 

Интерфейс пользователя: отображение и управление потоками

Для пользователя нужны: список активных стримов, текущий прогресс, уже выплачено, доступно к клейму, оставшееся. А также действия: withdraw и cancel (для sender). Визуализация прогресса — timeline с cliff и linear фазами.

Какие данные нужны для отображения стрима?

Sablier предоставляет subgraph (The Graph) для всех основных сетей. Запрос активных стримов для адреса описан выше. Текущий доступный баланс — streamedAmount - withdrawnAmount — считается через on-chain вызов streamedAmountOf(streamId). Subgraph даёт snapshot на момент последнего события, live баланс нужно читать с контракта.

Расчёт прогресса

Для linear стрима без cliff прогресс = (now - startTime) / (endTime - startTime). С cliff — до cliff показываем 0%, после cliff линейная интерполяция. Для dynamic стримов нужно интерполировать по сегментам — SDK Sablier предоставляет computeStreamedAmount helper.

import { getStreamedAmount } from '@sablier/v2-sdk'; const streamed = getStreamedAmount({ startTime: stream.startTime, endTime: stream.endTime, depositAmount: BigInt(stream.depositAmount), cliffTime: stream.cliffTime, currentTime: BigInt(Math.floor(Date.now() / 1000)), segments: stream.segments, // для dynamic streams }); const progressPercent = Number(streamed * 100n / BigInt(stream.depositAmount)); 

Что входит в работу

  • Анализ вашей логики вестинга и токеномики с выбором оптимального типа стрима.
  • Проектирование смарт-контрактов-обёрток (если требуется) с учётом безопасности (cancelable, transferable).
  • Реализация контрактов на Solidity с использованием Foundry и фаззинг-тестированием Echidna.
  • Разработка интерфейса с подключением Sablier subgraph, прогресс-барами и действиями (withdraw/cancel).
  • Мультисетевой деплой с верификацией на Etherscan для всех поддерживаемых сетей.
  • Документация, исходный код, скрипты деплоя, доступ к шаблонному репозиторию.
  • Обучение команды (1 час онлайн) и поддержка в течение 3 месяцев после сдачи.

Процесс работы и сроки

  1. Анализ — разбираем вашу логику вестинга и токеномику, подбираем тип стрима (linear или dynamic).
  2. Проектирование — проектируем смарт-контракты-обёртки (если нужны), определяем параметры безопасности (cancelable, transferable).
  3. Реализация — пишем контракты с использованием Sablier SDK с тяжёлым тестированием (foundry, echidna fuzzing).
  4. Интерфейс — подключаем Sablier subgraph, реализуем прогресс-бары и действия (withdraw/cancel) через viem или ethers.js.
  5. Деплой — мультисетевой деплой с верификацией на Etherscan. Sablier v2 задеплоен на Ethereum mainnet, Arbitrum, Optimism, Polygon, Avalanche, BNB Chain, Base, Gnosis. Адреса контрактов стабильны.
  6. Поддержка — передаём документацию, исходники, скрипты деплоя. Гарантируем исправление багов в течение 48 часов.

Базовая интеграция (создание стримов из контракта + UI просмотр) — 3-4 дня. Полноценный интерфейс с управлением, визуализацией и мультисетевой поддержкой — 5-7 дней. Стоимость рассчитывается индивидуально.

Почему стоит выбрать Sablier вместо кастомного контракта?

Sablier v2 прошёл аудит Trail of Bits и Quantstamp, что гарантирует отсутствие критических уязвимостей.

Критерий Sablier v2 Кастомный контракт
Аудит Trail of Bits и Quantstamp Часто без формальной верификации
Риск реэнтранси Отсутствует (детерминированная математика) Высокий при неаккуратной реализации
Гибкость Linear и dynamic потоки, cliff Требует переписывания кода
Поддержка сетей 8+ сетей с единым интерфейсом Каждая сеть — отдельный деплой
Газ (создание потока) 200k gas ($0.5 при текущем газе) 300k+ gas ($1.2)
Экономия на аудите Встроен в протокол Требуется отдельный аудит ($20k+)

Sablier надёжнее и внедряется в 10× быстрее, чем писать собственный контракт с нуля. Экономия на газе составляет 30-50% при создании каждого стрима. При 1000 стримах в месяц экономия может достигать $700.

Типичные сценарии использования

  • Team vesting: 4-year vesting с 1-year cliff для команды и инвесторов.
  • Grant streaming: DAO стримит гранты по месяцам вместо upfront выплат.
  • Salary in crypto: непрерывный поток USDC как зарплата.
  • Protocol rewards: замена custom reward-контракта на Sablier streams.

Если вы хотите добавить потоковые выплаты в ваш dApp, закажите интеграцию Sablier — мы проведём аудит вашей логики и предложим оптимальное решение. Получите консультацию по вашему кейсу — свяжитесь с нами.