feat: add E2E tests for EIP-6780 (SELFDESTRUCT only in same transaction)#8
Open
BenderVeChain wants to merge 9 commits intomainfrom
Open
feat: add E2E tests for EIP-6780 (SELFDESTRUCT only in same transaction)#8BenderVeChain wants to merge 9 commits intomainfrom
BenderVeChain wants to merge 9 commits intomainfrom
Conversation
…lity Replace hand-assembled EVM bytecode with Solidity contracts: - contracts/Destructible.sol: exposes destroy(recipient) via SELFDESTRUCT - contracts/Factory.sol: deploys a child and calls SELFDESTRUCT in same tx - contracts/gen.go: go:generate directive (solc:0.8.28 --evm-version cancun) - contracts/compiled/: pre-compiled ABI + bin artifacts Test logic is unchanged; all 4 EIP-6780 behaviours are covered: 1. Pre-fork: SELFDESTRUCT opcode is valid (does not revert) 2. Post-fork: pre-existing contract not deleted (code persists after destroy()) 3. Post-fork: same-tx creation IS deleted (Factory.deployAndDestroy()) 4. Post-fork: SELFDESTRUCT to self is a no-op (code + balance unchanged)
Test 1 (TestEIP6780_PostFork_PreExistingContractNotDeleted):
- Was checking HasCode at PostForkRevision (block 1), but the deploy tx
may be mined at block 2+, so block 1 state doesn't have the contract.
- Fix: use default 'best' revision for the post-deploy HasCode check.
Test 2 (TestEIP6780_PostFork_SelfDestructToSelfIsNoop):
- Was sending a plain VET transfer to Destructible which had no receive()
function — Solidity reverts plain transfers to contracts without a
receive()/fallback().
- Fix: add 'receive() external payable {}' to Destructible.sol and
recompile artifacts.
Root causes (both confirmed by running tests against a live network):
1. TestEIP6780_PostFork_PreExistingContractNotDeleted:
The check at line 158 (HasCode after SELFDESTRUCT on pre-existing contract)
was failing because the default Thor branch ('evm-upgrades') does not
contain EIP-6780 yet — vechain/thor#1590 is still open. Update
defaultThorBranch to 'moglu/eip6780' so local 'make test' and CI (when
THOR_BRANCH is not set) use the branch that implements opSuicide6780.
2. TestEIP6780_PostFork_SelfDestructToSelfIsNoop:
The funding tx (Step 2) used 21_000 gas. In VeChain, 21_000 is the base
clause cost; calling receive() on a contract requires slightly more
(~21055 total). Increased to 50_000 so the transfer succeeds.
Both fixes verified green locally with THOR_EXISTING_PATH=/tmp/thor_eip6780.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds end-to-end tests for EIP-6780, implemented in vechain/thor#1590.
EIP-6780 restricts
SELFDESTRUCT: a contract can only be fully deleted (code + storage removed) ifSELFDESTRUCTis executed in the same transaction that created it. CallingSELFDESTRUCTon a pre-existing contract only transfers the balance — the contract code and storage persist.Test cases
TestEIP6780_PreFork_SelfDestructExecutesSELFDESTRUCT(0xff) is a valid opcode and does not revertTestEIP6780_PreFork_OpcodeValidTestEIP6780_PostFork_PreExistingContractNotDeletedSELFDESTRUCTon a pre-existing contract transfers balance only — code and storage surviveTestEIP6780_PostFork_SameTxCreationDeletedSELFDESTRUCTon it in the same tx — child has no code afterwards (same-tx exception)TestEIP6780_PostFork_SelfDestructToSelfIsNoopSELFDESTRUCTwith self as beneficiary is a no-op — contract survives and balance is unchangedImplementation notes
eip5656pattern.helper.BuildTx/SendTransaction/WaitForReceipt) are used for all persistent-state assertions.InspectClausesis used for stateless opcode-validity checks (pre/post-fork comparisons).CREATE+CALL(child)in a single execution context to exercise the EIP-6780 same-tx deletion path.thor.CreateContractAddress(txID, clauseIndex, creationCount).Related
opSuicide6780in Cancun ISA)