erc20.test.ts.md•35.5 kB
# Snapshot report for `src/erc20.test.ts`
The actual snapshot is saved in `erc20.test.ts.snap`.
Generated by [AVA](https://avajs.dev).
## basic erc20
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use stylus_sdk::alloy_primitives::{Address, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = erc20::Error>)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
type Error = erc20::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)?)␊
}␊
}␊
`
## default erc20
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::permit::{␊
self, Erc20Permit, IErc20Permit␊
};␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use openzeppelin_stylus::utils::cryptography::{ecdsa, eip712::IEip712};␊
use openzeppelin_stylus::utils::nonces::{INonces, Nonces};␊
use stylus_sdk::alloy_primitives::{Address, B256, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
erc20_permit: Erc20Permit<Eip712>,␊
nonces: Nonces,␊
}␊
␊
#[storage]␊
struct Eip712;␊
␊
impl IEip712 for Eip712 {␊
const NAME: &'static str = "MyToken";␊
const VERSION: &'static str = "1";␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = permit::Error>, IErc20Permit<Error = permit::Error>, INonces)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
type Error = permit::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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Permit for MyToken {␊
type Error = permit::Error;␊
␊
#[selector(name = "DOMAIN_SEPARATOR")]␊
fn domain_separator(&self) -> B256 {␊
self.erc20_permit.domain_separator()␊
}␊
␊
fn permit(␊
&mut self,␊
owner: Address,␊
spender: Address,␊
value: U256,␊
deadline: U256,␊
v: u8,␊
r: B256,␊
s: B256,␊
) -> Result<(), Self::Error> {␊
Ok(self.erc20_permit.permit(owner, spender, value, deadline, v, r, s, &mut self.erc20, &mut self.nonces)?)␊
}␊
}␊
␊
#[public]␊
impl INonces for MyToken {␊
fn nonces(&self, owner: Address) -> U256 {␊
self.nonces.nonces(owner)␊
}␊
}␊
`
## erc20 burnable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::burnable::IErc20Burnable;␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use stylus_sdk::alloy_primitives::{Address, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = erc20::Error>, IErc20Burnable<Error = erc20::Error>)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
type Error = erc20::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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Burnable for MyToken {␊
type Error = erc20::Error;␊
␊
fn burn(&mut self, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn(value)?)␊
}␊
␊
fn burn_from(&mut self, account: Address, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn_from(account, value)?)␊
}␊
}␊
`
## erc20 flash-mint
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::flash_mint::{␊
self, Erc20FlashMint, IErc3156FlashLender␊
};␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use stylus_sdk::abi::Bytes;␊
use stylus_sdk::alloy_primitives::{Address, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
flash_mint: Erc20FlashMint,␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = flash_mint::Error>, IErc3156FlashLender<Error = flash_mint::Error>)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc3156FlashLender for MyToken {␊
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> {␊
Ok(self.flash_mint.flash_fee(token, value)?)␊
}␊
␊
fn flash_loan(&mut self, receiver: Address, token: Address, value: U256, data: Bytes) -> Result<bool, Self::Error> {␊
Ok(self.flash_mint.flash_loan(receiver, token, value, &data, &mut self.erc20)?)␊
}␊
}␊
`
## erc20 burnable flash-mint
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::burnable::IErc20Burnable;␊
use openzeppelin_stylus::token::erc20::extensions::flash_mint::{␊
self, Erc20FlashMint, IErc3156FlashLender␊
};␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use stylus_sdk::abi::Bytes;␊
use stylus_sdk::alloy_primitives::{Address, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
flash_mint: Erc20FlashMint,␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = flash_mint::Error>, IErc20Burnable<Error = flash_mint::Error>, IErc3156FlashLender<Error = flash_mint::Error>)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Burnable for MyToken {␊
type Error = flash_mint::Error;␊
␊
fn burn(&mut self, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn(value)?)␊
}␊
␊
fn burn_from(&mut self, account: Address, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn_from(account, value)?)␊
}␊
}␊
␊
#[public]␊
impl IErc3156FlashLender for MyToken {␊
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> {␊
Ok(self.flash_mint.flash_fee(token, value)?)␊
}␊
␊
fn flash_loan(&mut self, receiver: Address, token: Address, value: U256, data: Bytes) -> Result<bool, Self::Error> {␊
Ok(self.flash_mint.flash_loan(receiver, token, value, &data, &mut self.erc20)?)␊
}␊
}␊
`
## erc20 permit
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::permit::{␊
self, Erc20Permit, IErc20Permit␊
};␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use openzeppelin_stylus::utils::cryptography::{ecdsa, eip712::IEip712};␊
use openzeppelin_stylus::utils::nonces::{INonces, Nonces};␊
use stylus_sdk::alloy_primitives::{Address, B256, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
erc20_permit: Erc20Permit<Eip712>,␊
nonces: Nonces,␊
}␊
␊
#[storage]␊
struct Eip712;␊
␊
impl IEip712 for Eip712 {␊
const NAME: &'static str = "MyToken";␊
const VERSION: &'static str = "1";␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = permit::Error>, IErc20Permit<Error = permit::Error>, INonces)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
type Error = permit::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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Permit for MyToken {␊
type Error = permit::Error;␊
␊
#[selector(name = "DOMAIN_SEPARATOR")]␊
fn domain_separator(&self) -> B256 {␊
self.erc20_permit.domain_separator()␊
}␊
␊
fn permit(␊
&mut self,␊
owner: Address,␊
spender: Address,␊
value: U256,␊
deadline: U256,␊
v: u8,␊
r: B256,␊
s: B256,␊
) -> Result<(), Self::Error> {␊
Ok(self.erc20_permit.permit(owner, spender, value, deadline, v, r, s, &mut self.erc20, &mut self.nonces)?)␊
}␊
}␊
␊
#[public]␊
impl INonces for MyToken {␊
fn nonces(&self, owner: Address) -> U256 {␊
self.nonces.nonces(owner)␊
}␊
}␊
`
## erc20 permit burnable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::burnable::IErc20Burnable;␊
use openzeppelin_stylus::token::erc20::extensions::permit::{␊
self, Erc20Permit, IErc20Permit␊
};␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use openzeppelin_stylus::utils::cryptography::{ecdsa, eip712::IEip712};␊
use openzeppelin_stylus::utils::nonces::{INonces, Nonces};␊
use stylus_sdk::alloy_primitives::{Address, B256, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
erc20_permit: Erc20Permit<Eip712>,␊
nonces: Nonces,␊
}␊
␊
#[storage]␊
struct Eip712;␊
␊
impl IEip712 for Eip712 {␊
const NAME: &'static str = "MyToken";␊
const VERSION: &'static str = "1";␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = permit::Error>, IErc20Burnable<Error = permit::Error>, IErc20Permit<Error = permit::Error>, INonces)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
type Error = permit::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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Burnable for MyToken {␊
type Error = permit::Error;␊
␊
fn burn(&mut self, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn(value)?)␊
}␊
␊
fn burn_from(&mut self, account: Address, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn_from(account, value)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Permit for MyToken {␊
type Error = permit::Error;␊
␊
#[selector(name = "DOMAIN_SEPARATOR")]␊
fn domain_separator(&self) -> B256 {␊
self.erc20_permit.domain_separator()␊
}␊
␊
fn permit(␊
&mut self,␊
owner: Address,␊
spender: Address,␊
value: U256,␊
deadline: U256,␊
v: u8,␊
r: B256,␊
s: B256,␊
) -> Result<(), Self::Error> {␊
Ok(self.erc20_permit.permit(owner, spender, value, deadline, v, r, s, &mut self.erc20, &mut self.nonces)?)␊
}␊
}␊
␊
#[public]␊
impl INonces for MyToken {␊
fn nonces(&self, owner: Address) -> U256 {␊
self.nonces.nonces(owner)␊
}␊
}␊
`
## erc20 permit flash-mint
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::flash_mint::{␊
self, Erc20FlashMint, IErc3156FlashLender␊
};␊
use openzeppelin_stylus::token::erc20::extensions::permit::{␊
self, Erc20Permit, IErc20Permit␊
};␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use openzeppelin_stylus::utils::cryptography::{ecdsa, eip712::IEip712};␊
use openzeppelin_stylus::utils::nonces::{INonces, Nonces};␊
use stylus_sdk::abi::Bytes;␊
use stylus_sdk::alloy_primitives::{Address, B256, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[derive(SolidityError, Debug)]␊
enum Error {␊
ExpiredSignature(permit::ERC2612ExpiredSignature),␊
InvalidSigner(permit::ERC2612InvalidSigner),␊
InvalidSignature(ecdsa::ECDSAInvalidSignature),␊
InvalidSignatureS(ecdsa::ECDSAInvalidSignatureS),␊
InsufficientBalance(erc20::ERC20InsufficientBalance),␊
InvalidSender(erc20::ERC20InvalidSender),␊
InvalidReceiver(erc20::ERC20InvalidReceiver),␊
InsufficientAllowance(erc20::ERC20InsufficientAllowance),␊
InvalidSpender(erc20::ERC20InvalidSpender),␊
InvalidApprover(erc20::ERC20InvalidApprover),␊
UnsupportedToken(flash_mint::ERC3156UnsupportedToken),␊
ExceededMaxLoan(flash_mint::ERC3156ExceededMaxLoan),␊
ERC3156InvalidReceiver(flash_mint::ERC3156InvalidReceiver),␊
}␊
␊
impl From<erc20::Error> for Error {␊
fn from(error: erc20::Error) -> Self {␊
match error {␊
erc20::Error::InsufficientBalance(e) => Error::InsufficientBalance(e),␊
erc20::Error::InvalidSender(e) => Error::InvalidSender(e),␊
erc20::Error::InvalidReceiver(e) => Error::InvalidReceiver(e),␊
erc20::Error::InsufficientAllowance(e) => Error::InsufficientAllowance(e),␊
erc20::Error::InvalidSpender(e) => Error::InvalidSpender(e),␊
erc20::Error::InvalidApprover(e) => Error::InvalidApprover(e),␊
}␊
}␊
}␊
␊
impl From<permit::Error> for Error {␊
fn from(error: permit::Error) -> Self {␊
match error {␊
permit::Error::ExpiredSignature(e) => Error::ExpiredSignature(e),␊
permit::Error::InvalidSigner(e) => Error::InvalidSigner(e),␊
permit::Error::InvalidSignature(e) => Error::InvalidSignature(e),␊
permit::Error::InvalidSignatureS(e) => Error::InvalidSignatureS(e),␊
permit::Error::InsufficientBalance(e) => Error::InsufficientBalance(e),␊
permit::Error::InvalidSender(e) => Error::InvalidSender(e),␊
permit::Error::InvalidReceiver(e) => Error::InvalidReceiver(e),␊
permit::Error::InsufficientAllowance(e) => Error::InsufficientAllowance(e),␊
permit::Error::InvalidSpender(e) => Error::InvalidSpender(e),␊
permit::Error::InvalidApprover(e) => Error::InvalidApprover(e),␊
}␊
}␊
}␊
␊
impl From<flash_mint::Error> for Error {␊
fn from(error: flash_mint::Error) -> Self {␊
match error {␊
flash_mint::Error::UnsupportedToken(e) => Error::UnsupportedToken(e),␊
flash_mint::Error::ExceededMaxLoan(e) => Error::ExceededMaxLoan(e),␊
flash_mint::Error::ERC3156InvalidReceiver(e) => Error::ERC3156InvalidReceiver(e),␊
flash_mint::Error::InsufficientBalance(e) => Error::InsufficientBalance(e),␊
flash_mint::Error::InvalidSender(e) => Error::InvalidSender(e),␊
flash_mint::Error::InvalidReceiver(e) => Error::InvalidReceiver(e),␊
flash_mint::Error::InsufficientAllowance(e) => Error::InsufficientAllowance(e),␊
flash_mint::Error::InvalidSpender(e) => Error::InvalidSpender(e),␊
flash_mint::Error::InvalidApprover(e) => Error::InvalidApprover(e),␊
}␊
}␊
}␊
␊
#[entrypoint]␊
#[storage]␊
struct MyToken {␊
erc20: Erc20,␊
erc20_permit: Erc20Permit<Eip712>,␊
flash_mint: Erc20FlashMint,␊
nonces: Nonces,␊
}␊
␊
#[storage]␊
struct Eip712;␊
␊
impl IEip712 for Eip712 {␊
const NAME: &'static str = "MyToken";␊
const VERSION: &'static str = "1";␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = Error>, IErc20Permit<Error = Error>, IErc3156FlashLender<Error = Error>, INonces)]␊
impl MyToken {}␊
␊
#[public]␊
impl IErc20 for MyToken {␊
type Error = 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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Permit for MyToken {␊
type Error = Error;␊
␊
#[selector(name = "DOMAIN_SEPARATOR")]␊
fn domain_separator(&self) -> B256 {␊
self.erc20_permit.domain_separator()␊
}␊
␊
fn permit(␊
&mut self,␊
owner: Address,␊
spender: Address,␊
value: U256,␊
deadline: U256,␊
v: u8,␊
r: B256,␊
s: B256,␊
) -> Result<(), Self::Error> {␊
Ok(self.erc20_permit.permit(owner, spender, value, deadline, v, r, s, &mut self.erc20, &mut self.nonces)?)␊
}␊
}␊
␊
#[public]␊
impl IErc3156FlashLender for MyToken {␊
type Error = 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> {␊
Ok(self.flash_mint.flash_fee(token, value)?)␊
}␊
␊
fn flash_loan(&mut self, receiver: Address, token: Address, value: U256, data: Bytes) -> Result<bool, Self::Error> {␊
Ok(self.flash_mint.flash_loan(receiver, token, value, &data, &mut self.erc20)?)␊
}␊
}␊
␊
#[public]␊
impl INonces for MyToken {␊
fn nonces(&self, owner: Address) -> U256 {␊
self.nonces.nonces(owner)␊
}␊
}␊
`
## erc20 full - complex name
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Stylus ^0.2.0␊
␊
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]␊
extern crate alloc;␊
␊
use alloc::vec::Vec;␊
use openzeppelin_stylus::token::erc20::extensions::burnable::IErc20Burnable;␊
use openzeppelin_stylus::token::erc20::extensions::flash_mint::{␊
self, Erc20FlashMint, IErc3156FlashLender␊
};␊
use openzeppelin_stylus::token::erc20::extensions::permit::{␊
self, Erc20Permit, IErc20Permit␊
};␊
use openzeppelin_stylus::token::erc20::{self, Erc20, IErc20};␊
use openzeppelin_stylus::utils::cryptography::{ecdsa, eip712::IEip712};␊
use openzeppelin_stylus::utils::nonces::{INonces, Nonces};␊
use stylus_sdk::abi::Bytes;␊
use stylus_sdk::alloy_primitives::{Address, B256, U256};␊
use stylus_sdk::prelude::*;␊
␊
#[derive(SolidityError, Debug)]␊
enum Error {␊
ExpiredSignature(permit::ERC2612ExpiredSignature),␊
InvalidSigner(permit::ERC2612InvalidSigner),␊
InvalidSignature(ecdsa::ECDSAInvalidSignature),␊
InvalidSignatureS(ecdsa::ECDSAInvalidSignatureS),␊
InsufficientBalance(erc20::ERC20InsufficientBalance),␊
InvalidSender(erc20::ERC20InvalidSender),␊
InvalidReceiver(erc20::ERC20InvalidReceiver),␊
InsufficientAllowance(erc20::ERC20InsufficientAllowance),␊
InvalidSpender(erc20::ERC20InvalidSpender),␊
InvalidApprover(erc20::ERC20InvalidApprover),␊
UnsupportedToken(flash_mint::ERC3156UnsupportedToken),␊
ExceededMaxLoan(flash_mint::ERC3156ExceededMaxLoan),␊
ERC3156InvalidReceiver(flash_mint::ERC3156InvalidReceiver),␊
}␊
␊
impl From<erc20::Error> for Error {␊
fn from(error: erc20::Error) -> Self {␊
match error {␊
erc20::Error::InsufficientBalance(e) => Error::InsufficientBalance(e),␊
erc20::Error::InvalidSender(e) => Error::InvalidSender(e),␊
erc20::Error::InvalidReceiver(e) => Error::InvalidReceiver(e),␊
erc20::Error::InsufficientAllowance(e) => Error::InsufficientAllowance(e),␊
erc20::Error::InvalidSpender(e) => Error::InvalidSpender(e),␊
erc20::Error::InvalidApprover(e) => Error::InvalidApprover(e),␊
}␊
}␊
}␊
␊
impl From<permit::Error> for Error {␊
fn from(error: permit::Error) -> Self {␊
match error {␊
permit::Error::ExpiredSignature(e) => Error::ExpiredSignature(e),␊
permit::Error::InvalidSigner(e) => Error::InvalidSigner(e),␊
permit::Error::InvalidSignature(e) => Error::InvalidSignature(e),␊
permit::Error::InvalidSignatureS(e) => Error::InvalidSignatureS(e),␊
permit::Error::InsufficientBalance(e) => Error::InsufficientBalance(e),␊
permit::Error::InvalidSender(e) => Error::InvalidSender(e),␊
permit::Error::InvalidReceiver(e) => Error::InvalidReceiver(e),␊
permit::Error::InsufficientAllowance(e) => Error::InsufficientAllowance(e),␊
permit::Error::InvalidSpender(e) => Error::InvalidSpender(e),␊
permit::Error::InvalidApprover(e) => Error::InvalidApprover(e),␊
}␊
}␊
}␊
␊
impl From<flash_mint::Error> for Error {␊
fn from(error: flash_mint::Error) -> Self {␊
match error {␊
flash_mint::Error::UnsupportedToken(e) => Error::UnsupportedToken(e),␊
flash_mint::Error::ExceededMaxLoan(e) => Error::ExceededMaxLoan(e),␊
flash_mint::Error::ERC3156InvalidReceiver(e) => Error::ERC3156InvalidReceiver(e),␊
flash_mint::Error::InsufficientBalance(e) => Error::InsufficientBalance(e),␊
flash_mint::Error::InvalidSender(e) => Error::InvalidSender(e),␊
flash_mint::Error::InvalidReceiver(e) => Error::InvalidReceiver(e),␊
flash_mint::Error::InsufficientAllowance(e) => Error::InsufficientAllowance(e),␊
flash_mint::Error::InvalidSpender(e) => Error::InvalidSpender(e),␊
flash_mint::Error::InvalidApprover(e) => Error::InvalidApprover(e),␊
}␊
}␊
}␊
␊
#[entrypoint]␊
#[storage]␊
struct CustomToken {␊
erc20: Erc20,␊
erc20_permit: Erc20Permit<Eip712>,␊
flash_mint: Erc20FlashMint,␊
nonces: Nonces,␊
}␊
␊
#[storage]␊
struct Eip712;␊
␊
impl IEip712 for Eip712 {␊
const NAME: &'static str = "Custom $ Token";␊
const VERSION: &'static str = "1";␊
}␊
␊
#[public]␊
#[implements(IErc20<Error = Error>, IErc20Burnable<Error = Error>, IErc20Permit<Error = Error>, IErc3156FlashLender<Error = Error>, INonces)]␊
impl CustomToken {}␊
␊
#[public]␊
impl IErc20 for CustomToken {␊
type Error = 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)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Burnable for CustomToken {␊
type Error = Error;␊
␊
fn burn(&mut self, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn(value)?)␊
}␊
␊
fn burn_from(&mut self, account: Address, value: U256) -> Result<(), Self::Error> {␊
Ok(self.erc20.burn_from(account, value)?)␊
}␊
}␊
␊
#[public]␊
impl IErc20Permit for CustomToken {␊
type Error = Error;␊
␊
#[selector(name = "DOMAIN_SEPARATOR")]␊
fn domain_separator(&self) -> B256 {␊
self.erc20_permit.domain_separator()␊
}␊
␊
fn permit(␊
&mut self,␊
owner: Address,␊
spender: Address,␊
value: U256,␊
deadline: U256,␊
v: u8,␊
r: B256,␊
s: B256,␊
) -> Result<(), Self::Error> {␊
Ok(self.erc20_permit.permit(owner, spender, value, deadline, v, r, s, &mut self.erc20, &mut self.nonces)?)␊
}␊
}␊
␊
#[public]␊
impl IErc3156FlashLender for CustomToken {␊
type Error = 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> {␊
Ok(self.flash_mint.flash_fee(token, value)?)␊
}␊
␊
fn flash_loan(&mut self, receiver: Address, token: Address, value: U256, data: Bytes) -> Result<bool, Self::Error> {␊
Ok(self.flash_mint.flash_loan(receiver, token, value, &data, &mut self.erc20)?)␊
}␊
}␊
␊
#[public]␊
impl INonces for CustomToken {␊
fn nonces(&self, owner: Address) -> U256 {␊
self.nonces.nonces(owner)␊
}␊
}␊
`