Интеграция с OpenZeppelin Defender (автоматизация)
Смарт-контракты не живут в изоляции. Им нужно выполнять scheduled задачи (распределение наград, ребалансировка), реагировать на on-chain события (ликвидации, истечение lock-up), и делать это без ручного вмешательства. Обычный подход — сервер с cron job и приватным ключом. OpenZeppelin Defender убирает необходимость хранить ключи на сервере и добавляет мониторинг, алерты и audit trail из коробки.
Компоненты Defender и как они связаны
Relayer — управляемый кошелёк, который отправляет транзакции от вашего имени. Приватный ключ хранится в HSM Defender, вы его никогда не видите. Relayer автоматически управляет nonce и gas price (EIP-1559), обрабатывает resubmit при застрявших транзакциях.
Actions (бывший Autotask) — serverless JavaScript функции, которые запускаются по расписанию или по webhook. Внутри Action доступен prebuilt Relayer для подписи транзакций и Provider для чтения состояния чейна.
Monitor (бывший Sentinel) — мониторинг событий и вызовов функций on-chain. При срабатывании условия — webhook, email, или вызов Action.
Proposal — механизм для выполнения транзакций через Safe{Wallet} multisig или Timelock. Вместо прямого вызова функции — создаётся предложение, которое должны одобрить подписанты.
Типичная архитектура: автоматические ликвидации
Рассмотрим реальный сценарий: lending протокол, нужно ликвидировать позиции с health factor < 1.
Monitor → следит за Transfer и Borrow событиями
→ при падении цены залога через Price Feed
→ триггерит Action
Action → читает health factor через view-функцию
→ если HF < 1, вызывает liquidate() через Relayer
→ логирует результат
Код Action:
const { ethers } = require("ethers");
const { DefenderRelayProvider, DefenderRelaySigner } = require('@openzeppelin/defender-relay-client/lib/ethers');
exports.handler = async function(credentials) {
const provider = new DefenderRelayProvider(credentials);
const signer = new DefenderRelaySigner(credentials, provider, { speed: 'fast' });
const lending = new ethers.Contract(LENDING_ADDRESS, LENDING_ABI, signer);
// Получаем список позиций под ликвидацию (off-chain через Subgraph)
const positions = await getUnderwaterPositions();
for (const position of positions) {
const hf = await lending.getHealthFactor(position.borrower);
if (hf < ethers.parseEther("1")) {
const tx = await lending.liquidate(position.borrower, position.collateral);
console.log(`Liquidated ${position.borrower}: ${tx.hash}`);
}
}
};
speed: 'fast' — Relayer использует maxPriorityFeePerGas из оракула газа Defender. Есть также safeLow, average, rapid.
Monitor: настройка алертов
Monitor настраивается на конкретный контракт, сеть, и условие. Три типа условий:
- Event trigger — контракт эмитировал конкретное событие
- Function call — была вызвана функция (даже если она reverted)
- Expression — произвольное выражение на основе event args или call args
Пример: алерт на любой вывод из treasury более 50 ETH:
Event: Withdrawal(address indexed to, uint256 amount)
Condition: amount > 50000000000000000000
При срабатывании — webhook на Slack или PagerDuty. Для критических событий настраиваем Action, который автоматически ставит контракт на паузу через Pausable.
Безопасный деплой через Proposal
Для контрактов с мультиподписью (Safe{Wallet}) или Timelock рекомендуем управление апгрейдами через Defender Proposal, а не прямыми вызовами:
// Hardhat task для создания proposal
const { AdminClient } = require('@openzeppelin/defender-admin-client');
const client = new AdminClient({ apiKey, apiSecret });
await client.createProposal({
contract: { address: PROXY_ADDRESS, network: 'mainnet' },
title: 'Upgrade to V2',
description: 'Fix reentrancy in withdraw()',
type: 'upgrade',
newImplementation: NEW_IMPL_ADDRESS,
via: SAFE_ADDRESS,
viaType: 'Gnosis Safe'
});
Proposal виден в интерфейсе Defender. Подписанты Safe видят детали и одобряют через UI. Весь процесс логируется — кто создал, кто одобрил, когда выполнено.
Интеграция с Hardhat и Foundry
Для Hardhat — @openzeppelin/hardhat-upgrades плюс @openzeppelin/defender-deploy-client:
// hardhat.config.js
module.exports = {
defender: {
apiKey: process.env.DEFENDER_KEY,
apiSecret: process.env.DEFENDER_SECRET
}
};
Foundry — интеграция через Defender API напрямую или через CLI defender-deploy. Менее нативная, но работает.
Ориентиры по срокам
Базовая настройка Relayer + Action для автоматизации одной задачи: 1 день. Полная интеграция с Monitor, алертами, Safe Proposal workflow и тестированием на testnet: 2-3 дня.
Стоимость Defender зависит от плана (есть бесплатный tier с ограничениями по количеству Actions и Monitors). Это операционные расходы проекта, а не разовая стоимость разработки.







