Tokens

Set of extensions and utilities for tokens (e.g ERC-20, ERC-721, ERC-1155) and derivated ERCs (e.g. ERC-4626, ERC-1363).

  • OnTokenTransferAdapter: Adapter of the ERC-1363 receiver interface to comply with Chainlink’s 667 interface.

  • ERC20Allowlist: Extension of ERC20 with transfers and approvals that require users to be registered into an allowlist.

  • ERC20Blocklist: Extension of ERC20 with transfers and approvals that can be disabled by adding users into a blocklist.

  • ERC20Collateral: Oracle-agnostic extension of ERC20 that limits the total supply based on a collateral amount.

  • ERC20Custodian: Extension of ERC20 that implements an access-control agnostic approach to define a custodian that can freeze user’s transfers and approvals.

  • ERC4626Fees: ERC4626 vault with fees on entry (deposit/mint) or exit (withdraw/redeem).

General

OnTokenTransferAdapter

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

This contract exposes the 667 onTokenTransfer hook on top of {IERC1363Receiver-onTransferReceived}.

Inheriting from this adapter makes your ERC1363Receiver contract automatically compatible with tokens, such as Chainlink’s Link, that implement the 667 interface for transferAndCall.

Functions
  • onTokenTransfer(from, amount, data)

IERC1363Receiver
  • onTransferReceived(operator, from, value, data)

onTokenTransfer(address from, uint256 amount, bytes data) → bool public

ERC20

ERC20Allowlist

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

Extension of {ERC20} that allows to implement an allowlist mechanism that can be managed by an authorized account with the _disallowUser and _allowUser functions.

The allowlist provides the guarantee to the contract owner (e.g. a DAO or a well-configured multisig) that any account won’t be able to execute transfers or approvals to other entities to operate on its behalf if _allowUser was not called with such account as an argument. Similarly, the account will be disallowed again if _disallowUser is called.

Functions
  • allowed(account)

  • _allowUser(user)

  • _disallowUser(user)

  • _update(from, to, value)

  • _approve(owner, spender, value, emitEvent)

ERC20
  • name()

  • symbol()

  • decimals()

  • totalSupply()

  • balanceOf(account)

  • transfer(to, value)

  • allowance(owner, spender)

  • approve(spender, value)

  • transferFrom(from, to, value)

  • _transfer(from, to, value)

  • _mint(account, value)

  • _burn(account, value)

  • _approve(owner, spender, value)

  • _spendAllowance(owner, spender, value)

Events
  • UserAllowed(user)

  • UserDisallowed(user)

IERC20
  • Transfer(from, to, value)

  • Approval(owner, spender, value)

Errors
  • ERC20Disallowed(user)

IERC20Errors
  • ERC20InsufficientBalance(sender, balance, needed)

  • ERC20InvalidSender(sender)

  • ERC20InvalidReceiver(receiver)

  • ERC20InsufficientAllowance(spender, allowance, needed)

  • ERC20InvalidApprover(approver)

  • ERC20InvalidSpender(spender)

allowed(address account) → bool public

Returns the allowed status of an account.

_allowUser(address user) → bool internal

Allows a user to receive and transfer tokens, including minting and burning.

_disallowUser(address user) → bool internal

Disallows a user from receiving and transferring tokens, including minting and burning.

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

See {ERC20-_update}.

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

See {ERC20-_approve}.

UserAllowed(address indexed user) event

Emitted when a user is allowed to transfer and approve.

UserDisallowed(address indexed user) event

Emitted when a user is disallowed.

ERC20Disallowed(address user) error

The operation failed because the user is not allowed.

ERC20Blocklist

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

Extension of {ERC20} that allows to implement a blocklist mechanism that can be managed by an authorized account with the _blockUser and _unblockUser functions.

The blocklist provides the guarantee to the contract owner (e.g. a DAO or a well-configured multisig) that any account won’t be able to execute transfers or approvals to other entities to operate on its behalf if _blockUser was not called with such account as an argument. Similarly, the account will be unblocked again if _unblockUser is called.

Functions
  • blocked(account)

  • _blockUser(user)

  • _unblockUser(user)

  • _update(from, to, value)

  • _approve(owner, spender, value, emitEvent)

ERC20
  • name()

  • symbol()

  • decimals()

  • totalSupply()

  • balanceOf(account)

  • transfer(to, value)

  • allowance(owner, spender)

  • approve(spender, value)

  • transferFrom(from, to, value)

  • _transfer(from, to, value)

  • _mint(account, value)

  • _burn(account, value)

  • _approve(owner, spender, value)

  • _spendAllowance(owner, spender, value)

Events
  • UserBlocked(user)

  • UserUnblocked(user)

IERC20
  • Transfer(from, to, value)

  • Approval(owner, spender, value)

Errors
  • ERC20Blocked(user)

IERC20Errors
  • ERC20InsufficientBalance(sender, balance, needed)

  • ERC20InvalidSender(sender)

  • ERC20InvalidReceiver(receiver)

  • ERC20InsufficientAllowance(spender, allowance, needed)

  • ERC20InvalidApprover(approver)

  • ERC20InvalidSpender(spender)

blocked(address account) → bool public

Returns the blocked status of an account.

_blockUser(address user) → bool internal

Blocks a user from receiving and transferring tokens, including minting and burning.

_unblockUser(address user) → bool internal

Unblocks a user from receiving and transferring tokens, including minting and burning.

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

See {ERC20-_update}.

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

See {ERC20-_approve}.

UserBlocked(address indexed user) event

Emitted when a user is blocked.

UserUnblocked(address indexed user) event

Emitted when a user is unblocked.

ERC20Blocked(address user) error

The operation failed because the user is blocked.

ERC20Collateral

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

Extension of {ERC20} that limits the supply of tokens based on a collateral amount and time-based expiration.

The collateral function must be implemented to return the collateral data. This function can call external oracles or use any local storage.

Functions
  • constructor(liveness_)

  • liveness()

  • clock()

  • CLOCK_MODE()

  • collateral()

  • _update(from, to, value)

ERC20
  • name()

  • symbol()

  • decimals()

  • totalSupply()

  • balanceOf(account)

  • transfer(to, value)

  • allowance(owner, spender)

  • approve(spender, value)

  • transferFrom(from, to, value)

  • _transfer(from, to, value)

  • _mint(account, value)

  • _burn(account, value)

  • _approve(owner, spender, value)

  • _approve(owner, spender, value, emitEvent)

  • _spendAllowance(owner, spender, value)

Events
IERC20
  • Transfer(from, to, value)

  • Approval(owner, spender, value)

Errors
  • ERC20ExceededSupply(increasedSupply, cap)

  • ERC20ExpiredCollateral(timestamp, expiration)

IERC20Errors
  • ERC20InsufficientBalance(sender, balance, needed)

  • ERC20InvalidSender(sender)

  • ERC20InvalidReceiver(receiver)

  • ERC20InsufficientAllowance(spender, allowance, needed)

  • ERC20InvalidApprover(approver)

  • ERC20InvalidSpender(spender)

constructor(uint48 liveness_) internal

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

liveness() → uint48 public

Returns the minimum liveness duration of collateral.

clock() → uint48 public

Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).

CLOCK_MODE() → string public

Description of the clock

collateral() → uint256 amount, uint48 timestamp public

Returns the collateral data of the token.

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

See {ERC20-_update}.

ERC20ExceededSupply(uint256 increasedSupply, uint256 cap) error

Total supply cap has been exceeded.

ERC20ExpiredCollateral(uint48 timestamp, uint48 expiration) error

Collateral amount has expired.

ERC20Custodian

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

Extension of {ERC20} that allows to implement a custodian mechanism that can be managed by an authorized account with the freeze function.

This mechanism allows a custodian (e.g. a DAO or a well-configured multisig) to freeze and unfreeze the balance of a user.

The frozen balance is not available for transfers or approvals to other entities to operate on its behalf if. The frozen balance can be reduced by calling freeze again with a lower amount.

Modifiers
  • onlyCustodian()

Functions
  • frozen(user)

  • freeze(user, amount)

  • availableBalance(account)

  • _isCustodian(user)

  • _update(from, to, value)

ERC20
  • name()

  • symbol()

  • decimals()

  • totalSupply()

  • balanceOf(account)

  • transfer(to, value)

  • allowance(owner, spender)

  • approve(spender, value)

  • transferFrom(from, to, value)

  • _transfer(from, to, value)

  • _mint(account, value)

  • _burn(account, value)

  • _approve(owner, spender, value)

  • _approve(owner, spender, value, emitEvent)

  • _spendAllowance(owner, spender, value)

Events
  • TokensFrozen(user, amount)

  • TokensUnfrozen(user, amount)

IERC20
  • Transfer(from, to, value)

  • Approval(owner, spender, value)

Errors
  • ERC20InsufficientUnfrozenBalance(user)

  • ERC20InsufficientFrozenBalance(user)

  • ERC20NotCustodian()

IERC20Errors
  • ERC20InsufficientBalance(sender, balance, needed)

  • ERC20InvalidSender(sender)

  • ERC20InvalidReceiver(receiver)

  • ERC20InsufficientAllowance(spender, allowance, needed)

  • ERC20InvalidApprover(approver)

  • ERC20InvalidSpender(spender)

onlyCustodian() modifier

Modifier to restrict access to custodian accounts only.

frozen(address user) → uint256 public

Returns the amount of tokens frozen for a user.

freeze(address user, uint256 amount) external

Adjusts the amount of tokens frozen for a user.

availableBalance(address account) → uint256 available public

Returns the available (unfrozen) balance of an account.

_isCustodian(address user) → bool internal

Checks if the user is a custodian.

_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.

TokensFrozen(address indexed user, uint256 amount) event

Emitted when tokens are frozen for a user.

TokensUnfrozen(address indexed user, uint256 amount) event

Emitted when tokens are unfrozen for a user.

ERC20InsufficientUnfrozenBalance(address user) error

The operation failed because the user has insufficient unfrozen balance.

ERC20InsufficientFrozenBalance(address user) error

The operation failed because the user has insufficient frozen balance.

ERC20NotCustodian() error

Error thrown when a non-custodian account attempts to perform a custodian-only operation.

ERC4626Fees

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

ERC-4626 vault with entry/exit fees expressed in basis point (bp).

Functions
  • previewDeposit(assets)

  • previewMint(shares)

  • previewWithdraw(assets)

  • previewRedeem(shares)

  • _deposit(caller, receiver, assets, shares)

  • _withdraw(caller, receiver, owner, assets, shares)

  • _entryFeeBasisPoints()

  • _exitFeeBasisPoints()

  • _entryFeeRecipient()

  • _exitFeeRecipient()

ERC4626
  • decimals()

  • asset()

  • totalAssets()

  • convertToShares(assets)

  • convertToAssets(shares)

  • maxDeposit()

  • maxMint()

  • maxWithdraw(owner)

  • maxRedeem(owner)

  • deposit(assets, receiver)

  • mint(shares, receiver)

  • withdraw(assets, receiver, owner)

  • redeem(shares, receiver, owner)

  • _convertToShares(assets, rounding)

  • _convertToAssets(shares, rounding)

  • _decimalsOffset()

ERC20
  • name()

  • symbol()

  • totalSupply()

  • balanceOf(account)

  • transfer(to, value)

  • allowance(owner, spender)

  • approve(spender, value)

  • transferFrom(from, to, value)

  • _transfer(from, to, value)

  • _update(from, to, value)

  • _mint(account, value)

  • _burn(account, value)

  • _approve(owner, spender, value)

  • _approve(owner, spender, value, emitEvent)

  • _spendAllowance(owner, spender, value)

Events
IERC4626
  • Deposit(sender, owner, assets, shares)

  • Withdraw(sender, receiver, owner, assets, shares)

IERC20
  • Transfer(from, to, value)

  • Approval(owner, spender, value)

Errors
ERC4626
  • ERC4626ExceededMaxDeposit(receiver, assets, max)

  • ERC4626ExceededMaxMint(receiver, shares, max)

  • ERC4626ExceededMaxWithdraw(owner, assets, max)

  • ERC4626ExceededMaxRedeem(owner, shares, max)

IERC20Errors
  • ERC20InsufficientBalance(sender, balance, needed)

  • ERC20InvalidSender(sender)

  • ERC20InvalidReceiver(receiver)

  • ERC20InsufficientAllowance(spender, allowance, needed)

  • ERC20InvalidApprover(approver)

  • ERC20InvalidSpender(spender)

previewDeposit(uint256 assets) → uint256 public

Preview taking an entry fee on deposit. See {IERC4626-previewDeposit}.

previewMint(uint256 shares) → uint256 public

Preview adding an entry fee on mint. See {IERC4626-previewMint}.

previewWithdraw(uint256 assets) → uint256 public

Preview adding an exit fee on withdraw. See {IERC4626-previewWithdraw}.

previewRedeem(uint256 shares) → uint256 public

Preview taking an exit fee on redeem. See {IERC4626-previewRedeem}.

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

Send entry fee to _entryFeeRecipient. See {IERC4626-_deposit}.

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

Send exit fee to _exitFeeRecipient. See {IERC4626-_deposit}.

_entryFeeBasisPoints() → uint256 internal

_exitFeeBasisPoints() → uint256 internal

_entryFeeRecipient() → address internal

_exitFeeRecipient() → address internal