Разработка Safe{Wallet} Plugin

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка Safe{Wallet} Plugin
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Разработка Safe{Wallet} Plugin

Safe (бывший Gnosis Safe) — стандарт де-факто для мультисиг-хранения средств в Web3. $100B+ TVL, тысячи DAO и протоколов. Но базовая функциональность Safe — это только multisig. Plugins (ранее Modules) расширяют его до полноценной программируемой казны: автоматические платежи, ролевой доступ, DeFi-интеграции, spending limits без отдельного multisig голосования.

Архитектура Safe Extensions в Safe v1.4+

Safe{Core} Protocol — это модульная система поверх Safe Account. С версии 1.4 Safe перешёл на новую архитектуру с тремя типами расширений:

Тип Что делает
Plugin Выполняет транзакции от имени Safe без multisig
Hook Валидирует транзакции перед/после выполнения
Function Handler Обрабатывает вызовы к Safe через fallback

Plugin — самый мощный тип. Он может вызывать execTransactionFromModule() на Safe контракте, минуя порог подписей. Именно поэтому установка plugin требует полного multisig approve.

interface ISafeProtocolPlugin {
    function name() external view returns (string memory);
    function version() external view returns (string memory);
    function metadataHash() external view returns (bytes32);
}

Plugin регистрируется в SafeProtocolRegistry — whitelist одобренных расширений. Кастомный plugin для mainnet Safe нужно либо пройти аудит для включения в официальный реестр, либо использовать через кастомный Manager.

Пример: Spending Limit Plugin

Наиболее распространённый кейс — ограниченный доступ для операционных расходов. Вместо голосования 3/5 за каждый платёж команда устанавливает plugin, который разрешает конкретному адресу тратить до N USDC в день без multisig.

contract SpendingLimitPlugin is ISafeProtocolPlugin {
    struct AllowanceConfig {
        uint128 dailyLimit;
        uint128 spent;
        uint64 resetTimestamp;
    }
    
    // safe => token => delegate => config
    mapping(address => mapping(address => mapping(address => AllowanceConfig))) public allowances;
    
    function executeSpend(
        ISafeProtocolManager manager,
        ISafe safe,
        address token,
        address to,
        uint128 amount
    ) external {
        AllowanceConfig storage config = allowances[address(safe)][token][msg.sender];
        
        // сброс дневного лимита
        if (block.timestamp >= config.resetTimestamp + 1 days) {
            config.spent = 0;
            config.resetTimestamp = uint64(block.timestamp);
        }
        
        require(config.spent + amount <= config.dailyLimit, "Daily limit exceeded");
        config.spent += amount;
        
        // Transfer через Safe без multisig
        bytes memory data = abi.encodeCall(IERC20.transfer, (to, amount));
        SafeTransaction memory tx = SafeTransaction({
            to: token,
            value: 0,
            data: data,
            operation: Enum.Operation.Call
        });
        
        (, bytes memory returnData) = manager.executeTransaction(safe, tx);
    }
}

Официальный allowances module от Safe уже реализует похожую логику — для стандартных spending limits лучше использовать его. Кастомный plugin нужен когда требуется нестандартная логика: мульти-токенные лимиты, ролевая модель, интеграция с DeFi.

Hook: валидация транзакций перед выполнением

Hook позволяет добавить дополнительные проверки к любой Safe-транзакции:

contract TransactionGuardHook is ISafeProtocolHook {
    mapping(address => bool) public blockedAddresses;
    
    function preCheck(
        ISafe safe,
        SafeTransaction calldata tx,
        uint8 executionType,
        bytes calldata executionMeta
    ) external view returns (bytes memory preCheckData) {
        // Запрет транзакций на адреса из blacklist
        require(!blockedAddresses[tx.to], "Blocked address");
        
        // Запрет вызовов опасных функций
        if (tx.data.length >= 4) {
            bytes4 selector = bytes4(tx.data[:4]);
            require(!blockedSelectors[selector], "Blocked function");
        }
        
        return abi.encode(block.timestamp);
    }
    
    function postCheck(ISafe safe, bool success, bytes calldata preCheckData) external {
        // логика после выполнения
    }
}

Типичные use cases для Hook: compliance (запрет транзакций на sanctioned addresses через Chainalysis oracle), budget control (запрет превышения месячного бюджета), whitelist (только pre-approved адреса получателей).

Safe{Core} Protocol Manager

В новой архитектуре Plugin не вызывает Safe напрямую — только через SafeProtocolManager. Manager — посредник, который проверяет что plugin включён для конкретного Safe и что registry его одобряет.

// Установка plugin через multisig Safe транзакцию
function enablePlugin(address plugin, uint8 permissions) external authorized {
    ISafeProtocolManager(MANAGER).enablePlugin(plugin, permissions);
}

permissions — битмаска: EXECUTE_DELEGATECALL (0x01), EXECUTE_CALL (0x02). DelegateCall нужен осторожно — plugin с delegatecall правами исполняется в контексте Safe и может изменить его storage.

Тестирование Safe Plugins

Тесты через Foundry с форком mainnet и реальным Safe:

contract SpendingLimitTest is Test {
    ISafe safe;
    SpendingLimitPlugin plugin;
    
    function setUp() public {
        // Fork mainnet
        vm.createFork(MAINNET_RPC);
        
        // Deploy Safe через SafeProxyFactory
        safe = ISafe(safeFactory.createProxyWithNonce(
            SAFE_SINGLETON, 
            initData, 
            block.timestamp
        ));
        
        // Deploy и включить plugin
        plugin = new SpendingLimitPlugin();
        vm.prank(address(safe));
        manager.enablePlugin(address(plugin), 2);
    }
    
    function test_SpendWithinLimit() public {
        vm.prank(delegate);
        plugin.executeSpend(manager, safe, USDC, recipient, 100e6);
        
        assertEq(IERC20(USDC).balanceOf(recipient), 100e6);
    }
    
    function testFail_ExceedDailyLimit() public {
        vm.prank(delegate);
        plugin.executeSpend(manager, safe, USDC, recipient, 10000e6); // > daily limit
    }
}

Процесс разработки

Аналитика (0.5-1 день). Определяем тип расширения (Plugin/Hook/FunctionHandler), необходимые permissions, интеграции (DeFi протоколы, oracles, другие модули).

Разработка (2-3 дня). Контракт plugin, тесты на Foundry с mainnet fork. Safe registry интеграция. Если нужна custom Manager — дополнительный день.

Аудит и ревью (0.5-1 день). Особое внимание на reentrancy через execTransactionFromModule, на корректность permission проверок, на невозможность обхода multisig через plugin при нежелательных условиях.

Frontend интеграция (1 день). Safe Apps SDK для отображения plugin интерфейса прямо в Safe{Wallet} UI.

Итого: 3-5 дней для типового plugin. Сложные multi-module системы с DeFi интеграциями — до 2 недель.