fluxswap

Протокол децентрализованной биржи (DEX) на Solidity, собранный в Foundry. Пулы ликвидности, роутер, стейкинг и timelock - с инвариантами и полным покрытием тестами.

fluxswap
TL;DR

Протокол децентрализованной биржи (DEX) на Solidity: пулы ликвидности, роутер, стейкинг и timelock. Контракт ворочает реальными средствами, поэтому баг - это не правка к следующему релизу, а потерянные деньги. Поэтому важны инварианты и полное покрытие тестами в Foundry, а не утверждение, что выглядит рабочим.

Введение

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

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

Код, который нельзя обновить постфактум

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

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

Pool.sol · bash
uint256 kBefore = reserveX * reserveY;
_swap(amountIn, amountOut);
require(reserveX * reserveY >= kBefore, "K");

Отдельные тесты проверяют конкретные входные данные, которые вы сами придумываете, поэтому проверяют лишь то, что вы уже предусмотрели. Инвариантные тесты в Foundry делают нечто более сильное: они случайно бомбардируют контракт тысячами последовательностей операций и после каждой проверяют, что правило все еще выполняется.

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

1000+
случайных последовательностей на инвариант
0
сценариев, ломающих правило постоянного произведения

Timelock, или время на реакцию

!
Внимание

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

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

Доказательство вместо надежды

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

Инварианты и что они гарантируют

ИнвариантЧто гарантирует
Постоянное произведениепроизведение резервов не падает после свопа
Сумма токеноввклады равны выводам плюс остаток
Выводникто не берет больше, чем вложил
Timelockизменения параметров отложены и публичны

Больше проектов

Другие работы из той же категории - посмотрите, как мы решаем похожие задачи.

Есть похожий проект?

Напишите нам - смета бесплатна и приходит в течение часа.