Skip to content
Lattice

ERC20Lib

Git Source

Title: ERC20Lib

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)

Library implementing the ERC-20 token standard.

Mirrors OpenZeppelin v5.6.1 ERC20 logic. All state lives in an ERC-7201 slot. Differences from OpenZeppelin:

  • The caller is msg.sender, not _msgSender(); Lattice has no ERC-2771 context.
  • Nothing here is virtual. OpenZeppelin extensions override _update, _approve and _spendAllowance; a Lattice extension that changes movement replaces the facet's transfer/transferFrom instead (decision D25 on #234). Every other ERC20Lib caller (ERC20Burnable, ERC20FlashMint, ERC20Wrapper, ERC20Crosschain, ERC7802, ERC1363, ERC4626, VaultCore, GovernedVault) skips that replacement, so those extensions are mutually exclusive with ERC20Pausable and ERC20Votes where they move tokens.
  • _spendAllowance reads the allowance from storage, not through an overridable allowance(). It keeps the != type(uint256).max test that OpenZeppelin v5.2 rewrote as &lt;: the two agree for every uint256, and != measured 3 gas cheaper per transferFrom.
  • decimals is fixed at 18; a facet that needs another value replaces the decimals() selector (ERC4626, ERC20Wrapper).
  • __ERC20_init sets the name and symbol in the diamond's initializer, not a constructor.
  • OpenZeppelin's ERC20 has no ERC-165. __ERC20_init registers IERC20, whose id 0x942e8b22 also covers name, symbol and decimals, so it is not the bare ERC-20 id 0x36372b07.
  • The ERC-6093 errors are declared on IERC20 rather than IERC20Errors; their selectors are the same. See docs/guides/selector-compatibility.md#token-extension-hook-model.

Functions

erc20Storage

function erc20Storage() internal pure returns (ERC20Storage storage $);

Returns

NameTypeDescription
$ERC20Storage

__ERC20_init

Initializes the ERC-20 module with name and symbol.

Must be called inside a pre/postInitializer block.

function __ERC20_init(string memory name_, string memory symbol_) internal;

Parameters

NameTypeDescription
name_string
symbol_string

registerInterface

Registers support for the IERC20 interface via ERC-165.

function registerInterface() internal;

totalSupply

Returns the total token supply.

function totalSupply() internal view returns (uint256);

Returns

NameTypeDescription
<none>uint256

balanceOf

Returns the token balance of account.

function balanceOf(address account) internal view returns (uint256);

Parameters

NameTypeDescription
accountaddress

Returns

NameTypeDescription
<none>uint256

allowance

Returns the remaining allowance of spender over owner's tokens.

function allowance(address owner, address spender) internal view returns (uint256);

Parameters

NameTypeDescription
owneraddress
spenderaddress

Returns

NameTypeDescription
<none>uint256

name

Returns the token name.

function name() internal view returns (string memory);

Returns

NameTypeDescription
<none>string

symbol

Returns the token symbol.

function symbol() internal view returns (string memory);

Returns

NameTypeDescription
<none>string

decimals

Returns the number of decimals — always 18 unless overridden by the facet.

function decimals() internal view returns (uint8);

Returns

NameTypeDescription
<none>uint8

transfer

Moves value tokens from the caller to to.

function transfer(address to, uint256 value) internal returns (bool);

Parameters

NameTypeDescription
toaddress
valueuint256

Returns

NameTypeDescription
<none>bool

transferFrom

Moves value tokens from from to to using the caller's allowance.

function transferFrom(address from, address to, uint256 value) internal returns (bool);

Parameters

NameTypeDescription
fromaddress
toaddress
valueuint256

Returns

NameTypeDescription
<none>bool

approve

Sets value as the allowance of spender over the caller's tokens.

function approve(address spender, uint256 value) internal returns (bool);

Parameters

NameTypeDescription
spenderaddress
valueuint256

Returns

NameTypeDescription
<none>bool

_transfer

Entry-point transfer helper; reverts on zero sender or receiver.

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

Parameters

NameTypeDescription
fromaddress
toaddress
valueuint256

_update

Actual state-change for all token movements; emits Transfer.

Runs no extension hook (D25): unlike OpenZeppelin's virtual _update, it cannot be overridden, so a pause or vote checkpoint applies only on the facet selectors that wrap it.

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

Parameters

NameTypeDescription
fromaddress
toaddress
valueuint256

_mint

Mints value tokens to to.

function _mint(address to, uint256 value) internal;

Parameters

NameTypeDescription
toaddress
valueuint256

_burn

Burns value tokens from from.

function _burn(address from, uint256 value) internal;

Parameters

NameTypeDescription
fromaddress
valueuint256

_approve

3-arg entry-point for approve operations. Always emits the Approval event.

This is the public hook-point for override chains (Permit, Votes extensions). Mirrors OZ's _approve(address,address,uint256) which delegates to the 4-arg variant. Extensions that need to intercept approval at the entry-point should shadow this.

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

Parameters

NameTypeDescription
owneraddress
spenderaddress
valueuint256

_approve

Sets the allowance and optionally emits Approval.

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

Parameters

NameTypeDescription
owneraddress
spenderaddress
valueuint256
emitEventbool

_spendAllowance

Decreases the allowance of spender over owner's tokens by value.

Skips decrement when allowance is type(uint256).max (infinite allowance).

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

Parameters

NameTypeDescription
owneraddress
spenderaddress
valueuint256