Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable SELFDESTRUCT EIP #2751

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions EIPS/eip-draft_disable_selfdestruct.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
eip: <to be assigned>
title: Disable SELFDESTRUCT
author: Alexey Akhunov (@AlexeyAkhunov)
discussions-to: https://ethereum-magicians.org/t/eip-for-disabling-selfdestruct-opcode/4382
status: Draft
type: Standards Track
category: Core
created: 2020-06-25
---

<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. This is the suggested template for new EIPs. Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. The title should be 44 characters or less.-->
Disable SELFDESTRUCT

## Simple Summary
<!--"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP.-->
Make `SELFDESTRUCT` EVM operation no-op (effectively disable). Contracts will not be able to delete themselves.

## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
Althouth `SELFDESTRUCT` originally came with EVM to help clean up the state, we learnt that in practice it did not achieve this objective on

Choose a reason for hiding this comment

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

Althouth should read although

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Althouth `SELFDESTRUCT` originally came with EVM to help clean up the state, we learnt that in practice it did not achieve this objective on
Although `SELFDESTRUCT` originally came with EVM to help clean up the state, we learnt that in practice it did not achieve this objective on

Copy link
Contributor

Choose a reason for hiding this comment

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

Ooh, how did you do this @lightclient?

Copy link
Member

@lightclient lightclient Jul 17, 2020

Choose a reason for hiding this comment

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

There should be a plus/minus button as part of the comment interface :) (something like in #6 here https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request)

sufficient scale, and is on balance a burden of extra complexity and unintended effects (GasToken2 and polymorphic contracts).

## Motivation
<!--The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright.-->
Operation `SELFDESTRUCT` (formerly `SUICIDE`) was in the EVM from the beginning, and its purpose was to incentivise clearing the state, by giving the
caller gas refund. In practice, this incentivisation turned out to be very limited, and the designed purpose was not archieved. However, `SELFDESTRUCT`
brings significant amount of complexity to the EVM. It is responsible for some of the most arcane edge cases in the EVM semantics.
Copy link
Contributor

Choose a reason for hiding this comment

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

Strongly agree on this. In particular, the existence of this opcode significantly increases the complexity of many forms of caching, as SELFDESTRUCT can potentially delete an unbounded number of storage slots.

Copy link
Contributor

Choose a reason for hiding this comment

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

If selfdestruct did not delete those storage slots it would empower a new kind of upgrade pattern (create2 reincarnations) while reducing SELFDESTRUCT complexity.

I don't think geth ever clears those storage slots from the state trie; it checks if there was a recent self-destruct. A reincarnation could fork the network if not enough nodes remain aware of the selfdestruct and reference a quantum storage slot.

It is also used as a vehicle to run an efficient arbitrage of gas prices (GasToken2), which
ironically lead to the increase use of the state. Introduction of `CREATE2` opcode in Constantinople upgrade created a new phenomenom of
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ironically lead to the increase use of the state. Introduction of `CREATE2` opcode in Constantinople upgrade created a new phenomenom of
ironically lead to the increase use of the state. Introduction of `CREATE2` opcode in Constantinople upgrade created a new phenomenon of

polymorthic contracts, i.e. contracts that can change their bytecode over time, while residing on the same address. Polymorphic contracts are limited
in their use, because changing the bytecode via `SELFDESTRUCT` + `CREATE2` clears all the contract storage, making contract lose all its data,
and making it unsuitable to replace Proxy Pattern as a technique for upgradable contracts. Removing the effect of `SELFDESTRUCT`
will reduce complexity of EVM going forward, disable GasToken2 (but not GasToken1, which is based on storage clearing refunds), and make
polymorthic contracts impossible.
## Specification
<!--The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
After certain block number, the semantics of `SELFDESTRUCT` becomes the same as the combination of `POP`, followed by transferring remaining ETH
to the address popped from the stack, followed by `STOP`. Gas cost is the same as the gas cost of non-zero value transfer, which is 9000 gas. No gas refund is given.
Copy link
Contributor

Choose a reason for hiding this comment

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

This gas scheme will make it cheaper to create new account via SELFDESTRUCT (which costs 30000 right now). Better either:

  • Keep the current SELFDESTRUCT gas cost: 5000 + 25000 if new account.
  • Or, increase the base to 9000 like this but also with the 25000 new account penalty: 9000 + 25000 if new account.

Also note that 9000 comes from CALL opcode, but SELFDESTRUCT is not exactly the same as CALL transfer because the former will never execute the target if it's a contract.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's currently cheapest to create an account using a regular 21000 transfer

Copy link
Member

Choose a reason for hiding this comment

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

the address popped from the stack, followed by STOP.

This suggests selfdestruct can be executed multiple times. Is that the goal?

Copy link
Member

Choose a reason for hiding this comment

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

I don't think there's any point introducing new pricing here, if the specification is that SELFDESTRUCT is replaced with CALL(<addr>, <value>, gas=0, ..) and STOP, then just state that and apply the gas rules of those two.

Copy link
Contributor

@wjmelements wjmelements Jun 30, 2020

Choose a reason for hiding this comment

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

This operation should be cheaper than CALL because it doesn't need to load code or create an execution context.

Copy link
Member

Choose a reason for hiding this comment

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

because it doesn't need to load code or create an execution context.

This EIP is changing the semantics of SELFDESTRUCT. From the current description it is not clear whether it turns into a non-executing transfer or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, turning it into an executing transfer would be a nice EVM unification/simplification. SELFDESTRUCT is currently one of the "sneakiest" ways to add funds to an address; a capability that people often forget about.

Copy link
Contributor

Choose a reason for hiding this comment

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

@carver Developers only "forget" about it because of deceptive Solidity syntax. Nobody should assume their contract is "nonpayable". This does not change that because miners can still break that assumption via coinbase.


## Rationale
<!--The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.-->
Disabling `SELFDESTRUCT` is the simplest and most effective way to remove its negative effects.

## Backwards Compatibility
<!--All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright.-->
Backwards incompatible and requres a hard fork.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Backwards incompatible and requres a hard fork.
Backwards incompatible and requires a hard fork.


## Test Cases
<!--Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable.-->
There are a lot of test in the standards suite related to `SELFDESTRUCT` and its edge cases. These need to be modified for the new no-op semantics.

## Implementation
<!--The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details.-->
Implementation is likely to be trivial - introducing the eip flag and replacing the old, complex semantics, with the new, simple semantics.

## Security Considerations
<!--All EIPs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. EIP submissions missing the "Security Considerations" section will be rejected. An EIP cannot proceed to status "Final" without a Security Considerations discussion deemed sufficient by the reviewers.-->
At this point, author of this EIP is not aware of any class of smart contracts that rely on `SELFDESTRUCT` for their functionality and security, with the exception of
Copy link
Contributor

Choose a reason for hiding this comment

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

Some projects are using a ephemeral contracts pattern to generate payment accounts, to withdraw from such accounts a contract is deployed on them (using CREATE2), the withdrawal takes place and the contract it's self-destruct.

Because of the ephemeral nature of those accounts, authentication can be skipped (either the transaction fails and the account is never created, or the transaction success and the account is emptied). This would still be a safe pattern as long as the project never reuses those addresses, but it would endanger funds otherwise.

A good example of this pattern can be found on UniswapEX (https://github.com/UniswapEx/exchange/blob/master/contracts/libs/Fabric.sol), I think that UniswapEX is not affected, because those accounts are never re-used, but we would need to check if other projects are using the same pattern while re-using accounts.

GasToken2 contract and similar.

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).