What are the best practices for building Selfdestruct() functionality?

Best practices for building Selfdestruct() functionality

What is the best means to build and use the above functionality in a smart contract?

So as to help clean up older contracts in testnet and mainnet.

1 Like

Hi @pkr,

When I first started, I used to include selfdestruct in contracts for testnets, though didn’t want this included in production, so was easier not to include at all, than have code only for testnets.

Recently I have only used selfdestruct to attack a contract by forcibly sending Ether. (https://ethernaut.openzeppelin.com).

I will be interested to see other opinions on this.

Hi @pkr,

OpenZeppelin Contracts used to include a Destructible contract that used selfdestruct that was removed in OpenZeppelin Contracts 2.0

https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1254
Reasons for removal:

Destructible and TokenDestructible : selfdestruct should be used with tons of care because it’s not always safe to use, so it shouldn’t be as simple as inheriting a contract.

The risk with using selfdestruct is that it removes the bytecode from the account, and thus it becomes like a normal account. The implications of this can be pretty severe: all transactions sent to this account will now execute successfully, and all money sent to it will be lost forever.

For example, if the contract is a crowdsale and it is selfdestructed once the funding goal is reached, all following attemps to participate in the crowdsale will trap the ether in this black hole. The address would have been publicized in the internet, and it’s unlikely that all of those locations would be updated with a huge “DO NOT USE” sign. It’s better to encode this logic in the contract itself and keep the contract alive so that transactions are rejected from then on.

2 Likes

Thank you @abcoathup and @frangio …both of you bring up interesting points. I will read up on the resources shared by you and chalk out next steps.

My initial thinking for building selfdestruct into these contracts is to clean-up old invalid garbage contracts in testnet and mainnet.

The implementation and interaction with these contracts will be via an app that has proper on-boarding procedures. So hypothetically when we choose to retire a contract, the app will be re-wired to point to the new version of the contract.

Keen to understand how everyone else is building this into their app, using oz SDK upgradeable contracts.

Are you wiring your app to the Logic Smart Contract or Proxy Smart Contract?

1 Like

Hi @pkr,

OpenZeppelin SDK uses the “unstructured storage” proxy pattern, so the Proxy contracts storage is used, not the Logic contracts storage.

Using selfdestruct with upgradeable contracts are potentially unsafe operations, please see the documentation for details:
https://docs.openzeppelin.com/sdk/2.5/writing-contracts#potentially-unsafe-operations

1 Like