5.3 KiB
5.3 KiB
Архитектура модулей DLE
Обзор
DLE использует модульную архитектуру, где каждый модуль может иметь свои правила доступа и функциональность.
Типы модулей
1. Простые модули (Вариант 1)
Модули сами проверяют права доступа токен-холдеров.
contract SimpleModule {
address public dleContract;
modifier onlyDLEHolders() {
require(IERC20(dleContract).balanceOf(msg.sender) > 0, "Must hold DLE tokens");
_;
}
function someFunction() external onlyDLEHolders {
// Логика функции
}
}
2. Сложные модули (Вариант 3)
Модули работают через основной контракт DLE.
contract ComplexModule {
address public dleContract;
function executeOperation(address caller, bytes calldata operation) external {
require(msg.sender == dleContract, "Only DLE can call");
require(IERC20(dleContract).balanceOf(caller) > 0, "Must hold tokens");
// Выполняем операцию
_executeOperation(caller, operation);
}
}
Рекомендации по выбору
Используйте Вариант 1 для:
- ✅ Простых операций (чтение данных)
- ✅ Модулей с минимальной логикой
- ✅ Быстрых операций
Используйте Вариант 3 для:
- ✅ Сложных финансовых операций
- ✅ Модулей с критической логикой
- ✅ Операций, требующих аудита
Примеры модулей
TreasuryModule (Казна)
contract TreasuryModule {
address public dleContract;
mapping(address => bool) public supportedTokens;
modifier onlyDLEHolders() {
require(IERC20(dleContract).balanceOf(msg.sender) > 0, "Must hold DLE tokens");
_;
}
function depositToken(address token, uint256 amount) external onlyDLEHolders {
require(supportedTokens[token], "Token not supported");
IERC20(token).transferFrom(msg.sender, address(this), amount);
}
function withdrawToken(address token, uint256 amount) external onlyDLEHolders {
require(supportedTokens[token], "Token not supported");
IERC20(token).transfer(msg.sender, amount);
}
}
GovernanceModule (Управление)
contract GovernanceModule {
address public dleContract;
function executeOperation(address caller, bytes calldata operation) external {
require(msg.sender == dleContract, "Only DLE can call");
require(IERC20(dleContract).balanceOf(caller) > 0, "Must hold tokens");
// Выполняем операцию управления
_executeGovernanceOperation(caller, operation);
}
}
Безопасность
Общие принципы:
- Всегда проверяйте баланс токенов DLE
- Валидируйте входные данные в модулях
- Используйте ReentrancyGuard для финансовых операций
- Логируйте важные операции через события
Аудит модулей:
- Проверяйте права доступа
- Тестируйте граничные случаи
- Валидируйте входные параметры
- Проверяйте обработку ошибок
Модульная архитектура (обновление для DLE v2)
- Модули выносятся в отдельные контракты:
TreasuryModule,TimelockModule,DeactivationModule,CommunicationModule. - Подключение/отключение модулей — строго через предложения DLE (
ModuleAdded/ModuleRemoved). - Исполнение модульных операций инициируется основным DLE через
_executeOperationпо безопасномуoperationCalldata. - Денежные переводы из ядра исключены: все токено‑операции внутри
TreasuryModule. - Таймлок применяется на уровне предложения:
timelockHoursхранится вProposalи проверяется при исполнении. - Для оффчейн действий ядро эмитит событие
OffchainAction, которое подписывает и обрабатывает бекенд/клиент.
Последовательность для казначейской операции:
- Создание предложения с типом операции и параметрами, указание
governanceChainId,targetChains,timelockHours. - Сбор голосов в выбранной сети (снапшоты ERC20Votes).
- По наступлению timelock —
executeProposalBySignaturesв целевых сетях с проверкой EIP‑712 подписей и «100% или ничего». - Ядро вызывает
TreasuryModuleпоabi.encodeWithSelector(...).