Інтеграція Lido: де ламається стейкінг і що втрачає замовник
Інтеграція Lido ламається не на етапі підключення, а на експлуатації: контракти приймають транзакції, інтерфейс показує баланс, а через тиждень з'ясовується, що частина коштів зависла в черзі виведення, а облік stETH у вашій системі розходиться з ончейн-станом.
Ціна такого збою — не лише заблокована ліквідність, а й недостовірна звітність перед користувачами та регулятором.
Стейкінг Lido влаштований як обмін із відкладеним розрахунком: ви вносите ETH і отримуєте stETH, але назад отримуєте не ETH, а місце в черзі виведення.
Поки заявка не оброблена, актив не можна повернути в обіг, і якщо логіка продукту побудована на припущенні «вивів — одразу отримав», перший же сплеск заявок розкриє діру.
Окремий головний біль — обгорнутий wstETH: його курс зростає відносно stETH, і облік, який вважає wstETH рівним stETH один до одного, тихо занижує баланс казни.
Черга виведення Lido — не миттєвий механізм, а послідовність обробки заявок, де важливі порядок, ліміти та момент фіналізації.
Помилки інтеграції стейкінгу найчастіше живуть саме тут: заявку створили, але не відстежили зміну статусу, не врахували, що частина виведення може бути закрита не повністю, і не побудували ідемпотентну обробку повторних подій.
У результаті один і той самий вивід обліковується двічі, а розсинхрон stETH-обліку накопичується непомітно.
Далі розбираємо, як це закривається: де ставити звірку ончейн-стану з внутрішнім реєстром, як проєктувати обробку черги виведення і які перевірки ловлять розсинхрон до того, як він перетвориться на збиток.
Що дає коректна інтеграція Lido: режими, ефект, обмеження
Інтеграція Lido починається з вибору режиму: від нього залежать швидкість зарахування, поведінка обліку й те, які відмови взагалі можливі. Нижче — три робочі режими, які ми закриваємо під ключ, та їхній вимірюваний ефект.
stETH: базовий режим із щоденним перерахунком
Баланс зростає завдяки rebase — власник отримує дохід без транзакцій. Підходить для казначейств і вітрин, де потрібен «живий» зростаючий баланс.
Обмеження: rebase ламає облік там, де баланс зафіксовано у снапшотах, — інтеграція потребує явної обробки подій перерахунку, інакше розбіжності у звітності накопичуються.
wstETH: обгортка з фіксованим балансом
Курс зростає відносно stETH, кількість токенів не змінюється. Це знімає клас відмов, пов'язаних із rebase: баланс в обліку стабільний, снапшоти та внутрішні реєстри не «пливуть». Підходить для застав, пулів ліквідності та будь-яких місць, де важлива незмінність кількості. Обмеження — дохід видно лише через курс, а не через баланс.
WithdrawalQueue: прямий вивід в ETH
Заявка ставиться в чергу, виконання — у міру обробки. Це єдиний коректний шлях «стейкінг → нативний ETH» без зовнішніх обмінників. Підходить для сценаріїв, де потрібен саме ETH, а не похідний токен.
Обмеження: строк виконання залежить від завантаження черги, тому в інтерфейсі потрібен явний статус заявки, а не «миттєвий вивід».
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| stETH | вітрини, казначейство, зростаючий баланс | rebase ламає снапшоти та фіксований облік |
| wstETH | застави, пули, стабільний облік | дохід лише через курс, не через баланс |
| WithdrawalQueue | вивід у нативний ETH | строк залежить від черги, потрібен статус заявки |
Ефект інтеграції вимірний: зарахування стейку проходить в одній транзакції, частка розбіжностей в обліку падає до нуля завдяки коректній обробці rebase, а клас відмов «вивід завис без статусу» зникає разом із явною моделлю черги.
Ми будуємо інтеграцію на Lido з роздільними шляхами для обліку та виводу — це дозволяє змінювати режим без переписування логіки.
Як ми впроваджуємо інтеграцію: етапи інженерної роботи
Інтеграція Lido — це не «підключити бібліотеку», а вбудувати в наявний контур роботу з похідними стейкінгу: облік stETH і wstETH, коректна обробка черги виведення WithdrawalQueue та розмежування прав на операції з активами клієнта. Нижче — послідовність, за якою ми ведемо проєкт від аудиту до передачі.
- Аудит поточної інфраструктури та стейкінгу. Дивимося, як влаштовані гаманці й ключі, хто ініціює транзакції, як ведеться облік балансів і чи вже є робота з похідними токенами. Фіксуємо розриви: де баланс stETH вважається «як звичайний токен», де не враховано курс обміну stETH↔wstETH, де немає обробки заявок на виведення.
- Проєктування схеми. Визначаємо, чи працюємо через stETH, чи обгортаємо в wstETH, як будується шлях виведення через WithdrawalQueue, які ролі потрібні для мінту, обгортки та ініціювання виведення. На виході — схема потоків активів і матриця доступів.
- Налаштування Lido під контур замовника. Підключаємо контракти та сервісний шар, налаштовуємо параметри роботи з похідними токенами й чергою виведення, приводимо облік до єдиної логіки — щоб баланси та нарахування збігалися з ончейн-станом.
- Перевірка інтеграції. Прогоняємо сценарії на тестовому середовищі: стейкінг, обгортка, виведення, часткове виведення, повторна заявка. Звіряємо розрахунки з фактичними даними мережі та перевіряємо поведінку при відмовах і затримках черги.
- Передача рішення. Віддаємо робочу інтеграцію, документацію за схемою та доступами, інструкції з експлуатації й розбір типових інцидентів — щоб команда замовника вела систему самостійно.
Кожен етап закінчується артефактом: звіт аудиту, схема, конфігурація, протокол перевірки, комплект документації. Так на прийманні видно, що саме перевірено і на яких даних.
Чим відрізняється прямий стейкінг від обгорнутого wstETH?
Прямий стейкінг через Lido повертає користувачеві stETH — токен, який щоденно відображає винагороди через зростання балансу. Це rebasing-модель: кількість токенів на гаманці збільшується сама по собі, а курс до ETH залишається близьким до одиниці.
Облік винагород відбувається «зсередини» протоколу, і будь-який зовнішній сервіс, який тримає stETH, зобов'язаний коректно реагувати на зміну балансу.
wstETH — це обгорнута версія того самого стейку. Баланс фіксований, а винагороди «зашиті» в курс обміну: з часом один wstETH коштує більше ETH. Така механіка не ламає облік у чужих контрактах, тому wstETH без проблем приймають кредитні протоколи, агрегатори дохідності та мости. Різниця токенів — саме у способі нарахування: rebasing проти зростаючого курсу.
Ліквідність стейкінгу — ключовий практичний критерій вибору. stETH зручний для простого утримання та обліку винагород, але його не можна «загорнути» в пул або заставу без обгортки.
wstETH створений для DeFi: він сумісний із пулами ліквідності, заставними позиціями та структурованими продуктами, де важлива передбачувана одиниця балансу. Обгорнути stETH у wstETH і повернути назад можна в будь-який момент, втрати винагород при цьому не відбувається.
Є і нюанс виведення. WithdrawalQueue фіксує заявку на обмін стейку на ETH за курсом на момент виконання, і до її закриття токен заблокований у черзі — це впливає на доступну ліквідність.
Під час інтеграції ми враховуємо цей сценарій: обираємо форму токена під задачу клієнта, налаштовуємо коректний облік винагород і перевіряємо поведінку контрактів при rebasing і при виведенні.
Кейс: як ми усунули затримки виведення та розсинхрон обліку
Замовник прийшов із працюючим стейкінгом: контракти приймали ETH, мінтили stETH, але виведення через чергу йшло із затримкою, а баланси в інтерфейсі розходилися з фактичним станом на ланцюгу.
Користувачі бачили одну суму, при спробі вивести — іншу; частина заявок на виведення зависала в статусі очікування, бо запити не зв'язувалися з реальними подіями черги.
Облік будувався на періодичному опитуванні стану замість підписки на події — звідси розсинхрон і сплески навантаження.
Що було до
- Виведення оброблялося вручну: оператор звіряв заявки зі станом черги, середній час закриття заявки — години, в пікові періоди — більше доби.
- Частка успішних операцій виведення трималася на рівні близько 80%: решта — завислі заявки та ручні правки.
- Облік розходився з ланцюгом: інтерфейс показував баланс за останнім опитуванням, а не за актуальним станом, через що користувачі повторно ініціювали виведення.
Що змінили
Перевели облік на потік подій: підписка на випуск і погашення токенів, на постановку заявок у чергу та на їхню фіналізацію. Кожна подія лягає в журнал з ідентифікатором операції, а стан балансів перезбирається з журналу, а не з періодичного опитування.
Заявку на виведення зв'язали з її позицією в черзі — статус оновлюється в міру просування, а не за таймером.
Додали ідемпотентність: повторний запит на виведення з тим самим ідентифікатором не створює дубль, а повертає поточний статус. Це прибрало клас відмов, коли користувач, не дочекавшись відповіді, надсилав заявку вдруге.
Окремо закрили обробку відмов на стороні черги — тепер система розрізняє «заявка в обробці» та «заявку відхилено» і не показує перше замість другого.
Що стало
| Метрика | До | Після |
|---|---|---|
| Середній час закриття заявки на виведення | години | хвилини |
| Частка успішних операцій виведення | ~80% | стабільно вище 99% |
| Розходження обліку з ланцюгом | регулярне | усунуто |
| Ручні правки заявок | постійні | не потрібні |
Розсинхрон пішов як клас: стан в інтерфейсі перезбирається з того самого журналу подій, що й на ланцюгу, тому «показане» і «фактичне» збігаються в будь-який момент.
Навантаження на вузли вирівнялося — замість частих опитувань іде потік подій, який масштабується разом із кількістю операцій.
Логіку черги та обліку ми винесли в окремий шар із покриттям перевірками на сценарії виведення, повторної заявки та відмови — це те, що раніше трималося на ручних діях. Спиралися на Lido як на джерело подій і стану черги, без власної інтерпретації балансів.
Якщо у вас стейкінг уже працює, але виведення гальмує або облік розходиться з ланцюгом — опишіть задачу, повернемося з оцінкою та планом.
Сумніви щодо сумісності, міграції та доступів — обговоримо задачу
Інтеграція Lido майже ніколи не починається з чистого аркуша: у замовника вже є кастодіальний контур, власний сервіс обліку позицій або працюючий стейкінг через іншого оператора. Тому перше питання на дзвінку — не «як підключити stETH», а «що буде з тим, що вже працює».
Сумісність Lido з поточним стеком перевіряємо до початку робіт: дивимося, як влаштований облік балансів, хто тримає ключі, чи є готовий шар підпису транзакцій і як організовано виведення коштів.
Якщо позиції вже десь розміщені — плануємо міграцію стейкінгу так, щоб не зупиняти операції: паралельний контур, перенесення позицій частинами, звірка балансів на кожному кроці.
Що якщо знадобиться відкат інтеграції? Проєктуємо її оборотною з першого дня: контракти та черги виведення ізольовані, стан фіксується в окремому сховищі, а перемикання між старим і новим контуром робиться без втрати вже нарахованих позицій. Відкат — це повернення до попередньої схеми, а не відновлення з нуля.
Як поділяються доступи та ролі? Розмежовуємо права за принципом мінімально необхідного: окремо ролі на ініціалізацію виведення, окремо — на управління позиціями, окремо — на читання звітності.
Ключі не лежать в одному місці, дії записуються в журнал, а зміна відповідального не потребує перезбирання всієї схеми.
Чи можна вбудувати інтеграцію Lido у вже працюючий сервіс без переписування?
Так, якщо поточний шар роботи з мережею підтримує стандартні виклики контрактів. Ми підключаємося до наявної логіки через адаптер: сервіс продовжує працювати як раніше, а операції зі stETH, wstETH і чергою виведення йдуть через окремий модуль. Переписувати ядро не потрібно — змінюється лише шар взаємодії з протоколом.
На руки замовник отримує не «доступ до репозиторію», а комплект, за яким систему можна супроводжувати й передавати іншій команді:
- схему інтеграції з точками входу та виходу коштів;
- конфігурації контрактів і черги виведення з поясненням параметрів;
- матрицю ролей і політику доступів до ключів;
- регламент міграції позицій і процедуру відкату;
- документацію зі стейкінгу: як читати баланси, нарахування та статуси виведення;
- журнал звірки та шаблони звітності для внутрішнього контролю.
Опишіть вашу поточну схему — де зберігаються позиції, хто керує ключами, що вже працює. Повернемося з оцінкою та планом: що перевикористаємо, що додамо і в якому порядку.







