The ERC20 standard does not specify the mint and burn mechanisms, it is therefore up to the developer to define them.

The OpenZeppelin ERC20 reference implementation implements a burn function that decreases both the account balance and the token total supply :

function _burn(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: burn from the zero address");

    _beforeTokenTransfer(account, address(0), amount);

    uint256 accountBalance = _balances[account];
    require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
    _balances[account] = accountBalance - amount;
    _totalSupply -= amount;

    emit Transfer(account, address(0), amount);
}

The account balance and the total supply are respectively decremented with _balances[account] = accountBalance - amount; and _totalSupply -= amount;.

Although the event Transfer assimilates the burn operation to a transfer to the zero address, this is not the case, and this event is purely conventional.

This _burn function is internal and therefore can only be called within the smart contract and derived contracts. It is up to the developer to decide how to use this feature, if necessary. For example, to allow users to burn their token, you could create a public burn function wrapping the subfunction :

function burn(uint256 amount) public {
    _burn(msg.sender, amount)
}

Regarding the zero address, it is true that you can burn tokens by transferring them directly to it. However, the tokens will not be destroyed and the total supply will remain the same. So we can say that may be using the burn function is more appropriate, although no one can prevent a user from sending and forever locking tokens at addresses 0x0 (OpenZeppelin does for this one but this is not required by the standard) or 0x1 for example.

Answer from clement on Stack Exchange
Top answer
1 of 1
10

The ERC20 standard does not specify the mint and burn mechanisms, it is therefore up to the developer to define them.

The OpenZeppelin ERC20 reference implementation implements a burn function that decreases both the account balance and the token total supply :

function _burn(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: burn from the zero address");

    _beforeTokenTransfer(account, address(0), amount);

    uint256 accountBalance = _balances[account];
    require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
    _balances[account] = accountBalance - amount;
    _totalSupply -= amount;

    emit Transfer(account, address(0), amount);
}

The account balance and the total supply are respectively decremented with _balances[account] = accountBalance - amount; and _totalSupply -= amount;.

Although the event Transfer assimilates the burn operation to a transfer to the zero address, this is not the case, and this event is purely conventional.

This _burn function is internal and therefore can only be called within the smart contract and derived contracts. It is up to the developer to decide how to use this feature, if necessary. For example, to allow users to burn their token, you could create a public burn function wrapping the subfunction :

function burn(uint256 amount) public {
    _burn(msg.sender, amount)
}

Regarding the zero address, it is true that you can burn tokens by transferring them directly to it. However, the tokens will not be destroyed and the total supply will remain the same. So we can say that may be using the burn function is more appropriate, although no one can prevent a user from sending and forever locking tokens at addresses 0x0 (OpenZeppelin does for this one but this is not required by the standard) or 0x1 for example.

🌐
Etherscan
etherscan.io › token › 0xa2fe5e51729be71261bcf42854012827bc44c044
Burn (BURN) | ERC-20 | Address: 0xa2fe5e51...7bc44c044 | Etherscan
... OVERVIEW$BURN token is an hyper-deflationary token that is built to become more scarce with each transaction that takes place within Burn economy. ... [{"inputs":[{"internalType":"string","name":"name__","type":"string"},{"internalType"...
Discussions

Is 0x0000000000000000000000000000000000000000 a "burn address"?
No the correct burner address is: 0x7C291eB2D2Ec9A35dba0e2C395c5928cd7d90e51 This is where you send all the funds you do not want More on reddit.com
🌐 r/ethereum
53
13
July 26, 2018
Sending ERC20 To Burn Address
Hello, Just a quick question. If i have erc20 tokens and i send them to the burn address manually does it automatically lower the supply (openzeppelin erc20) Or will i have to call burn function and do it that method? Thank you More on forum.openzeppelin.com
🌐 forum.openzeppelin.com
0
0
November 15, 2021
How to burn tokens erc20?

Send me the tokens instead 😪

More on reddit.com
🌐 r/ethereum
3
0
February 21, 2021
blockchain - How to burn token of Smart contract from another Smart contract? - Stack Overflow
I've tried many solutions but still ... function_burn ... Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. ... Since the function is internal, it means it can only be accessed internally within the contract itself or in contracts deriving from it. You can either use ERC20Burnable extension ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
BitcoinTalk
bitcointalk.org › index.php
erc20 burn address?
Bitcoin Forum > Alternate cryptocurrencies > Altcoin Discussion > erc20 burn address?
🌐
Wemix
docs.wemix.com › en › tutorial › erc-20-token › burn-erc-20-token
Burn ERC-20 Token | WEMIX3.0 (ENG) | WEMIX3.0
First, let's proceed with the burning process by sending the ERC-20 Token to the Dead Wallet address.
🌐
Venly
docs.venly.io › docs › how-to-burn-erc20-tokens
Burn ERC20 Token
Burning an ERC-20 token means permanently removing a certain number of tokens by sending them to an address from which they can never be retrieved, typically an address with no private key (commonly called a "burn address").
🌐
Reddit
reddit.com › r/ethereum › is 0x0000000000000000000000000000000000000000 a "burn address"?
r/ethereum on Reddit: Is 0x0000000000000000000000000000000000000000 a "burn address"?
July 26, 2018 -

I see that https://etherscan.io/address/0x0000000000000000000000000000000000000000 owns almost $3 billion in tokens plus $3.5 million ETH.

Is this a burn address? I know in Bitcoin that one can send BTC to an address where no-one knows the private key. Is the same true in Ethereum? If someone wanted to prove that they had "destroyed" a token could they send it to the above-referenced address?

Find elsewhere
🌐
OpenZeppelin
forum.openzeppelin.com › support › contracts
Sending ERC20 To Burn Address - Contracts - OpenZeppelin Forum
November 15, 2021 - Hello, Just a quick question. If i have erc20 tokens and i send them to the burn address manually does it automatically lower the supply (openzeppelin erc20) Or will i have to call burn function and do it that method? T…
🌐
GitHub
github.com › OpenZeppelin › openzeppelin-contracts › blob › master › contracts › token › ERC20 › ERC20.sol
openzeppelin-contracts/contracts/token/ERC20/ERC20.sol at master · OpenZeppelin/openzeppelin-contracts
revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } · /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead · */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } ·
Author   OpenZeppelin
🌐
GitHub
github.com › OpenZeppelin › openzeppelin-contracts › blob › master › contracts › token › ERC20 › extensions › ERC20Burnable.sol
openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol at master · OpenZeppelin/openzeppelin-contracts
* See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least · * `value`. */ function burnFrom(address account, uint256 value) public virtual { _spendAllowance(account, _msgSender(), value); _burn(account, value); } }
Author   OpenZeppelin
🌐
Reddit
reddit.com › r › ethereum › comments › 8tgkld › how_to_burn_tokens_erc20
r/ethereum - How to burn tokens erc20?
February 21, 2021 -

guys someone know how to burn the tokens erc20? i tried to send soem tokens to this address 0x0000000000000000000000000000000000000000 but mycrypto and mew don't let me do it. Tried even with contract options but nothings! Any options?

🌐
OpenZeppelin
docs.openzeppelin.com › contracts-stylus › 0.1.0 › erc20-burnable
ERC-20 Burnable | OpenZeppelin Docs
{ #[entrypoint] struct Erc20Example { #[borrow] Erc20 erc20; } } #[public] #[inherit(Erc20)] impl Erc20Example { pub fn burn(&mut self, value: U256) -> Result<(), Vec<u8>> { // ... self.erc20.burn(value).map_err(|e| e.into()) } pub fn burn_from( &mut self, account: Address, value: U256, ) -> Result<(), Vec<u8>> { // ...
🌐
Stack Overflow
stackoverflow.com › questions › 71984775 › how-to-burn-token-of-smart-contract-from-another-smart-contract
blockchain - How to burn token of Smart contract from another Smart contract? - Stack Overflow
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; contract BurnOther{ ERC20Burnable _token; constructor(address token_){ _token = ERC20Burnable(token_); } function burnOther(uint256 amount) external { _token.burnFrom(msg.sender, amount); } }
Top answer
1 of 3
20

According to Jeff Wilcke, the right way to burn ETH is to create a contract which immediately self destructs and sends to its own address, or just send ether to his deployed contract which does it all for you:

https://etherscan.io/address/0xb69fba56b2e67e7dda61c8aa057886a8d1468575#code

Here's the code:

pragma solidity ^0.4.11;

contract Burner {
    uint256 public totalBurned;

    function Purge() public {
        // the caller of purge action receives 0.01% out of the
        // current balance.
        msg.sender.transfer(this.balance / 1000);
        assembly {
            mstore(0, 0x30ff)
            // transfer all funds to a new contract that will selfdestruct
            // and destroy all ether in the process.
            create(balance(address), 30, 2)
            pop
        }
    }

    function Burn() payable {
        totalBurned += msg.value;
    }
}

A simpler example without assembly is:

contract GetsBurned {

    function () payable {
    }

    function BurnMe () {
        // Selfdestruct and send eth to self, 
        selfdestruct(address(this));
    }
}

After calling BurnMe on the second example, you'll see that the address of the contract no longer has any balance or code. The ETH just vanishes!

2 of 3
5

In the case you need to destroy only tokens developed on Ethereum platform, this functionality may be embedded into the smart contract itself:

/**
 * @dev Burns a specific amount of tokens.
 * @param _value The amount of token to be burned.
 */
function burn(uint256 _value) public {
    require(_value > 0);
    require(_value <= balances[msg.sender]);
    // no need to require value <= totalSupply, since that would imply the
    // sender's balance is greater than the totalSupply, which *should* be an assertion failure

    address burner = msg.sender;
    balances[burner] = balances[burner].sub(_value);
    totalSupply = totalSupply.sub(_value);
    Burn(burner, _value);
}

Source - OpenZeppelin

You may want to embed some additional security check like verifying the address of the function caller if you develop your own centralized token.

🌐
Reddit
reddit.com › r/ethereum › is there an "official" burn address for ethereum?
r/ethereum on Reddit: Is there an "official" burn address for Ethereum?
May 17, 2021 - The problem with that is that the ERC-20 standard doesn't allow sending to the 0x0 address unless you use the _burn funtion, which is usually not callable by normal users.
🌐
Stack Overflow
stackoverflow.com › questions › 69866141 › erc20-mint-to-the-zero-address-exception-when-trying-to-buy-my-own-erc20-token
ethereum - ERC20: mint to the zero address exception when trying to buy my own ERC20 token (based on OpenZeppelin) from my own simple DEX - Stack Overflow
* * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } Notice how I commented out the require line in _mint. ... /* Adapted from from https://for
🌐
Twitter
twitter.com › addressburn
Twitter
JavaScript is not available · We’ve detected that JavaScript is disabled in this browser. Please enable JavaScript or switch to a supported browser to continue using twitter.com. You can see a list of supported browsers in our Help Center · Help Center · Terms of Service Privacy Policy ...
🌐
20lab
20lab.app › 20lab - token generator › tools › erc-20 burn tokens › ethereum burn tokens
Burn Ethereum ERC-20 Tokens - Destroy Tokens to Reduce Supply
Burn your Ethereum ERC-20 tokens permanently. Native burn() function or 0xdead address burn supported. Reduce circulating supply on-chain.
🌐
Reddit
reddit.com › r/ethdev › how to call burn function of erc20 token from another contract?
r/ethdev on Reddit: How to call burn function of erc20 token from another contract?
November 7, 2023 -

Suppose I have a contract "A" which can mint "X" tokens to address "R" . Then suppose I have another Contract "B" which can mint "Y" tokens to address "R" based on a condition that is , address "R" have to burn "K" amount of "X" token to mint "K" amount of "Y" token.

I have a custom mint function in contract "B", where I first try to burn the "X" token then mints "Y" token to the wallet address. As I am using Interface to call the burn function in contract "A", the contract "B"'s address is calling the `burn(uint256 amount)` function not the wallet address. And for this reason I am getting errors while burning. How can I solve this problem ?