Розробка таймлок-контрактів
Compound Finance запровадив таймлок-контракт у мейнстрим. Їх Timelock.sol — двохденна затримка перед виконанням будь-яких змін протоколу — став стандартом після того, як кілька DeFi-протоколів втратили средства через миттєві admin-операції. Сьогодні таймлок — це базова вимога будь-якого аудитора й перше питання на лістингу.
Ідея проста: адміністративна дія не виконується миттєво, а ставиться в очередь з мінімальною затримкою. Користувачі бачать майбутню зміну й можуть вийти з протоколу, якщо вона їм не підходить. Це не панацея, але це чесний контракт з користувачами.
Дві реалізації: OpenZeppelin TimelockController проти кастомного контракту
OpenZeppelin TimelockController — перший вибір для більшості випадків. Підтримує ролі (proposer, executor, canceller), пакетне виконання операцій, перевірку мінімальної затримки. Інтегрується з Governor для on-chain голосування. Добре протестований, використовується Compound, Uniswap, Aave.
Кастомний таймлок потрібен, коли:
- Потрібні різні затримки для різних типів операцій (наприклад, 48 годин для зміни fee, 7 днів для зміни admin)
- Потрібна інтеграція з мультисигом без Governor
- Специфічна логіка скасування або екстрених операцій
Ми працюємо з обома варіантами. Для нового протоколу зазвичай розпочинаємо з TimelockController — він покриває 80% випадків.
Критичні деталі реалізації
Мінімальна затримка
48 годин — мінімум для production-протоколу. Менше — користувачі не встигнуть відреагувати. Стандарт DeFi-протоколів: 24-72 години для параметрів, 7 днів для зміни owner/admin.
uint256 public constant MIN_DELAY = 2 days;
uint256 public constant MAX_DELAY = 30 days;
Попередження replay-атак
Кожна операція ідентифікується хешем параметрів плюс salt. Без salt одна й та ж операція (наприклад, setFee(100)) може бути поставлена в очередь тільки один раз. З salt — будь-яку кількість разів. Переконуємось, що клієнт розуміє це поведення.
Екстрені функції
Майже завжди потрібен bypass для критичних ситуацій — якщо знайдена вразливість, неможна чекати 48 годин. Паузатор (Pausable) з окремою роллю — стандартне рішення. Але паузатор, у свою чергу, повинен бути обмежений: він тільки зупиняє, не змінює логіку.
Інтеграція з Governor
Для повноцінного on-chain управління ланцюжок виглядає так: Governor → TimelockController → Protocol. Голосування проходить у Governor, переможне пропозиція ставиться в очередь TimelockController, після затримки виконується.
OpenZeppelin надає GovernorTimelockControl — адаптер, який пов'язує ці два контракти. Головна помилка — дати TimelockController прямий admin-доступ до протоколу, минуючи Governor. Це робить голосування декоративним.
Сроки
Деплой TimelockController з конфігурацією ролей — 1 день. Кастомний таймлок з кількома рівнями затримки — 2-3 дня. Інтеграція з існуючим Governor — 1-2 дня залежно від архітектури протоколу. Тесты включені в оцінку.







