Skip to main content

ERC-20 Bridgeable Module

Internal functions for cross-chain ERC20 token operations

Key Features
  • Internal functions for cross-chain token operations.
  • Leverages diamond storage for access control roles (trusted-bridge).
  • Emits CrosschainBurn and CrosschainMint events for off-chain monitoring.
  • Does not use using directives or external dependencies.
Module Usage

This module provides internal functions for use in your custom facets. Import it to access shared logic and storage.

Overview

This module provides internal functions for cross-chain ERC20 token transfers, specifically for burning and minting tokens across different chains. It relies on diamond storage for managing access control roles, ensuring that only trusted bridges can execute these sensitive operations. Changes to token balances are immediately visible to all facets interacting with the same diamond storage.

Storage

AccessControlStorage

storage struct for the AccessControl. storage-location: erc8042:compose.accesscontrol

Definition
struct AccessControlStorage {
mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole;
}

ERC20Storage

ERC-8042 compliant storage struct for ERC20 token data. storage-location: erc8042:erc20

Definition
struct ERC20Storage {
mapping(address owner => uint256 balance) balanceOf;
uint256 totalSupply;
}

State Variables

PropertyTypeDescription
ERC20_STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("erc20"))
ACCESS_STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("compose.accesscontrol"))

Functions

checkTokenBridge

Internal check to check if the bridge (caller) is trusted. Reverts if caller is zero or not in the AccessControl trusted-bridge role.

function checkTokenBridge(address _caller) view;

Parameters:

PropertyTypeDescription
_calleraddressThe address to validate

crosschainBurn

Cross-chain burn — callable only by an address having the trusted-bridge role.

function crosschainBurn(address _from, uint256 _value) ;

Parameters:

PropertyTypeDescription
_fromaddressThe account to burn tokens from.
_valueuint256The amount to burn.

crosschainMint

Cross-chain mint — callable only by an address having the trusted-bridge role.

function crosschainMint(address _account, uint256 _value) ;

Parameters:

PropertyTypeDescription
_accountaddressThe account to mint tokens to.
_valueuint256The amount to mint.

getAccessControlStorage

helper to return AccessControlStorage at its diamond slot

function getAccessControlStorage() pure returns (AccessControlStorage storage s);

getERC20Storage

Returns the ERC20 storage struct from the predefined diamond storage slot. Uses inline assembly to set the storage slot reference.

function getERC20Storage() pure returns (ERC20Storage storage s);

Returns:

PropertyTypeDescription
sERC20StorageThe ERC20 storage struct reference.

Events

Errors

Best Practices

Best Practice
  • Ensure the caller has the trusted-bridge role before invoking crosschainBurn or crosschainMint.
  • Verify that the diamond storage layout remains compatible when upgrading facets to prevent storage collisions.
  • Handle potential reverts from ERC20InsufficientBalance, ERC20InvalidBridgeAccount, ERC20InvalidCallerAddress, ERC20InvalidReceiver, or ERC20InvalidSender.

Integration Notes

Shared Storage

This module utilizes the diamond storage pattern, with its state stored at the ERC20_STORAGE_POSITION slot, identified by keccak256("erc20"). Functions like crosschainBurn and crosschainMint directly read from and write to the shared diamond storage. The AccessControlStorage struct, though empty in the provided definition, is conceptually used for role management. Any changes made to token balances via this module are immediately reflected for all other facets accessing the same storage.

Was this helpful?
Last updated:

Newsletter

Get notified about releases, feature announcements, and technical deep-dives on building smart contracts with Compose.

No spam. Unsubscribe anytime.