From b7033394dd34d44ce3045b66e487ee155dea6974 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Fri, 19 Jun 2026 19:56:54 -0300 Subject: [PATCH] feat(tests): add EIP-211 return data buffer tests for SELFDESTRUCT (#3029) * feat(tests): add EIP-211 return data buffer tests for SELFDESTRUCT behavior * Apply suggestions from code review Co-authored-by: Mario Vega --------- Co-authored-by: Mario Vega --- .../byzantium/eip211_return_data/__init__.py | 1 + tests/byzantium/eip211_return_data/spec.py | 17 ++++++ .../eip211_return_data/test_selfdestruct.py | 53 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/byzantium/eip211_return_data/__init__.py create mode 100644 tests/byzantium/eip211_return_data/spec.py create mode 100644 tests/byzantium/eip211_return_data/test_selfdestruct.py diff --git a/tests/byzantium/eip211_return_data/__init__.py b/tests/byzantium/eip211_return_data/__init__.py new file mode 100644 index 0000000000..610ca7b632 --- /dev/null +++ b/tests/byzantium/eip211_return_data/__init__.py @@ -0,0 +1 @@ +"""Tests for EIP-211 return data buffer behavior.""" diff --git a/tests/byzantium/eip211_return_data/spec.py b/tests/byzantium/eip211_return_data/spec.py new file mode 100644 index 0000000000..fb0d55403a --- /dev/null +++ b/tests/byzantium/eip211_return_data/spec.py @@ -0,0 +1,17 @@ +"""Defines EIP-211 specification reference.""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ReferenceSpec: + """Defines the reference spec version and git path.""" + + git_path: str + version: str + + +ref_spec_211 = ReferenceSpec( + git_path="EIPS/eip-211.md", + version="N/A", +) diff --git a/tests/byzantium/eip211_return_data/test_selfdestruct.py b/tests/byzantium/eip211_return_data/test_selfdestruct.py new file mode 100644 index 0000000000..7636ddbe5f --- /dev/null +++ b/tests/byzantium/eip211_return_data/test_selfdestruct.py @@ -0,0 +1,53 @@ +"""Test SELFDESTRUCT return data buffer behavior.""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Op, + StateTestFiller, + Transaction, +) + +from .spec import ref_spec_211 + +REFERENCE_SPEC_GIT_PATH = ref_spec_211.git_path +REFERENCE_SPEC_VERSION = ref_spec_211.version + + +@pytest.mark.valid_from("Byzantium") +def test_selfdestruct_clears_return_data( + state_test: StateTestFiller, + pre: Alloc, +) -> None: + """ + Test SELFDESTRUCT returns empty data after an inner call returns data. + + The selfdestructing contract first performs a call that leaves 32 bytes in + its own return-data buffer. The outer caller must still observe empty + return data from the selfdestructing call. + """ + returns_32 = pre.deploy_contract( + code=Op.MSTORE(0, 0x112233) + Op.RETURN(0, 32) + ) + + selfdestructs = pre.deploy_contract( + code=Op.POP(Op.CALL(address=returns_32, ret_size=0)) + + Op.SELFDESTRUCT(Op.CALLER) + ) + + caller = pre.deploy_contract( + code=Op.SSTORE( + 0, + Op.CALL(address=selfdestructs, ret_size=0), + ) + + Op.SSTORE(1, Op.RETURNDATASIZE) + ) + + tx = Transaction(sender=pre.fund_eoa(), to=caller) + + state_test( + pre=pre, + tx=tx, + post={caller: Account(storage={0: 1, 1: 0})}, + )