Skip to content

burn(...) function would enable burners to burn users assets without their consent #222

Description

@EmanHerawy

Hi team
I'm studying your implementation to learn Aptos Move development and noticed what appears to be a significant difference from standard token burning patterns. Your burn function allows privileged addresses to burn tokens from any user's account without their explicit consent or approval.
current implementation :

public entry fun burn(
        burner: &signer, from: address, amount: u64
    ) acquires TokenMetadataRefs, TokenState {
        let burner_addr = signer::address_of(burner);
        assert_is_allowed_burner(burner_addr);

        if (amount == 0) { return };

        primary_fungible_store::burn(
            &borrow_token_metadata_refs().burn_ref, from, amount
        ); 

        event::emit(Burn { burner: burner_addr, from, amount });
    }

The test even clearly has it

   #[test(owner = @0x999, recipient = @0xcafe, managed_token = @managed_token)]
    public fun test_burn_managed_token(
        owner: &signer, recipient: &signer, managed_token: &signer
    ) {
        // Setup env and mint managed_token first, mint 100 to recipient
        test_mint_managed_token(owner, recipient, managed_token);

        let recipient_addr = signer::address_of(recipient);
        let burn_amount: u64 = 50;

        managed_token::burn(owner, recipient_addr, burn_amount);

        let metadata_obj =
            object::address_to_object<Metadata>(managed_token::token_metadata());
        // 100 is the mint amount, 50 is the burn amount
        let mint_amount: u64 = 100;
        assert!(
            primary_fungible_store::balance(recipient_addr, metadata_obj)
                == mint_amount - burn_amount
        );

        // Assert tokens are burned from existing supply
        assert!(
            fungible_asset::supply(metadata_obj)
                == option::some((mint_amount - burn_amount) as u128)
        );
    }

This implementation enables any address with "burner" privileges to burn tokens from any user's account (as shown in the test where owner burns tokens from recipient_addr). This is a significant deviation from standard token burning patterns.

In OpenZeppelin's ERC20 implementation:

  • burn() only burns caller's own tokens
  • burnFrom() requires explicit allowance from the token owner
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)

    /**
     * @dev Destroys a `value` amount of tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 value) public virtual {
        _burn(_msgSender(), value);
    }
    /**
     * @dev Destroys a `value` amount of tokens from `account`, deducting from
     * the caller's allowance.
     *
     * 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);
    }

I'm wondering if the move implementation is a design choice so I would really appreciate any clarification

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions