@@ -108,7 +108,94 @@ TEST_F(state_transition, selfdestruct_double_revert)
108108
109109TEST_F (state_transition, selfdestruct_initcode)
110110{
111+ rev = EVMC_SHANGHAI ;
112+ tx.data = selfdestruct (0xbe_address);
113+
114+ expect.post [compute_create_address (tx.sender , tx.nonce )].exists = false ;
115+ expect.post [0xbe_address].exists = false ;
116+ }
117+
118+ TEST_F (state_transition, selfdestruct_initcode_amsterdam)
119+ {
120+ // A same-tx-created account that self-destructs ending with a zero balance must not be in the
121+ // final state (EIP-8246). In this test we use initcode.
122+ rev = EVMC_AMSTERDAM ;
111123 tx.data = selfdestruct (0xbe_address);
124+
125+ expect.post [compute_create_address (tx.sender , tx.nonce )].exists = false ;
126+ expect.post [0xbe_address].exists = false ;
127+ }
128+
129+ TEST_F (state_transition, selfdestruct_prefunded)
130+ {
131+ // Although burn is removed in EIP-8246, the deletion of a pre-funded account still happens.
132+ rev = EVMC_CANCUN ;
133+ const auto created = compute_create_address (tx.sender , tx.nonce );
134+ pre [created] = {.balance = 1 };
135+ tx.data = selfdestruct (0xbe_address); // Transfer to distinct beneficiary.
136+
137+ expect.post [created].exists = false ; // Removed, despite pre-existing in the state.
138+ expect.post [0xbe_address].balance = 1 ; // Pre-funded balance delivered to the beneficiary.
139+ }
140+
141+ TEST_F (state_transition, selfdestruct_prefunded_amsterdam)
142+ {
143+ // Although burn is removed in EIP-8246, the deletion of a pre-funded account still happens.
144+ rev = EVMC_AMSTERDAM ;
145+ const auto created = compute_create_address (tx.sender , tx.nonce );
146+ pre [created] = {.balance = 1 };
147+ tx.data = selfdestruct (0xbe_address); // Transfer to distinct beneficiary.
148+
149+ expect.post [created].exists = false ; // Removed, despite pre-existing in the state.
150+ expect.post [0xbe_address].balance = 1 ; // Pre-funded balance delivered to the beneficiary.
151+ }
152+
153+ TEST_F (state_transition, selfdestruct_prefunded_burn)
154+ {
155+ // Burn pre-funded ETH by self-destruct to self.
156+ rev = EVMC_CANCUN ;
157+ const auto created = compute_create_address (tx.sender , tx.nonce );
158+ pre [created] = {.balance = 1 };
159+ tx.data = selfdestruct (created);
160+
161+ expect.post [created].exists = false ; // Removed, despite pre-existing in the state.
162+ }
163+
164+ TEST_F (state_transition, selfdestruct_prefunded_burn_amsterdam)
165+ {
166+ // Burn is removed with EIP-8246, the balance must be preserved.
167+ rev = EVMC_AMSTERDAM ;
168+ const auto created = compute_create_address (tx.sender , tx.nonce );
169+ pre [created] = {.balance = 1 };
170+ tx.data = selfdestruct (created);
171+
172+ expect.post [created].balance = 1 ; // Balance preserved.
173+ expect.post [created].nonce = 0 ;
174+ expect.post [created].code = {};
175+ }
176+
177+ TEST_F (state_transition, selfdestruct_sibling_create_then_destruct_amsterdam)
178+ {
179+ // A contract created in one sub-call and self-destructed in a sibling sub-call of the same
180+ // transaction must still be removed (especially its code).
181+ rev = EVMC_AMSTERDAM ;
182+ static constexpr auto F = 0xfac0_address; // Factory address.
183+
184+ const auto runtime = selfdestruct (0xbe_address);
185+ const auto initcode = mstore (0 , push (runtime)) + ret (32 - runtime.size (), runtime.size ());
186+ const auto created = compute_create_address (F, 1 );
187+
188+ pre [F] = {.nonce = 1 ,
189+ .balance = 1 ,
190+ .code = mstore (0 , push (initcode)) +
191+ create ().input (32 - initcode.size (), initcode.size ()).value (1 )};
192+ pre [To] = {.code = call (F).gas (0xffffff ) + call (created).gas (0xffffff )};
193+ tx.to = To;
194+
195+ expect.post [created].exists = false ; // Created and destructed in the same tx -> removed.
196+ expect.post [0xbe_address].balance = 1 ; // Funds delivered to the beneficiary.
197+ expect.post [F] = {.nonce = 2 , .balance = 0 }; // F created one contract and sent it the balance.
198+ expect.post [To] = {};
112199}
113200
114201TEST_F (state_transition, massdestruct_shanghai)
0 commit comments