Proposal #25: Восстановление наград за стейкинг

Основная информация

После взлома Tornado, произошедшего в после proposal 20, помимо основных потерь, связанных с выводом хакером 483 000 TORN из Governance Vault, возникла иная проблема - сломанный контракт Governance Staking и вывод из него (с помощью появившегося бага) более 130 000 TORN.

Произошло это по очень простой причине: при вычислении общей награды за выплаченную релеером комиссию с вывода в контракте стейкинга отвечает функция addBurnRewards и переменная accumulatedRewardPerTorn. Вычисленная награда на 1 TORN средств стейкеров зависит, разумеется, от общей суммы токенов, находящихся в стейкинге - а конкретно, поскольку все средства стейкеров должны находиться в Governance Vault, оно просто берёт баланс контракта Vault.

Поскольку почти все токены из контракта Vault были выведены взломщиком, на оставшиеся там несколько TORN с каждой комиссии релееров начислялись огромные награды, что привело к увеличению наград стейкеров до миллионов, а то и миллиардов TORN. Поскольку исправить случившееся уже было нельзя, изменив данные в контракте, пришлось создать новый прокси-контракт стейкинга и логический контракт (имплементацию), что было сделано в proposal 22. Поскольку старый state (данные о наградах и так далее) остался в предыдущем прокси-контракте, после исполнения proposal 22 награды всех пользователей были обнулены - в особенности пострадали те, кто имели честно заработанные награды до момента взлома и не успели их вывести.

Описание измненений

Для восстановления наград необходимо:

  • Изменить логический контракт (имплементацию) Governance Staking, добавив функцию setReward, которая позволит напрямую устанавливать награды стейкерам (разумеется, её можно вызвать только с помощью proposal, от лица Governance contract);
  • Вернуть стейкерам старые награды - разумеется, только тем, которые не успели их вывести после взлома, и только тем, у кого наград было более 1 TORN - поскольку мы ограничены комиссией и максимальным размером кода контракта;
  • Перевести общую сумму возвращённых стейкерам наград (42 754 TORN) из контракта Governance в контракт Staking, чтобы они могли забрать токены, не нарушая баланс средств в контракте.

Предложение

https://git.tornado.ws/Theo/proposal-25-restore-rewards

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

Данный скрипт сначала получает адреса всех стейкеров, затем проверяет их награды на момент до взлома, фильтрует тех, кто успел вывести с момента взлома до момента создания нового Staking-контракта, высчитывает общую сумму возвращаемых токенов и генерирует Solidity-код, который записывается в файл codeToAccrueRewards.txt без единого изменения и затем копируется в код основного контракта proposal. Любой может выполнить данный код снова, запустив команду npm run computeRewards в директории репозитория, и сравнить с кодом в основном контракте proposal`а.

Информация о всех стейкерах с балансами более 1 TORN до момента взлома находится в этом файле - можете проверить данные любого адреса самостоятельно.

Так же предлагаю каждому сравнить изменённую имплементацию контракта Staking с верифицированным кодом актуальной имплементации на etherscan - отличие лишь в новой добавленной функции setReward.