1

I ran into an EVM edge case. Is it correct that extcodesize(addr) is not zero, after calling selfdestruct on addr in the same transaction?

This behavior seems strange and I could not find any documentation on it.

2

I was able to reproduce your issue with the following code on Remix (You can check the different behavior between calling extcodesize in the same tx or in a subsequent one)

pragma solidity ^0.8.10;


contract Test {
    SelfDestruct instance;
    
    constructor() {
        redeploy();
    }
    
    function redeploy() public {
        instance = new SelfDestruct();    
    }
    
    function killInstanceAndGetCodeSize() public returns (uint256) {
        killInstance();
        return getCodeSize();
    }
    
    function killInstance() public {
        instance.kill();
    }
    
    function getCodeSize() public view returns (uint256 codeSize) {
        
        address addr = address(instance);
        
        assembly {
             codeSize := extcodesize(addr)
        }
    }  
}

contract SelfDestruct {
  function kill() public {
      selfdestruct(payable(address(0)));
  }
}

The reason for that behavior can be explained by looking at the geth implementation of selfdestruct.

// The account's state object is still available until the state is committed, // getStateObject will return a non-nil account after Suicide.

This is actually a logical behavior, as you have to take the possibility of reverts into account, plus you cannot leave another contract in an unstable state in the middle of a transaction if you decide to self-destruct. Until the state is committed, the self-destructed contract is still fully accessible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.