TGViewer
Из Solidity в AI и дальше Из Solidity в AI и дальше @solidityset · 2.49K subscribers
Post #1464 637
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;


// Target contract with a function that consumes some gas
contract Target {
uint256 private _storedData = 0;
function execute(bytes memory _data) external {
// Simulate some work that consumes gas
uint256 i;
while(i < 100) {
i++;
_storedData += i;
}
}
}


// Relayer contract vulnerable to insufficient gas griefing
contract Relayer {
mapping (bytes => bool) public executed; // Replay protection mapping
address public target;


constructor(address _target) {
target = _target;
}


function forward(bytes memory _data) public {
// Check replay protection
require(!executed[_data], "Replay protection");
executed[_data] = true;


// Vulnerability: External call is made, but its success status is NOT checked.
// If target.call runs out of gas (due to limited gas sent by attacker),
// this function DOES NOT revert. The state change above persists.
target.call(abi.encodeWithSignature("execute(bytes)", _data));
}
}


Функция Relayer.forward помечает параметр _data как выполненный до вызова контракта Target и, что критически важно, не проверяет возвращаемое значение успешности вызова target.call. Злоумышленник использует эту уязвимость, отправляя транзакцию с ровно таким количеством газа, которого хватит для выполнения проверки require и строки executed[_data] = true, но недостаточно для завершения внутренней логики вызова target.call. Внешний вызов завершается неудачно из-за нехватки газа, однако транзакция в контракте Relayer продолжается и успешно завершается, поскольку ошибка не была обнаружена. В результате флаг executed устанавливается в true, портя состояние системы и делая невозможным успешную передачу реального _data — даже несмотря на то, что функция Target.execute в рамках атакующей транзакции так и не была полностью выполнена.

Как поправить: Хотя общая рекомендация предлагает «явные проверки газа», для конкретной уязвимости (манипуляция потоком выполнения через нехватку газа при внешнем вызове) наиболее прямое и надежное решение — проверять статус успешности внешнего вызова.

Низкоуровневый метод .call возвращает булево значение success (успех). Это значение обязательно должно проверяться. Если success равно false (что происходит, если внешний вызов откатывается или исчерпывает газ), вызывающая функция должна также откатиться — обычно с помощью require(success, "Сообщение об ошибке"). Это предотвращает успешное завершение транзакции в несогласованном состоянии.

Использование require(gasleft() > MIN_GAS_NEEDED) перед внешним вызовом, как правило, менее эффективно для решения именно этой проблемы, поскольку фактическое потребление газа внешним контрактом может быть непредсказуемым или намеренно завышено злонамеренным целевым контрактом. Проверка require(success) корректно обрабатывает результат независимо от причины сбоя.

// Исправленный фрагмент функции forward (внутри Relayer)

function forward(bytes memory _data) public {
require(!executed[_data], "Защита от повторного выполнения");
executed[_data] = true;

// Взаимодействие: выполнение внешнего вызова

(bool success, ) = target.call(abi.encodeWithSignature("execute(bytes)", _data));
require(success, "Внешний вызов завершился неудачно");

}


Эта исправленная логика гарантирует, что транзакция завершится и флаг executed будет установлен в true только в случае реального успешного выполнения target.call. Она напрямую предотвращает атаку манипуляции газом, откатывая всю транзакцию при неудаче внешнего вызова и тем самым сохраняя согласованность состояния.

#griefing
  • 👍 8
  • ❤ 1
  • 👌 1
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 →