Selfdestruct and Redeploy in the same transaction using CREATE2 fails

:computer: Environment

Remix

:memo:Details

Redeploying the contract with the same address using the CREATE2 in the same transaction, in which it gets selfdestruct() seems to fail.
Tx β†’ selfdestruct() β†’ redeploy using create2 β†’ FAIL
Tx1 β†’ selfdestruct() Tx2 β†’ redeploy using create2 β†’ SUCCESS

Why is it that we cannot selfdestruct and redeploy in the same transaction?

:1234: Code to reproduce

pragma solidity ^0.8.0;


contract Test {
    function name() public pure returns(string memory) {
        return "Testing Redeploy in Same Transaction";
    }
    function destroy() public {
        address _addr = payable(address(this)); 
        assembly {
            selfdestruct(_addr)
        }
    }
}

contract TestCreate2 {
    
    Test public t;
    
    function deploy() public {
        t = new Test{salt: bytes32(0)}();
    }
    
    function checkName() public view returns(string memory){
        return t.name();
    }
    
    function destroyTest() public {
        t.destroy();
    }
    // This fails...Why?
    function destroyAndRedeploy() public {
        t.destroy();
        TestCreate2(address(this)).deploy();
    }

}
1 Like

Welcome back @sarang! This is a limitation of the EVM. When a contract selfdestructs it is only marked for destruction at the very end of the transaction. Only then its code is completely puged. So if you try to selfdestruct and recreate immediately, it will not work as it will see there is still code in the address.

1 Like

@frangio Thanks for the reply. :slight_smile:

I’m trying to understand the design decision behind this limitation. Is this a feature or a bug? :joy:

As far as I have assessed this issue, It does not display any security concerns. Please let me know if I’m missing something at my assessment.

It’s certainly not a bug, but I’m not sure if the design decision was put in place as a feature or as mitigation for some sort of issue.

Security concerns about what are you asking?