Skip to content

Conversation

@jwasinger
Copy link
Contributor

@jwasinger jwasinger commented Oct 15, 2025

  • previously, invocation of BalanceIncreaseSelfdestruct (transfer to recipient of selfdestruct) was duplicated in the hooked statedb and in the opcode handler for the selfdestruct opcode.
  • balance is burned immediately when the beneficiary of the selfdestruct is the sender, and the contract was created in the same transaction. Previously we emit two balance increases to the recipient (see above point), and a balance decrease from the sender.
  • Other than immediate balance transfer or burn, the other state changes related to account removal happen at transaction finalization. Let's invoke those hooks there.

@jwasinger jwasinger changed the title core: fix some incorrect EIP-6780 selfdestruct behavior core: fix some incorrect EIP-6780 selfdestruct tracer behavior Oct 17, 2025
@jwasinger jwasinger marked this pull request as ready for review October 17, 2025 06:54

// ExistBeforeCurTx returns true if a contract exists and was not created
// in the current transaction.
func (s *StateDB) ExistBeforeCurTx(addr common.Address) bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will rename this to reflect that the method returns true if the account exists and it is a contract.

evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct)
createdInTx := !evm.StateDB.ExistBeforeCurTx(scope.Contract.Address())

if createdInTx {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this section. Why is the balance burnt immediately and not at the tx end in case contract is new?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's part of the spec for 6780.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a general case in statedb.Finalize: if the contract being destroyed has balance > 0, that balance is burnt. Does that not cover this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically: I think this part was fine before and the createdInTx is not strictly needed. Let me know if I'm missing something.

s.hooks.OnBalanceChange(addr, bal.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestructBurn)
}
}
if s.hooks.OnNonceChangeV2 != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add OnNonceChange (v1) even tho it doesn't take in a reason.

@s1na
Copy link
Contributor

s1na commented Oct 20, 2025

I've now gone through the PR, quite a few good fixes there. Left a comment for the section where I couldn't follow the logic, why we change it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants