<!--
  Copyright (c) 2024-2025 Тарабанов Александр Викторович
  All rights reserved.
  
  This software is proprietary and confidential.
  Unauthorized copying, modification, or distribution is prohibited.
  
  For licensing inquiries: info@hb3-accelerator.com
  Website: https://hb3-accelerator.com
  GitHub: https://github.com/HB3-ACCELERATOR
-->

# Архитектура модулей DLE

## Обзор

DLE использует модульную архитектуру, где каждый модуль может иметь свои правила доступа и функциональность.

## Типы модулей

### 1. Простые модули (Вариант 1)
Модули сами проверяют права доступа токен-холдеров.

```solidity
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.

```solidity
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 (Казна)
```solidity
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 (Управление)
```solidity
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);
    }
}
```

## Безопасность

### Общие принципы:
1. **Всегда проверяйте** баланс токенов DLE
2. **Валидируйте входные данные** в модулях
3. **Используйте ReentrancyGuard** для финансовых операций
4. **Логируйте важные операции** через события

### Аудит модулей:
- Проверяйте права доступа
- Тестируйте граничные случаи
- Валидируйте входные параметры
- Проверяйте обработку ошибок 

# Модульная архитектура (обновление для DLE v2)

- Модули выносятся в отдельные контракты: `TreasuryModule`, `TimelockModule`, `DeactivationModule`, `CommunicationModule`.
- Подключение/отключение модулей — строго через предложения DLE (`ModuleAdded`/`ModuleRemoved`).
- Исполнение модульных операций инициируется основным DLE через `_executeOperation` по безопасному `operationCalldata`.
- Денежные переводы из ядра исключены: все токено‑операции внутри `TreasuryModule`.
- Таймлок применяется на уровне предложения: `timelockHours` хранится в `Proposal` и проверяется при исполнении.
- Для оффчейн действий ядро эмитит событие `OffchainAction`, которое подписывает и обрабатывает бекенд/клиент.

Последовательность для казначейской операции:
1) Создание предложения с типом операции и параметрами, указание `governanceChainId`, `targetChains`, `timelockHours`.
2) Сбор голосов в выбранной сети (снапшоты ERC20Votes).
3) По наступлению timelock — `executeProposalBySignatures` в целевых сетях с проверкой EIP‑712 подписей и «100% или ничего».
4) Ядро вызывает `TreasuryModule` по `abi.encodeWithSelector(...)`. 