Как проверить действие руководства

Как проверить действие руководства

15 декабря 2022 г.

Надлежащее управление требует четкого понимания последствий.

Когда я работал в финансовых учреждениях, строгие процессы управления изменениями защищали технологию от непреднамеренного вреда во время изменений.

Старшие сотрудники отвечали за внедрение изменений, но их напряженный график и сложность изменений часто усложняли эту задачу.

Чтобы избежать отклонения, нужно было тщательно описать предполагаемое изменение, а также следовать правилам и ставить соответствующие галочки.

Технология Blockchain заново изобретает финансы, включая процессы управления изменениями.

Нам удалось возложить ответственность за изменения на старших сотрудников с помощью мультиподписей и DAO, но нам не удалось добиться того, чтобы подписавшие понимали, что они подписывают.

В результате приходится умолять их подписать. Несмотря на реальный риск атаки на руководство, стало шуткой просто соглашаться с вещами, не понимая их последствий.

В начале работы в Yield я сосредоточился на проблеме мультиподписных участников, которые не понимали, что они подписывают. Для меня это было неприемлемо, и я хотел помешать себе проверить протокол до того, как более высокие оценки повлияют на мое суждение.

Если ваши участники с мультиподписью не уверены в том, что они подписывают, есть способы упростить для них этот процесс. Я покажу вам, как это сделать.

Как губернаторы видят перемены

Некоторые блокчейн-приложения, такие как Uniswap, не требуют разрешений и не требуют дополнительных действий после развертывания. Тем не менее, в большинстве других приложений используются шаблоны изменения по управлению, когда изменения могут быть внесены, если они подписаны мультиподписью или DAO.

Некоторые изменения просты, например, передача токенов или настройка параметра, тогда как другие более сложны и включают в себя развертывание контрактов и их согласование.

Получение подписи для любого изменения требует значительных усилий, поэтому обычно требуется единая подпись для всех элементов, включенных в изменение. В Yield самое большое изменение, которое я видел, включало более трехсот отдельных звонков.

Для более простых изменений участники с мультиподписью могут захотеть просмотреть данные о звонках и даже могут понять их. Однако для более сложных изменений это невозможно.

Губернаторы, одобряющие изменение, должны знать, какие функции вызываются, какие параметры используются и какие последствия они будут иметь. Они должны иметь возможность найти эту информацию самостоятельно, без посторонней помощи.

Добиться этого можно, и это проще, чем может показаться. Однако сначала мы должны понять, как смарт-контракты реализуют изменения в управлении.

Технологии управления

В Yield мы создали собственный Timelock, вдохновившись Compound, но внеся в него важные изменения. В то время как оригинальный Timelock может хранить и задерживать один вызов, наш Timelock может хранить пакет вызовов с любым количеством включенных вызовов.

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

В нашей Timelock вызов является целью, а данные о вызове представляют собой вызов цели:

struct Proposal {
       STATE state;
       uint32 eta;
    }

Предложение или изменение — это просто набор звонков.

function propose(Call[] calldata functionCalls)
       external override auth returns (bytes32 txHash)
   {
       txHash = keccak256(abi.encode(functionCalls));
       require(proposals[txHash].state == STATE.UNKNOWN, "Already proposed.");
       proposals[txHash].state = STATE.PROPOSED;
       emit Proposed(txHash);
   }

Функция предложения разрешена и в нашей реализации разрешена только нашим разработчикам.

Существует также функция утверждения, которая может быть вызвана только мультиподписью. Время утверждения определяет самое раннее возможное время выполнения.

function approve(bytes32 txHash)
       external override auth returns (uint32 eta)
   {
       Proposal memory proposal = proposals[txHash];
       require(proposal.state == STATE.PROPOSED, "Not proposed.");
       eta = uint32(block.timestamp) + delay;
       proposal.state = STATE.APPROVED;
       proposal.eta = eta;
       proposals[txHash] = proposal;
       emit Approved(txHash, eta);
   }

Только разработчикам разрешено выполнять изменения, и они должны предоставить тот же пакет, который использовался в функции предложения. Если пакет другой или идентификатор изменения неверный, изменение не будет одобрено и не будет выполнено.

function execute(Call[] calldata functionCalls)
       external override auth returns (bytes[] memory results)
   {
       bytes32 txHash = keccak256(abi.encode(functionCalls));
       Proposal memory proposal = proposals[txHash];
 
       require(proposal.state == STATE.APPROVED, "Not approved.");
       require(uint32(block.timestamp) >= proposal.eta, "ETA not reached.");
       require(uint32(block.timestamp) <= proposal.eta + GRACE_PERIOD, "Proposal is stale.");

       delete proposals[txHash];

       results = new bytes[](functionCalls.length);
       for (uint256 i = 0; i < functionCalls.length; i++){
           require(functionCalls[i].target.isContract(), "Call to a non-contract");
           (bool success, bytes memory result) = functionCalls[i].target.call(functionCalls[i].data);
           if (!success) revert(RevertMsgExtractor.getRevertMsg(result));
           results[i] = result;
       }
       emit Executed(txHash);
   }

В любой ситуации, когда рассматривается изменение, найдется кто-то, кто решит, что изменение должно быть сделано, и будут разработчики, которые превратят эту идею в код. Этот код в виде пакета вызовов функций затем передается в Timelock с помощью `propose`.

Следующим шагом для ответственного старшего персонала, мультиподписи или DAO является рассмотрение изменения и принятие решения о его утверждении с помощью вызова «утвердить».

Этот шаг часто бывает трудным, потому что трудно понять предлагаемое изменение из Timelock. Мы можем упростить для них этот процесс, используя существующие инструменты разработки, чтобы предоставить им подробную информацию о характере изменения.

Подробный просмотр изменений

Как только изменение было предложено в Timelock, оно становится неизменяемым благодаря своему уникальному идентификатору. Если управляющий утвердит этот идентификатор, будет выполняться только указанная партия вызовов.

Имея это в виду, мы можем:

  1. `предложить` в реальной сети.
  2. Разветвите эту сеть.
  3. Выдайте себя за губернатора и «одобрите» предложение в ответвлении.
  4. `выполнить` в ответвлении

Выполняемое изменение такое же, как и предложенное, потому что мы разветвили сеть после предложения. Кроме того, любой может проанализировать выполнение с помощью декодера транзакций.

В Yield мы используем Tenderly, но есть и другие варианты. Я опубликовал одно из наших предложений, выполненных в вилка для образовательных целей.

Как мультиподписной член Yield, я проверяю исполнение каждого предложения в форке. Я сравниваю идентификатор изменения для утверждения в мультиподписи с идентификатором изменения в ответвлении, и тогда я с полной уверенностью знаю, что в мультиподписи будет то, что будет выполнено.

Verifying the execution identifier

Все изменения должны включать текстовое описание их назначения и параметров. использовался. Я использую это, чтобы понять, что делает изменение в широком смысле, а затем использую декодер транзакций для просмотра деталей.

Я начинаю со сравнения описания с контрактами, задействованными в исполнении, чтобы убедиться, что они совпадают. Проведение комплексной проверки в этом процессе включает проверку всех новых контрактов и обеспечение того, чтобы их проверенный код соответствовал тому, что находится в репозитории.

Reviewing contracts involved

Зная задействованные контракты, события транзакции предоставляют всю необходимую информацию для просмотра остальной части исполнения.

Я просматриваю предоставленные и отозванные разрешения, любые изменения в оракулах и соответствие числовых параметров тому, что было обсуждено и согласовано.

Reviewing al events

Я документирую свой отзыв о Понятие и сделать его общедоступным для каждого изменения. Другие управляющие могут проверить мою работу или провести собственную комплексную проверку любым другим способом, который они выберут. В любом случае, я считаю, что риск быть пойманным, если я искажу информацию об изменении, теперь достаточно высок.

Gnosis Safe как более простая альтернатива

Gnosis Safe теперь предлагает пакетный конструктор и автоматически создает симуляцию на Tenderly для всех выполнений. Это та же функциональность, которую я описал, но с более удобным интерфейсом.

Если ваши предложения по управлению достаточно просты, чтобы их можно было создать вручную в веб-интерфейсе, Gnosis Safe будет более простым вариантом. Вы можете поделиться отчетом о моделировании из Gnosis Safe и получить тот же результат.

Gnosis Safe offers a neatly packaged solution

Заключение

Управлять блокчейн-приложениями сложно, и как управляющий вы рискуете подписать изменения, которые могут привести к сбою приложения либо по ошибке, либо намеренно. Недавние события только подчеркнули необходимость защиты наших пользователей от вреда.

Используя инструменты разработчика и следуя простым процедурам на Yield, мы смогли предоставить управляющим четкую информацию о том, что они подписывают. Мы успешно внесли более сотни отдельных изменений, в общей сложности тысячи вызовов контрактов, сократили количество ошибок управления и можем обнаружить больше ошибок раньше, чем раньше.

Ничто из того, что мы делаем, не является волшебством; это просто здравый смысл. Пожалуйста, убедитесь, что вы понимаете, что подписываете, и попросите необходимые инструменты, если необходимо. Мы в долгу перед нашими пользователями.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE