-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
1 changed file
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
--- | ||
eip: 7775 | ||
title: BURN opcode | ||
description: An opcode to burn native ether at the given address | ||
author: Dev Bear (@itsdevbear) | ||
discussions-to: https://ethereum-magicians.org/t/eip-7775-burn-opcode/21287 | ||
status: Draft | ||
type: Standards Track | ||
category: Core | ||
created: 2024-09-30 | ||
--- | ||
|
||
## Abstract | ||
|
||
This proposal introduces a `BURN` opcode to the EVM. When called, the opcode is to burn native ether at the address of the current evm context. | ||
|
||
## Motivation | ||
|
||
The motivation for this proposal is to provide a standardized and efficient way to burn native ether directly within the EVM. Historically, contracts such as the BeaconDepositContract have "burned" ether by making it irrecoverable from the given address. This approach can lead to confusion and potential misuse. By introducing a dedicated `BURN` opcode, we can ensure a clear and consistent method for burning native ether. This could become useful for Ethereum L2s when transferring ether back to the L1, as well as other EVM L1 chains that could leverage this for their cryptoeconomics. | ||
|
||
## Specification | ||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. | ||
|
||
### Behaviour | ||
|
||
The `BURN` opcode `(0xFC)` is introduced with the following behavior: | ||
|
||
1. Pops one 32-byte word from the top of the stack, treating these bytes as the `uint256` amount of native ether to be burned. | ||
2. Retrieves the current address from the EVM execution context. | ||
3. Checks the balance of the current address. | ||
4. If the amount to be burned is greater than the balance of the current address, the opcode `MUST` revert. | ||
5. If the amount to be burned is 0, the execution `MUST NOT` revert. | ||
6. Subtracts the amount from the current address's native ether balance. | ||
|
||
When `BURN` is used in the context of a DELEGATECALL or CALLCODE, the contract whose balance is to be manipulated is the contract that issued the DELEGATECALL or CALLCODE instruction. | ||
|
||
When `BURN` is used in the context of a STATICCALL the call `MUST` revert. | ||
|
||
### Gas Cost | ||
|
||
The base gas cost for the `BURN` opcode is 100 gas. The dynamic gas cost is determined as follows: | ||
|
||
1. If the value to be burned is 0, the dynamic gas cost is 0. | ||
2. If the account doesn't exist, or the balance of the account is 0, the dynamic gas cost is 0. | ||
3. Otherwise, the dynamic gas cost is 2800. | ||
|
||
The total gas cost for the `BURN` opcode is the sum of the base gas cost and the dynamic gas cost. | ||
|
||
### Pseudocode | ||
|
||
Example pseudocode for the `BURN` opcode: | ||
|
||
```python | ||
def op_burn(pc, interpreter, scope): | ||
# Consume the base gas cost | ||
interpreter.consume_gas(100) | ||
|
||
# Pop the value to be burned from the stack | ||
value_to_burn = scope.stack.pop() | ||
|
||
# If the value to be burned is 0, do not revert | ||
if value_to_burn == 0: | ||
return None | ||
|
||
# Retrieve the current address from the EVM execution context | ||
current_address = scope.contract.address() | ||
|
||
# Check the balance of the current address | ||
balance = interpreter.evm.state_db.get_balance(current_address) | ||
|
||
# If the value to be burned is greater than the balance, revert | ||
if value_to_burn > balance: | ||
return "ErrInsufficientBalance" | ||
|
||
# If the account balance is 0, return. | ||
if balance == 0: | ||
return None | ||
|
||
# Subtract the value from the current address's balance | ||
interpreter.evm.state_db.sub_balance(current_address, value_to_burn) | ||
|
||
# The account is known to exist at this point, thus we consume "warm" gas. | ||
interpreter.consume_gas(2800) | ||
return None | ||
``` | ||
|
||
## Rationale | ||
|
||
The introduction of the `BURN` opcode helps clean up a piece of weird semantics in the Ethereum. Historically, burning native ether involved sending them to an address from which they could not be recovered, such as the zero address or a contract with no withdrawal functionality. This method is not only inefficient but also confusing for indexers and other tools that track token movements. By providing a dedicated `BURN` opcode, we eliminate this ambiguity and ensure that the act of burning tokens is explicit and standardized. | ||
|
||
Potential Pros: | ||
|
||
- Provides a clear and standardized method for burning native ether within smart contracts. | ||
- Allows for better accounting practices of native token within smart contracts. | ||
- Reduces the possibility of a smart contract exploit caused by native token that was marked as "burned" being unintetionally recovered. | ||
|
||
Potential Cons: | ||
|
||
- Does not help remove unrecoverable ether sitting in existing contracts. | ||
- New code in the clients | ||
- New concept needed to be added to the yellow paper. | ||
|
||
## Backwards Compatibility | ||
|
||
This EIP introduces a new opcode and thus must be activated via a scheduled hardfork. | ||
|
||
## Test Cases | ||
|
||
<!-- TODO --> | ||
|
||
## Reference Implementation | ||
|
||
<!-- TODO --> | ||
|
||
## Security Considerations | ||
|
||
- Potentially opens up misuse when using `DELEGATECALL`. | ||
|
||
Needs discussion. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |