ERC 20
Outdated Version
This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc20
This set of interfaces, contracts, and utilities are all related to the ERC20 Token Standard.
For an overview of ERC20 tokens and a walk through on how to create a token contract read our ERC20 guide.
There a few core contracts that implement the behavior specified in the EIP:
- IERC20: the interface all ERC20 implementations should conform to.
- ERC20: the implementation of the ERC20 interface, including the
name
,symbol
anddecimals
optional standard extension to the base interface.
Additionally there are multiple custom extensions, including:
- ERC20Permit: gasless approval of tokens.
- ERC20Snapshot: efficient storage of past token balances to be later queried at any point in time.
- ERC20Burnable: destruction of own tokens.
- ERC20Capped: enforcement of a cap to the total supply when minting tokens.
- ERC20Pausable: ability to pause token transfers.
Finally, there are some utilities to interact with ERC20 contracts in various ways.
- SafeERC20: a wrapper around the interface that eliminates the need to handle boolean return values.
- TokenTimelock: hold tokens for a beneficiary until a specified time.
The following related EIPs are in draft status and can be found in the drafts directory.
- IERC20Permit
- ERC20Permit
This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as [_mint
](#_mint(address-account,-uint256-amount) *internal*
)) and expose them as external functions in the way they prefer. On the other hand, ERC20 Presets (such as ERC20PresetMinterPauser) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
Core
IERC20
Interface of the ERC20 standard as defined in the EIP.
Functions
totalSupply()
balanceOf(account)
transfer(recipient, amount)
allowance(owner, spender)
approve(spender, amount)
transferFrom(sender, recipient, amount)
Events
totalSupply() → uint256 *external*
Returns the amount of tokens in existence.
balanceOf(address account) → uint256 *external*
Returns the amount of tokens owned by account
.
transfer(address recipient, uint256 amount) → bool *external*
Moves amount
tokens from the caller’s account to recipient
.
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 amount) → bool *external*
Sets amount
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 sender, address recipient, uint256 amount) → bool *external*
Moves amount
tokens from sender
to recipient
using the
allowance mechanism. amount
is then deducted from the caller’s
allowance.
Returns a boolean value indicating whether the operation succeeded.
Emits a Transfer event.
Transfer(address from, address 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 owner, address 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.
ERC20
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 generic mechanism see ERC20PresetMinterPauser.
For a detailed writeup see our guide https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How to implement supply mechanisms].
We have followed general OpenZeppelin guidelines: functions revert instead
of returning false
on failure. This behavior is nonetheless conventional
and does not conflict with the expectations of ERC20 applications.
Additionally, an Approval event is emitted on calls to transferFrom. This allows applications to reconstruct the allowance for all accounts just by listening to said events. Other implementations of the EIP may not emit these events, as it isn’t required by the specification.
Finally, the non-standard decreaseAllowance and increaseAllowance functions have been added to mitigate the well-known issues around setting allowances. See IERC20-approve.
Functions
constructor(name_, symbol_)
name()
symbol()
decimals()
totalSupply()
balanceOf(account)
transfer(recipient, amount)
allowance(owner, spender)
approve(spender, amount)
transferFrom(sender, recipient, amount)
increaseAllowance(spender, addedValue)
decreaseAllowance(spender, subtractedValue)
_transfer(sender, recipient, amount)
_mint(account, amount)
_burn(account, amount)
_approve(owner, spender, amount)
_setupDecimals(decimals_)
_beforeTokenTransfer(from, to, amount)
Events
IERC20
constructor(string name_, string symbol_) *public*
Sets the values for name and symbol, initializes decimals with a default value of 18.
To select a different value for decimals, use _setupDecimals.
All three 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 value ERC20 uses, unless _setupDecimals is called.
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*
See IERC20-totalSupply.
balanceOf(address account) → uint256 *public*
See IERC20-balanceOf.
`transfer(address recipient, uint256 amount) → bool public
See IERC20-transfer.
Requirements:
*
recipient` cannot be the zero address.
- the caller must have a balance of at least
amount
.
allowance(address owner, address spender) → uint256 *public*
See IERC20-allowance.
`approve(address spender, uint256 amount) → bool public
See IERC20-approve.
Requirements:
*
spender` cannot be the zero address.
`transferFrom(address sender, address recipient, uint256 amount) → bool public
See IERC20-transferFrom.
Emits an Approval event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of ERC20.
Requirements:
*
senderand
recipient` cannot be the zero address.
sender
must have a balance of at leastamount
.- the caller must have allowance for ``sender
’s tokens of at least
amount`.
increaseAllowance(address spender, uint256 addedValue) → bool *public*
Atomically increases the allowance granted to spender
by the caller.
This is an alternative to approve that can be used as a mitigation for problems described in IERC20-approve.
Emits an Approval event indicating the updated allowance.
Requirements:
spender
cannot be the zero address.
decreaseAllowance(address spender, uint256 subtractedValue) → bool *public*
Atomically decreases the allowance granted to spender
by the caller.
This is an alternative to approve that can be used as a mitigation for problems described in IERC20-approve.
Emits an Approval event indicating the updated allowance.
Requirements:
spender
cannot be the zero address.spender
must have allowance for the caller of at leastsubtractedValue
.
_transfer(address sender, address recipient, uint256 amount) *internal*
Moves tokens amount
from sender
to recipient
.
This is internal function is equivalent to transfer, and can be used to e.g. implement automatic token fees, slashing mechanisms, etc.
Emits a Transfer event.
Requirements:
sender
cannot be the zero address.recipient
cannot be the zero address.sender
must have a balance of at leastamount
.
_mint(address account, uint256 amount) *internal*
Creates amount
tokens and assigns them to account
, increasing
the total supply.
Emits a Transfer event with from
set to the zero address.
Requirements:
to
cannot be the zero address.
_burn(address account, uint256 amount) *internal*
Destroys amount
tokens from account
, reducing the
total supply.
Emits a Transfer event with to
set to the zero address.
Requirements:
account
cannot be the zero address.account
must have at leastamount
tokens.
_approve(address owner, address spender, uint256 amount) *internal*
Sets amount
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.
_setupDecimals(uint8 decimals_) *internal*
Sets decimals to a value other than the default one of 18.
This function should only be called from the constructor. Most applications that interact with token contracts will not expect decimals to ever change, and may work incorrectly if it does.
`_beforeTokenTransfer(address from, address to, uint256 amount) internal
Hook that is called before any transfer of tokens. This includes minting and burning.
Calling conditions:
*when
fromand
toare both non-zero,
amount of ``from
’s tokens
will be to transferred to to
.
- when
from
is zero,amount
tokens will be minted forto
. - when
to
is zero,amount
of ``from`’s tokens will be burned. from
andto
are never both zero.
To learn more about hooks, head to Using Hooks.
Extensions
ERC20Snapshot
This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and total supply at the time are recorded for later access.
This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. In naive implementations it’s possible to perform a "double spend" attack by reusing the same balance from different accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be used to create an efficient ERC20 forking mechanism.
Snapshots are created by the internal _snapshot function, which will emit the Snapshot event and return a snapshot id. To get the total supply at the time of a snapshot, call the function totalSupplyAt with the snapshot id. To get the balance of an account at the time of a snapshot, call the balanceOfAt function with the snapshot id and the account address.
Gas Costs
Snapshots are efficient. Snapshot creation is O(1). Retrieval of balances or total supply from a snapshot is O(log n) in the number of snapshots that have been created, although n for a specific account will generally be much smaller since identical balances in subsequent snapshots are stored as a single entry.
There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent transfers will have normal cost until the next snapshot, and so on.
Functions
_snapshot()
balanceOfAt(account, snapshotId)
totalSupplyAt(snapshotId)
_beforeTokenTransfer(from, to, amount)
ERC20
constructor(name_, symbol_)
name()
symbol()
decimals()
totalSupply()
balanceOf(account)
transfer(recipient, amount)
allowance(owner, spender)
approve(spender, amount)
transferFrom(sender, recipient, amount)
increaseAllowance(spender, addedValue)
decreaseAllowance(spender, subtractedValue)
_transfer(sender, recipient, amount)
_mint(account, amount)
_burn(account, amount)
_approve(owner, spender, amount)
_setupDecimals(decimals_)
Events
IERC20
_snapshot() → uint256 *internal*
Creates a new snapshot and returns its snapshot id.
Emits a Snapshot event that contains the same id.
_snapshot is internal
and you have to decide how to expose it externally. Its usage may be restricted to a
set of accounts, for example using AccessControl, or it may be open to the public.
While an open way of calling _snapshot is required for certain trust minimization mechanisms such as forking, you must consider that it can potentially be used by attackers in two ways.
First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs section above.
We haven’t measured the actual numbers; if this is something you’re interested in please reach out to us.
balanceOfAt(address account, uint256 snapshotId) → uint256 *public*
Retrieves the balance of account
at the time snapshotId
was created.
totalSupplyAt(uint256 snapshotId) → uint256 *public*
Retrieves the total supply at the time snapshotId
was created.
_beforeTokenTransfer(address from, address to, uint256 amount) *internal*
Snapshot(uint256 id) *event*
Emitted by _snapshot when a snapshot identified by id
is created.
ERC20Pausable
ERC20 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.
Functions
Pausable
ERC20
name()
symbol()
decimals()
totalSupply()
balanceOf(account)
transfer(recipient, amount)
allowance(owner, spender)
approve(spender, amount)
transferFrom(sender, recipient, amount)
increaseAllowance(spender, addedValue)
decreaseAllowance(spender, subtractedValue)
_transfer(sender, recipient, amount)
_mint(account, amount)
_burn(account, amount)
_approve(owner, spender, amount)
_setupDecimals(decimals_)
Events
Pausable
IERC20
`_beforeTokenTransfer(address from, address to, uint256 amount) internal
See ERC20-_beforeTokenTransfer.
Requirements:
*` the contract must not be paused.
ERC20Burnable
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).
Functions
ERC20
constructor(name_, symbol_)
name()
symbol()
decimals()
totalSupply()
balanceOf(account)
transfer(recipient, amount)
allowance(owner, spender)
approve(spender, amount)
transferFrom(sender, recipient, amount)
increaseAllowance(spender, addedValue)
decreaseAllowance(spender, subtractedValue)
_transfer(sender, recipient, amount)
_mint(account, amount)
_burn(account, amount)
_approve(owner, spender, amount)
_setupDecimals(decimals_)
_beforeTokenTransfer(from, to, amount)
Events
IERC20
burn(uint256 amount) *public*
Destroys amount
tokens from the caller.
See ERC20-_burn.
burnFrom(address account, uint256 amount) *public*
Destroys amount
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
amount`.
ERC20Capped
Extension of ERC20 that adds a cap to the supply of tokens.
Functions
ERC20
name()
symbol()
decimals()
totalSupply()
balanceOf(account)
transfer(recipient, amount)
allowance(owner, spender)
approve(spender, amount)
transferFrom(sender, recipient, amount)
increaseAllowance(spender, addedValue)
decreaseAllowance(spender, subtractedValue)
_transfer(sender, recipient, amount)
_mint(account, amount)
_burn(account, amount)
_approve(owner, spender, amount)
_setupDecimals(decimals_)
Events
IERC20
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.
`_beforeTokenTransfer(address from, address to, uint256 amount) internal
See ERC20-_beforeTokenTransfer.
Requirements:
*` minted tokens must not cause the total supply to go over the cap.
Utilities
SafeERC20
Wrappers around ERC20 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.
Functions
safeTransfer(token, to, value)
safeTransferFrom(token, from, to, value)
safeApprove(token, spender, value)
safeIncreaseAllowance(token, spender, value)
safeDecreaseAllowance(token, spender, value)
safeTransfer(contract IERC20 token, address to, uint256 value) *internal*
safeTransferFrom(contract IERC20 token, address from, address to, uint256 value) *internal*
safeApprove(contract IERC20 token, address spender, uint256 value) *internal*
Deprecated. This function has issues similar to the ones found in IERC20-approve, and its usage is discouraged.
Whenever possible, use safeIncreaseAllowance and safeDecreaseAllowance instead.
safeIncreaseAllowance(contract IERC20 token, address spender, uint256 value) *internal*
safeDecreaseAllowance(contract IERC20 token, address spender, uint256 value) *internal*
TokenTimelock
A token holder contract that will allow a beneficiary to extract the tokens after a given release time.
Useful for simple vesting schedules like "advisors get all of their tokens after 1 year".
Functions