ERC-721 Pausable

ERC721 token with pausable token transfers, minting, and burning.

Useful for scenarios such as preventing trades until the end of an evaluation period, or having an emergency switch for freezing all token transfers, e.g. caused by a bug.

Usage

In order to make your ERC721 token pausable, you need to use the Pausable contract and apply its mechanisms to ERC721 token functions as follows:

use openzeppelin_stylus::{
    token::erc721::{self, extensions::IErc721Burnable, Erc721, IErc721},
    utils::{pausable, Pausable},
};

#[derive(SolidityError, Debug)]
enum Error {
    Erc721(erc721::Error),
    Pausable(pausable::Error),
}

#[entrypoint]
#[storage]
struct Erc721Example {
    #[borrow]
    erc721: Erc721,
    #[borrow]
    pausable: Pausable,
}

#[public]
#[inherit(Erc721, Pausable)]
impl Erc721Example {
    fn burn(&mut self, token_id: U256) -> Result<(), Error> {
        // ...
        self.pausable.when_not_paused()?;
        // ...
        self.erc721.burn(token_id)?;
        Ok(())
    }

    fn mint(&mut self, to: Address, token_id: U256) -> Result<(), Error> {
        // ...
        self.pausable.when_not_paused()?;
        // ...
        self.erc721._mint(to, token_id)?;
        Ok(())
    }

    fn safe_transfer_from(
        &mut self,
        from: Address,
        to: Address,
        token_id: U256,
    ) -> Result<(), Error> {
        // ...
        self.pausable.when_not_paused()?;
        // ...
        self.erc721.safe_transfer_from(from, to, token_id)?;
        Ok(())
    }

    #[selector(name = "safeTransferFrom")]
    fn safe_transfer_from_with_data(
        &mut self,
        from: Address,
        to: Address,
        token_id: U256,
        data: Bytes,
    ) -> Result<(), Error> {
        // ...
        self.pausable.when_not_paused()?;
        // ...
        self.erc721.safe_transfer_from_with_data(from, to, token_id, data)?;
        Ok(())
    }

    fn transfer_from(
        &mut self,
        from: Address,
        to: Address,
        token_id: U256,
    ) -> Result<(), Error> {
        // ...
        self.pausable.when_not_paused()?;
        // ...
        self.erc721.transfer_from(from, to, token_id)?;
        Ok(())
    }
}