ERC-20 Flash Mint

Extension of ERC-20 that provides flash loan support at the token level.

Usage

In order to make ERC-20 Flash Mint methods “external” so that other contracts can call them, you need to add the following code to your contract:

use openzeppelin_stylus::token::erc20::{
    extensions::{flash_mint, Erc20FlashMint, IErc3156FlashLender},
    Erc20, IErc20,
};

#[entrypoint]
#[storage]
struct Erc20FlashMintExample {
    erc20: Erc20,
    flash_mint: Erc20FlashMint,
}

#[public]
#[implements(IErc20<Error = flash_mint::Error>, IErc3156FlashLender<Error = flash_mint::Error>)]
impl Erc20FlashMintExample {}

#[public]
impl IErc3156FlashLender for Erc20FlashMintExample {
    type Error = flash_mint::Error;

    fn max_flash_loan(&self, token: Address) -> U256 {
        self.flash_mint.max_flash_loan(token, &self.erc20)
    }

    fn flash_fee(
        &self,
        token: Address,
        value: U256,
    ) -> Result<U256, Self::Error> {
        self.flash_mint.flash_fee(token, value)
    }

    fn flash_loan(
        &mut self,
        receiver: Address,
        token: Address,
        value: U256,
        data: Bytes,
    ) -> Result<bool, Self::Error> {
        self.flash_mint.flash_loan(
            receiver,
            token,
            value,
            &data,
            &mut self.erc20,
        )
    }
}

#[public]
impl IErc20 for Erc20FlashMintExample {
    type Error = flash_mint::Error;

    fn total_supply(&self) -> U256 {
        self.erc20.total_supply()
    }

    fn balance_of(&self, account: Address) -> U256 {
        self.erc20.balance_of(account)
    }

    fn transfer(
        &mut self,
        to: Address,
        value: U256,
    ) -> Result<bool, Self::Error> {
        Ok(self.erc20.transfer(to, value)?)
    }

    fn allowance(&self, owner: Address, spender: Address) -> U256 {
        self.erc20.allowance(owner, spender)
    }

    fn approve(
        &mut self,
        spender: Address,
        value: U256,
    ) -> Result<bool, Self::Error> {
        Ok(self.erc20.approve(spender, value)?)
    }

    fn transfer_from(
        &mut self,
        from: Address,
        to: Address,
        value: U256,
    ) -> Result<bool, Self::Error> {
        Ok(self.erc20.transfer_from(from, to, value)?)
    }
}