TGViewer
Из Solidity в AI и дальше Из Solidity в AI и дальше @solidityset · 2.49K subscribers
Post #950 629
Foundry с 0. Часть 30

В завершении базовых постов по инвариант тестам стоит поднять тему Actor management.

В прошлом уроке мы написали более продвинутый тест от имени одного контракта, а теперь посмотрим, как организовать процесс теста, когда вызовы в наш WETH контракт идут от нескольких Handler, что имитирует вызовы функций от разных пользователей.

Как вы можете догадаться, что нам потребуется дополнительный контракт:

contract ActorManager is CommonBase, StdCheats, StdUtils {
Handler[] public handlers;

constructor(Handler[] memory _handlers) {
handlers = _handlers;
}

function sendToFallback(uint256 handlerIndex, uint256 amount) public {
uint256 index = bound(handlerIndex, 0, handlers.length - 1);
handlers[index].sendToFallback(amount);
}

function deposit(uint256 handlerIndex, uint256 amount) public {
uint256 index = bound(handlerIndex, 0, handlers.length - 1);
handlers[index].deposit(amount);
}

function withdraw(uint256 handlerIndex, uint256 amount) public {
uint256 index = bound(handlerIndex, 0, handlers.length - 1);
handlers[index].withdraw(amount);
}
}


Здесь мы создаем массив из объектов нашего контракта Handler и инициализируем их в конструкторе.

Далее нам также нужно повторить те же функции в Handler, которые мы планируем вызывать.

Обратите внимание на аргументы в этих функциях! Мы позволяем Foundry самому случайным образом выбрать один из наших Handler и послать вызов от его имени. Не забудьте использовать читкод bound(), чтобы Foundry мог использовать индекс контракта, который действительно есть в массиве.

Далее обновим наш контракт с тестом:

contract WETH_Multi_Handler_Invariant_Tests is Test {
WETH public weth;
ActorManager public manager;
Handler[] public handlers;

function setUp() public {
weth = new WETH();

for (uint256 i = 0; i < 3; i++) {
handlers.push(new Handler(weth));
// Send 100 ETH to handler
deal(address(handlers[i]), 100 * 1e18);
}

manager = new ActorManager(handlers);

targetContract(address(manager));
}

function invariant_eth_balance() public {
uint256 total = 0;
for (uint256 i = 0; i < handlers.length; i++) {
total += handlers[i].wethBalance();
console.log("Handler num calls", i, handlers[i].numCalls());
}
console.log("ETH total", total / 1e18);
assertGe(address(weth).balance, total);
}
}


В функции setUp() мы создаем объекты наших контрактов и пополняем балансы каждого созданного Handler.

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

В приведенном выше тесте мы хотим удостовериться, что баланс токенов WETH будет равен или больше балансам всех наших Handler контрактов.

Именно поэтому мы создаем новую переменную total, в которую записываем все значения от переменных wethBalance в каждом Handler.

Запускаем наш тест через консольную команду forge test и видим, что все прошло успешно без каких-либо откатов!

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

#foundry #lesson30
  • 👍 2
More from @solidityset
  1. Sep 22, 2026Какой язык программирования учить сейчас? На днях в Твиттере увидел небольшой пост о разви…
  2. Sep 18, 2026Интересная модель Jev Буквально пару дней назад в Твиттере многие начали обсуждение новой…
  3. Sep 14, 2026Графы повсюду Если вы также следите за новостями в мире ИИ, то наверняка уже все чаще встр…
  4. Sep 10, 2026GTA6, Cyberleek, блокчейн и безопасность Увидел несколько постов (тут и тут) про Cyberleek…
  5. Sep 9, 2026Работа с чистой энергией Дисклеймер Сегодня ава и название канала, наконец, поменялись. Я…
  6. Sep 9, 2026Channel name was changed to «Из Solidity в AI и дальше»
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →