Complete verkle trie construction for motivation: HackMD - Collaborative Markdown Knowledge Base
Analysis on applications that would be affected by this change: Impact Analysis of Neutering SELFDESTRUCT - Dev Update #2 - HackMD
Abstract says:
The new functionality will be only to send all Ether in the account to the caller.
I believe you intended to say it sends to a beneficiary (instruction input address) and not the caller.
Also Iâll paste @chfastâs comment from draft PR here:
You forgot to mention that
SENDALL
still terminates execution.
Should it be repriced, as itâs now only updating balance?
The SELFDESTRUCT
has one additional quirk not handled here: when the beneficiary is the selfdestructing address itself the balance is burned instead of being transferred.
Agreed that it should be mentioned explicitly in the EIP: EIP-4758: Deactivate selfdestruct by dankrad ¡ Pull Request #4758 ¡ ethereum/EIPs ¡ GitHub.
But the new behavior can also be inferred from the EIP: the account removal doesnât happen so a SENDALL
with self as beneficiary is basically a no-op that just terminates execution of the current frame.
GitHub - jwasinger/eth-selfdestruct-analysis . This is an updated impact analysis which looks at usage of SELFDESTRUCT
after the London hard fork and identifies contracts with large holdings that could be affected by the changes in EIP-4758
As mentioned by @chfast SELFDESTRUCT
can be used to burn ETH by âselfdestructingâ to the current address. There is another quirk however which is changed by this EIP:
SELFDESTRUCT
does not immediately destroy code and send the balance. This is done after all call frames are done and thus every opcode of the transaction has been executed. Only then are the following steps executed:
1. Send all ETH of the contract to the beneficiary
2. Destroy the contract (code = empty, balance = empty, nonce = 0, balance = 0)
Due to this order it is thus possible to destroy ETH. Also, notice that it is possible to do âmultipleâ selfdestructs by calling the selfdestruct from another contract multiple times. It is possible to first SELFDESTRUCT
to address A
and then SELFDESTRUCT
to address B
. In this case, the beneficiary is B
, not A
. If this changes, it should be specified on the EIP. It now seems that SENDALL
sends all ETH of the current contract to the beneficiary and immediately exits the current call frame - which I guess is fine, but the EIP also states that it ârenamesâ SELFDESTRUCT
to SENDALL
which is due to these quirks not really the case.
I donât believe this is correct. The ETH is sent immediately. @gumb0 has double-checked this.
Oops, you are right, have semi-deleted my post.
I am a consumer of the reincarnation upgrade pattern. I built an NFT contract ownership system (0x000000000000c57CF0A1f923d44527e703F1ad70
on every chain) to facilitate this pattern. It helps us upgrade our contract without needing to re-approve and migrate every token for every protocol. Our storage footprint on the protocol would be much larger without SELFDESTRUCT
. The SLOAD
+DELEGATECALL
pattern, especially after Berlin, costs way too much for practical use in gas-denominated auctions, so we cannot use it.
I am willing to pay millions in gas to facilitate code changes. I do not see why code must be immutable but not storage. Perhaps there is a fair way to price a code change, and we could introduce a replacement opcode like SETCODE
.
The main drawback of SELFDESTRUCT
right now from an engineering perspective is that it doesnât take place until the end of the transaction, so I need two separate transactions to do the upgrade. This has prevented wider adoption, as you could not safely upgrade a token, for example, without risking being sandwiched.
Our production system heavily utilizes the CREATE2 and SELFDESTRUCT loop. We have a few million dollars of TVL, with more expected to arrive in the near future. The system wasnât designed to be modified once deployed and this EIP would fully brick our value-storage system, rendering funds inaccessible for users.
As a result, Iâm very opposed to this EIP. It breaks a system that allows us to deploy and undeploy smart contract proxies within the same block, which is good not only for gas costs and allowing lower storage utilization, but also for security. By never having code deployed on those contracts outside of very predetermined periods, we reduce our attack surface area significantly. It is frustrating to be punished for being at the forefront of security in smart contract development, and we strongly request that this EIP be reconsidered or modified in some way.
Perhaps a change to CREATE2 could be considered in concert with this, such that it checks for existing byte-code and quietly fails rather than reverting. That would allow our system to continue to function unimpeded by the implementation of this proposal.
Is there any progress on this EIP-4758??
What do you think on repricing CREATE and CREATE2 when constructor returns zero size? Nothing will be deployed, only constructor code will be executed from new address. Now this costs 32k
I have no strong opinions on this EIP and whether or not it is the right path forward.
Did want to flag for visibility though as part of this conversation, that this has impact on the BytecodeStorage.sol
library that we introduced in our ERC721-conforming âCoreContractâ at Art Blocks here: Contract bytecode for script storage by ryley-o ¡ Pull Request #299 ¡ ArtBlocks/artblocks-contracts ¡ GitHub.
This would not be a breaking change perse, so if this EIP were approved+implemented it wouldnât be a dramatic concern point for our team by any means.
That said, a meaningful part of our rationale for adding this functionality in the first place was the intention to be mindful custodians of our impact on state bloat (see Allow for cleanup of unused contract bytecode for script storage by jakerockland ¡ Pull Request #304 ¡ ArtBlocks/artblocks-contracts ¡ GitHub for context).
It sounds like this rationale of ours may not hold water vs. the concerns around the state management complexity that comes with SELFDESTRUCT
which is totally valid and again not a matter that we have a strong opinion on.
tl;dr, weâre making use of SELFDESTRUCT
at Art Blocks, but it is in a way that is not dramatically impacted by this EIP in a way that we have strong concern aboutâI am sharing all of this for additional context/visibility and not because we have a strong opinion on the matter.
Not sure if this actually fully solves the problem that this EIP intends to capture, and again I definitely do not have a strong horse in this race, but has the approach of functionality limiting the amount of state change caused by a given usage of SELFDESTRUCT, by way of changing the op-code pricing for the opcode in order to more directly bound state change to the current gas limit, an approach that has been considered?
Could definitely understand that this type of approach would be impractical with regards to the client complexity it would add to calculate gas costs in a way that fits the state-change-bounding constraints that are driving this PR, but figured I would ask!
Related discussion regarding Shanghai inclusion: Shanghai Core EIP Consideration - #35 by wjmelements
That is an interesting idea. You could probably set it up so that CREATE2
will allow you to deploy the exact same bytecode to the same address, but fail for all other code.
Iâd be concerned about the case where someone expects SELFDESTRUCT
followed by a CREATE2
to clear storage, which wouldnât happen.
Could you elaborate?