ERC-20

This set of interfaces, contracts, and utilities are all related to the ERC-20 Token Standard.

For an overview of ERC-20 tokens and a walk through on how to create a token contract read our ERC-20 guide.

There are a few core contracts that implement the behavior specified in the ERC:

  • IERC20: the interface all ERC-20 implementations should conform to.

  • IERC20Metadata: the extended ERC-20 interface including the name, symbol and decimals functions.

  • ERC20: the implementation of the ERC-20 interface, including the name, symbol and decimals optional standard extension to the base interface.

Additionally there are multiple custom extensions, including:

  • ERC20Permit: gasless approval of tokens (standardized as ERC-2612).

  • ERC20Burnable: destruction of own tokens.

  • ERC20Capped: enforcement of a cap to the total supply when minting tokens.

  • ERC20Pausable: ability to pause token transfers.

  • ERC20FlashMint: token level support for flash loans through the minting and burning of ephemeral tokens (standardized as ERC-3156).

  • ERC20Votes: support for voting and vote delegation.

  • ERC20Wrapper: wrapper to create an ERC-20 backed by another ERC-20, with deposit and withdraw methods. Useful in conjunction with ERC20Votes.

  • ERC20TemporaryApproval: support for approvals lasting for only one transaction, as defined in ERC-7674.

  • ERC1363: support for calling the target of a transfer or approval, enabling code execution on the receiver within a single transaction.

  • ERC4626: tokenized vault that manages shares (represented as ERC-20) that are backed by assets (another ERC-20).

Finally, there are some utilities to interact with ERC-20 contracts in various ways:

  • SafeERC20: a wrapper around the interface that eliminates the need to handle boolean return values.

Other utilities that support ERC-20 assets can be found in codebase:

  • ERC-20 tokens can be timelocked (held tokens for a beneficiary until a specified time) or vested (released following a given schedule) using a VestingWallet.

This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC-20 (such as _mint) and expose them as external functions in the way they prefer.

Core

IERC20

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

Interface of the ERC-20 standard as defined in the ERC.

totalSupply() → uint256 external

Returns the value of tokens in existence.

balanceOf(address account) → uint256 external

Returns the value of tokens owned by account.

transfer(address to, uint256 value) → bool external

Moves a value amount of tokens from the caller’s account to to.

Returns a boolean value indicating whether the operation succeeded.

Emits a transfer event.

allowance(address owner, address spender) → uint256 external

Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom. This is zero by default.

This value changes when approve or transferFrom are called.

approve(address spender, uint256 value) → bool external

Sets a value amount of tokens as the allowance of spender over the caller’s tokens.

Returns a boolean value indicating whether the operation succeeded.

Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender’s allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

Emits an Approval event.

transferFrom(address from, address to, uint256 value) → bool external

Moves a value amount of tokens from from to to using the allowance mechanism. value is then deducted from the caller’s allowance.

Returns a boolean value indicating whether the operation succeeded.

Emits a transfer event.

Transfer(address indexed from, address indexed to, uint256 value) event

Emitted when value tokens are moved from one account (from) to another (to).

Note that value may be zero.

Approval(address indexed owner, address indexed spender, uint256 value) event

Emitted when the allowance of a spender for an owner is set by a call to approve. value is the new allowance.

IERC20Metadata

import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

Interface for the optional metadata functions from the ERC-20 standard.

name() → string external

Returns the name of the token.

symbol() → string external

Returns the symbol of the token.

decimals() → uint8 external

Returns the decimals places of the token.

ERC20

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

Implementation of the IERC20 interface.

This implementation is agnostic to the way tokens are created. This means that a supply mechanism has to be added in a derived contract using _mint.

For a detailed writeup see our guide How to implement supply mechanisms.

The default value of decimals is 18. To change this, you should override this function so it returns a different value.

We have followed general OpenZeppelin Contracts guidelines: functions revert instead returning false on failure. This behavior is nonetheless conventional and does not conflict with the expectations of ERC-20 applications.

constructor(string name_, string symbol_) internal

Sets the values for name and symbol.

All two of these values are immutable: they can only be set once during construction.

name() → string public

Returns the name of the token.

symbol() → string public

Returns the symbol of the token, usually a shorter version of the name.

decimals() → uint8 public

Returns the number of decimals used to get its user representation. For example, if decimals equals 2, a balance of 505 tokens should be displayed to a user as 5.05 (505 / 10 ** 2).

Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it’s overridden.

This information is only used for display purposes: it in no way affects any of the arithmetic of the contract, including IERC20.balanceOf and IERC20.transfer.

totalSupply() → uint256 public

balanceOf(address account) → uint256 public

transfer(address to, uint256 value) → bool public

Requirements:

  • to cannot be the zero address.

  • the caller must have a balance of at least value.

allowance(address owner, address spender) → uint256 public

approve(address spender, uint256 value) → bool public

If value is the maximum uint256, the allowance is not updated on transferFrom. This is semantically equivalent to an infinite approval.

Requirements:

  • spender cannot be the zero address.

transferFrom(address from, address to, uint256 value) → bool public

Skips emitting an Approval event indicating an allowance update. This is not required by the ERC. See _approve.

Does not update the allowance if the current allowance is the maximum uint256.

Requirements:

  • from and to cannot be the zero address.

  • from must have a balance of at least value.

  • the caller must have allowance for from's tokens of at least value.

_transfer(address from, address to, uint256 value) internal

Moves a value amount of tokens from from to to.

This internal function is equivalent to transfer, and can be used to e.g. implement automatic token fees, slashing mechanisms, etc.

Emits a transfer event.

This function is not virtual, _update should be overridden instead.

_update(address from, address to, uint256 value) internal

Transfers a value amount of tokens from from to to, or alternatively mints (or burns) if from (or to) is the zero address. All customizations to transfers, mints, and burns should be done by overriding this function.

Emits a transfer event.

_mint(address account, uint256 value) internal

Creates a value amount of tokens and assigns them to account, by transferring it from address(0). Relies on the _update mechanism

Emits a transfer event with from set to the zero address.

This function is not virtual, _update should be overridden instead.

_burn(address account, uint256 value) internal

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.

This function is not virtual, _update should be overridden instead

_approve(address owner, address spender, uint256 value) internal

Sets value as the allowance of spender over the owner s tokens.

This internal function is equivalent to approve, and can be used to e.g. set automatic allowances for certain subsystems, etc.

Emits an Approval event.

Requirements:

  • owner cannot be the zero address.

  • spender cannot be the zero address.

Overrides to this logic should be done to the variant with an additional bool emitEvent argument.

_approve(address owner, address spender, uint256 value, bool emitEvent) internal

Variant of _approve with an optional flag to enable or disable the Approval event.

By default (when calling _approve) the flag is set to true. On the other hand, approval changes made by _spendAllowance during the transferFrom operation set the flag to false. This saves gas by not emitting any Approval event during transferFrom operations.

Anyone who wishes to continue emitting Approval events on the`transferFrom` operation can force the flag to true using the following override:

function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
    super._approve(owner, spender, value, true);
}

Requirements are the same as _approve.

_spendAllowance(address owner, address spender, uint256 value) internal

Updates owner s allowance for spender based on spent value.

Does not update the allowance value in case of infinite allowance. Revert if not enough allowance is available.

Does not emit an Approval event.

Extensions

IERC20Permit

import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";

Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in ERC-2612.

Adds the permit method, which can be used to change an account’s ERC-20 allowance (see IERC20.allowance) by presenting a message signed by the account. By not relying on IERC20.approve, the token holder account doesn’t need to send a transaction, and thus is not required to hold Ether at all.

Security Considerations

There are two important considerations concerning the use of permit. The first is that a valid permit signature expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be considered as an intention to spend the allowance in any specific way. The second is that because permits have built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should take this into consideration and allow a permit call to fail. Combining these two aspects, a pattern that may be generally recommended is:

function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
    try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
    doThing(..., value);
}

function doThing(..., uint256 value) public {
    token.safeTransferFrom(msg.sender, address(this), value);
    ...
}

Observe that: 1) msg.sender is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of try/catch allows the permit to fail and makes the code tolerant to frontrunning. (See also SafeERC20.safeTransferFrom).

Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so contracts should have entry points that don’t rely on permit.

permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external

Sets value as the allowance of spender over owner's tokens, given owner's signed approval.

The same issues IERC20.approve has related to transaction ordering also apply here.

Emits an Approval event.

Requirements:

  • spender cannot be the zero address.

  • deadline must be a timestamp in the future.

  • v, r and s must be a valid secp256k1 signature from owner over the EIP712-formatted function arguments.

  • the signature must use owner's current nonce (see nonces).

For more information on the signature format, see the relevant EIP section.

See Security Considerations above.

nonces(address owner) → uint256 external

Returns the current nonce for owner. This value must be included whenever a signature is generated for permit.

Every successful call to permit increases owner's nonce by one. This prevents a signature from being used multiple times.

DOMAIN_SEPARATOR() → bytes32 external

Returns the domain separator used in the encoding of the signature for permit, as defined by EIP712.

ERC20Permit

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";

Implementation of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in ERC-2612.

Adds the permit method, which can be used to change an account’s ERC-20 allowance (see IERC20.allowance) by presenting a message signed by the account. By not relying on IERC20.approve, the token holder account doesn’t need to send a transaction, and thus is not required to hold Ether at all.

constructor(string name) internal

Initializes the EIP712 domain separator using the name parameter, and setting version to "1".

It’s a good idea to use the same name that is defined as the ERC-20 token name.

permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public

Sets value as the allowance of spender over owner's tokens, given owner's signed approval.

The same issues IERC20.approve has related to transaction ordering also apply here.

Emits an Approval event.

Requirements:

  • spender cannot be the zero address.

  • deadline must be a timestamp in the future.

  • v, r and s must be a valid secp256k1 signature from owner over the EIP712-formatted function arguments.

  • the signature must use owner's current nonce (see nonces).

For more information on the signature format, see the relevant EIP section.

See Security Considerations above.

nonces(address owner) → uint256 public

Returns the current nonce for owner. This value must be included whenever a signature is generated for permit.

Every successful call to permit increases owner's nonce by one. This prevents a signature from being used multiple times.

DOMAIN_SEPARATOR() → bytes32 external

Returns the domain separator used in the encoding of the signature for permit, as defined by EIP712.

ERC2612ExpiredSignature(uint256 deadline) error

Permit deadline has expired.

ERC2612InvalidSigner(address signer, address owner) error

Mismatched signature.

ERC20Burnable

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";

Extension of ERC20 that allows token holders to destroy both their own tokens and those that they have an allowance for, in a way that can be recognized off-chain (via event analysis).

burn(uint256 value) public

Destroys a value amount of tokens from the caller.

burnFrom(address account, uint256 value) public

Destroys a value amount of tokens from account, deducting from the caller’s allowance.

Requirements:

  • the caller must have allowance for accounts's tokens of at least value.

ERC20Capped

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol";

Extension of ERC20 that adds a cap to the supply of tokens.

constructor(uint256 cap_) internal

Sets the value of the cap. This value is immutable, it can only be set once during construction.

cap() → uint256 public

Returns the cap on the token’s total supply.

_update(address from, address to, uint256 value) internal

ERC20ExceededCap(uint256 increasedSupply, uint256 cap) error

Total supply cap has been exceeded.

ERC20InvalidCap(uint256 cap) error

The supplied cap is not a valid cap.

ERC20Pausable

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";

ERC-20 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 in the event of a large bug.

This contract does not include public pause and unpause functions. In addition to inheriting this contract, you must define both functions, invoking the Pausable._pause and Pausable._unpause internal functions, with appropriate access control, e.g. using AccessControl or Ownable. Not doing so will make the contract pause mechanism of the contract unreachable, and thus unusable.

_update(address from, address to, uint256 value) internal

Requirements:

  • the contract must not be paused.

ERC20Votes

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";

Extension of ERC-20 to support Compound-like voting and delegation. This version is more generic than Compound’s, and supports token supply up to 2208 - 1, while COMP is limited to 296 - 1.

This contract does not provide interface compatibility with Compound’s COMP token.

This extension keeps a history (checkpoints) of each account’s vote power. Vote power can be delegated either by calling the Votes.delegate function directly, or by providing a signature to be used with Votes.delegateBySig. Voting power can be queried through the public accessors Votes.getVotes and Votes.getPastVotes.

By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.

_maxSupply() → uint256 internal

Maximum token supply. Defaults to type(uint208).max (2208 - 1).

This maximum is enforced in _update. It limits the total supply of the token, which is otherwise a uint256, so that checkpoints can be stored in the Trace208 structure used by Votes. Increasing this value will not remove the underlying limitation, and will cause _update to fail because of a math overflow in Votes._transferVotingUnits. An override could be used to further restrict the total supply (to a lower value) if additional logic requires it. When resolving override conflicts on this function, the minimum should be returned.

_update(address from, address to, uint256 value) internal

Move voting power when tokens are transferred.

_getVotingUnits(address account) → uint256 internal

Returns the voting units of an account.

Overriding this function may compromise the internal vote accounting. ERC20Votes assumes tokens map to voting units 1:1 and this is not easy to change.

numCheckpoints(address account) → uint32 public

Get number of checkpoints for account.

checkpoints(address account, uint32 pos) → struct Checkpoints.Checkpoint208 public

Get the pos-th checkpoint for account.

ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap) error

Total supply cap has been exceeded, introducing a risk of votes overflowing.

ERC20Wrapper

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

Extension of the ERC-20 token contract to support token wrapping.

Users can deposit and withdraw "underlying tokens" and receive a matching number of "wrapped tokens". This is useful in conjunction with other modules. For example, combining this wrapping mechanism with ERC20Votes will allow the wrapping of an existing "basic" ERC-20 into a governance token.

Any mechanism in which the underlying token changes the balanceOf of an account without an explicit transfer may desynchronize this contract’s supply and its underlying balance. Please exercise caution when wrapping tokens that may undercollateralize the wrapper (i.e. wrapper’s total supply is higher than its underlying balance). See _recover for recovering value accrued to the wrapper.

constructor(contract IERC20 underlyingToken) internal

decimals() → uint8 public

underlying() → contract IERC20 public

Returns the address of the underlying ERC-20 token that is being wrapped.

depositFor(address account, uint256 value) → bool public

Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.

withdrawTo(address account, uint256 value) → bool public

Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.

_recover(address account) → uint256 internal

Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake or acquired from rebasing mechanisms. Internal function that can be exposed with access control if desired.

ERC20InvalidUnderlying(address token) error

The underlying token couldn’t be wrapped.

ERC20FlashMint

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20FlashMint.sol";

Implementation of the ERC-3156 Flash loans extension, as defined in ERC-3156.

Adds the flashLoan method, which provides flash loan support at the token level. By default there is no fee, but this can be changed by overriding flashFee.

When this extension is used along with the ERC20Capped or ERC20Votes extensions, maxFlashLoan will not correctly reflect the maximum that can be flash minted. We recommend overriding maxFlashLoan so that it correctly reflects the supply cap.

maxFlashLoan(address token) → uint256 public

Returns the maximum amount of tokens available for loan.

flashFee(address token, uint256 value) → uint256 public

Returns the fee applied when doing flash loans. This function calls the _flashFee function which returns the fee applied when doing flash loans.

_flashFee(address token, uint256 value) → uint256 internal

Returns the fee applied when doing flash loans. By default this implementation has 0 fees. This function can be overloaded to make the flash loan mechanism deflationary.

_flashFeeReceiver() → address internal

Returns the receiver address of the flash fee. By default this implementation returns the address(0) which means the fee amount will be burnt. This function can be overloaded to change the fee receiver.

flashLoan(contract IERC3156FlashBorrower receiver, address token, uint256 value, bytes data) → bool public

Performs a flash loan. New tokens are minted and sent to the receiver, who is required to implement the IERC3156FlashBorrower interface. By the end of the flash loan, the receiver is expected to own value + fee tokens and have them approved back to the token contract itself so they can be burned.

ERC3156UnsupportedToken(address token) error

The loan token is not valid.

ERC3156ExceededMaxLoan(uint256 maxLoan) error

The requested loan exceeds the max loan value for token.

ERC3156InvalidReceiver(address receiver) error

The receiver of a flashloan is not a valid IERC3156FlashBorrower.onFlashLoan implementer.

ERC20TemporaryApproval

import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20TemporaryApproval.sol";

Extension of ERC20 that adds support for temporary allowances following ERC-7674.

This is a draft contract. The corresponding ERC is still subject to changes.

Available since v5.1.

allowance(address owner, address spender) → uint256 public

allowance override that includes the temporary allowance when looking up the current allowance. If adding up the persistent and the temporary allowances result in an overflow, type(uint256).max is returned.

_temporaryAllowance(address owner, address spender) → uint256 internal

Internal getter for the current temporary allowance that spender has over owner tokens.

temporaryApprove(address spender, uint256 value) → bool public

Alternative to approve that sets a value amount of tokens as the temporary allowance of spender over the caller’s tokens.

Returns a boolean value indicating whether the operation succeeded.

Requirements: - spender cannot be the zero address.

Does NOT emit an Approval event.

_temporaryApprove(address owner, address spender, uint256 value) internal

Sets value as the temporary allowance of spender over the owner s tokens.

This internal function is equivalent to temporaryApprove, and can be used to e.g. set automatic allowances for certain subsystems, etc.

Requirements: - owner cannot be the zero address. - spender cannot be the zero address.

Does NOT emit an Approval event.

_spendAllowance(address owner, address spender, uint256 value) internal

_spendAllowance override that consumes the temporary allowance (if any) before eventually falling back to consuming the persistent allowance. NOTE: This function skips calling super._spendAllowance if the temporary allowance is enough to cover the spending.

ERC1363

import "@openzeppelin/contracts/token/ERC20/extensions/ERC1363.sol";

Extension of ERC20 tokens that adds support for code execution after transfers and approvals on recipient contracts. Calls after transfers are enabled through the ERC1363.transferAndCall and ERC1363.transferFromAndCall methods while calls after approvals can be made with ERC1363.approveAndCall

Available since v5.1.

supportsInterface(bytes4 interfaceId) → bool public

Returns true if this contract implements the interface defined by interfaceId. See the corresponding ERC section to learn more about how these ids are created.

This function call must use less than 30 000 gas.

transferAndCall(address to, uint256 value) → bool public

Moves a value amount of tokens from the caller’s account to to and then calls IERC1363Receiver.onTransferReceived on to.

Requirements:

transferAndCall(address to, uint256 value, bytes data) → bool public

Variant of transferAndCall that accepts an additional data parameter with no specified format.

transferFromAndCall(address from, address to, uint256 value) → bool public

Moves a value amount of tokens from from to to using the allowance mechanism and then calls IERC1363Receiver.onTransferReceived on to.

Requirements:

transferFromAndCall(address from, address to, uint256 value, bytes data) → bool public

Variant of transferFromAndCall that accepts an additional data parameter with no specified format.

approveAndCall(address spender, uint256 value) → bool public

Sets a value amount of tokens as the allowance of spender over the caller’s tokens and then calls IERC1363Spender.onApprovalReceived on spender.

Requirements:

approveAndCall(address spender, uint256 value, bytes data) → bool public

Variant of approveAndCall that accepts an additional data parameter with no specified format.

ERC1363TransferFailed(address receiver, uint256 value) error

Indicates a failure within the transfer part of a transferAndCall operation.

ERC1363TransferFromFailed(address sender, address receiver, uint256 value) error

Indicates a failure within the transferFrom part of a transferFromAndCall operation.

ERC1363ApproveFailed(address spender, uint256 value) error

Indicates a failure within the approve part of a approveAndCall operation.

ERC4626

import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";

Implementation of the ERC-4626 "Tokenized Vault Standard" as defined in ERC-4626.

This extension allows the minting and burning of "shares" (represented using the ERC-20 inheritance) in exchange for underlying "assets" through standardized deposit, mint, redeem and burn workflows. This contract extends the ERC-20 standard. Any additional extensions included along it would affect the "shares" token represented by this contract and not the "assets" token which is an independent contract.

In empty (or nearly empty) ERC-4626 vaults, deposits are at high risk of being stolen through frontrunning with a "donation" to the vault that inflates the price of a share. This is variously known as a donation or inflation attack and is essentially a problem of slippage. Vault deployers can protect against this attack by making an initial deposit of a non-trivial amount of the asset, such that price manipulation becomes infeasible. Withdrawals may similarly be affected by slippage. Users can protect against this attack as well as unexpected slippage in general by verifying the amount received is as expected, using a wrapper that performs these checks such as ERC4626Router.

Since v4.9, this implementation introduces configurable virtual assets and shares to help developers mitigate that risk. The _decimalsOffset() corresponds to an offset in the decimal representation between the underlying asset’s decimals and the vault decimals. This offset also determines the rate of virtual shares to virtual assets in the vault, which itself determines the initial exchange rate. While not fully preventing the attack, analysis shows that the default offset (0) makes it non-profitable even if an attacker is able to capture value from multiple user deposits, as a result of the value being captured by the virtual shares (out of the attacker’s donation) matching the attacker’s expected gains. With a larger offset, the attack becomes orders of magnitude more expensive than it is profitable. More details about the underlying math can be found here.

The drawback of this approach is that the virtual shares do capture (a very small) part of the value being accrued to the vault. Also, if the vault experiences losses, the users try to exit the vault, the virtual shares and assets will cause the first user to exit to experience reduced losses in detriment to the last users that will experience bigger losses. Developers willing to revert back to the pre-v4.9 behavior just need to override the _convertToShares and _convertToAssets functions.

To learn more, check out our ERC-4626 guide.

constructor(contract IERC20 asset_) internal

Set the underlying asset contract. This must be an ERC20-compatible contract (ERC-20 or ERC-777).

decimals() → uint8 public

Decimals are computed by adding the decimal offset on top of the underlying asset’s decimals. This "original" value is cached during construction of the vault contract. If this read operation fails (e.g., the asset has not been created yet), a default of 18 is used to represent the underlying asset’s decimals.

asset() → address public

totalAssets() → uint256 public

convertToShares(uint256 assets) → uint256 public

convertToAssets(uint256 shares) → uint256 public

maxDeposit(address) → uint256 public

maxMint(address) → uint256 public

maxWithdraw(address owner) → uint256 public

maxRedeem(address owner) → uint256 public

previewDeposit(uint256 assets) → uint256 public

previewMint(uint256 shares) → uint256 public

previewWithdraw(uint256 assets) → uint256 public

previewRedeem(uint256 shares) → uint256 public

deposit(uint256 assets, address receiver) → uint256 public

mint(uint256 shares, address receiver) → uint256 public

withdraw(uint256 assets, address receiver, address owner) → uint256 public

redeem(uint256 shares, address receiver, address owner) → uint256 public

_convertToShares(uint256 assets, enum Math.Rounding rounding) → uint256 internal

Internal conversion function (from assets to shares) with support for rounding direction.

_convertToAssets(uint256 shares, enum Math.Rounding rounding) → uint256 internal

Internal conversion function (from shares to assets) with support for rounding direction.

_deposit(address caller, address receiver, uint256 assets, uint256 shares) internal

Deposit/mint common workflow.

_withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares) internal

Withdraw/redeem common workflow.

_decimalsOffset() → uint8 internal

ERC4626ExceededMaxDeposit(address receiver, uint256 assets, uint256 max) error

Attempted to deposit more assets than the max amount for receiver.

ERC4626ExceededMaxMint(address receiver, uint256 shares, uint256 max) error

Attempted to mint more shares than the max amount for receiver.

ERC4626ExceededMaxWithdraw(address owner, uint256 assets, uint256 max) error

Attempted to withdraw more assets than the max amount for receiver.

ERC4626ExceededMaxRedeem(address owner, uint256 shares, uint256 max) error

Attempted to redeem more shares than the max amount for receiver.

Utilities

SafeERC20

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

Wrappers around ERC-20 operations that throw on failure (when the token contract returns false). Tokens that return no value (and instead revert or throw on failure) are also supported, non-reverting calls are assumed to be successful. To use this library you can add a using SafeERC20 for IERC20; statement to your contract, which allows you to call the safe operations as token.safeTransfer(…​), etc.

safeTransfer(contract IERC20 token, address to, uint256 value) internal

Transfer value amount of token from the calling contract to to. If token returns no value, non-reverting calls are assumed to be successful.

safeTransferFrom(contract IERC20 token, address from, address to, uint256 value) internal

Transfer value amount of token from from to to, spending the approval given by from to the calling contract. If token returns no value, non-reverting calls are assumed to be successful.

safeIncreaseAllowance(contract IERC20 token, address spender, uint256 value) internal

Increase the calling contract’s allowance toward spender by value. If token returns no value, non-reverting calls are assumed to be successful.

If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using this function. Performing a safeIncreaseAllowance or safeDecreaseAllowance operation on a token contract that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.

safeDecreaseAllowance(contract IERC20 token, address spender, uint256 requestedDecrease) internal

Decrease the calling contract’s allowance toward spender by requestedDecrease. If token returns no value, non-reverting calls are assumed to be successful.

If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using this function. Performing a safeIncreaseAllowance or safeDecreaseAllowance operation on a token contract that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.

forceApprove(contract IERC20 token, address spender, uint256 value) internal

Set the calling contract’s allowance toward spender to value. If token returns no value, non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval to be set to zero before setting it to a non-zero value, such as USDT.

If the token implements ERC-7674, this function will not modify any temporary allowance. This function only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being set here.

transferAndCallRelaxed(contract IERC1363 token, address to, uint256 value, bytes data) internal

Performs an ERC1363 transferAndCall, with a fallback to the simple ERC20 transfer if the target has no code. This can be used to implement an ERC721-like safe transfer that rely on ERC1363 checks when targeting contracts.

Reverts if the returned value is other than true.

transferFromAndCallRelaxed(contract IERC1363 token, address from, address to, uint256 value, bytes data) internal

Performs an ERC1363 transferFromAndCall, with a fallback to the simple ERC20 transferFrom if the target has no code. This can be used to implement an ERC721-like safe transfer that rely on ERC1363 checks when targeting contracts.

Reverts if the returned value is other than true.

approveAndCallRelaxed(contract IERC1363 token, address to, uint256 value, bytes data) internal

Performs an ERC1363 approveAndCall, with a fallback to the simple ERC20 approve if the target has no code. This can be used to implement an ERC721-like safe transfer that rely on ERC1363 checks when targeting contracts.

When the recipient address (to) has no code (i.e. is an EOA), this function behaves as forceApprove. Opposedly, when the recipient address (to) has code, this function only attempts to call ERC1363.approveAndCall once without retrying, and relies on the returned value to be true.

Reverts if the returned value is other than true.

SafeERC20FailedOperation(address token) error

An operation with an ERC-20 token failed.

SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease) error

Indicates a failed decreaseAllowance request.

ERC1363Utils

import "@openzeppelin/contracts/token/ERC20/utils/ERC1363Utils.sol";

Library that provides common ERC-1363 utility functions.

See ERC-1363.

checkOnERC1363TransferReceived(address operator, address from, address to, uint256 value, bytes data) internal

Performs a call to IERC1363Receiver.onTransferReceived on a target address.

Requirements:

checkOnERC1363ApprovalReceived(address operator, address spender, uint256 value, bytes data) internal

Performs a call to IERC1363Spender.onApprovalReceived on a target address.

Requirements:

ERC1363InvalidReceiver(address receiver) error

Indicates a failure with the token receiver. Used in transfers.

ERC1363InvalidSpender(address spender) error

Indicates a failure with the token spender. Used in approvals.