Skip to content

DigiShares/ABT20

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ABT20 Token Suite

A modular suite of ERC20 token contracts for Real World Asset (RWA) tokenization, built by Digishares. Each contract in the suite is a deployable, self-contained token that combines a base ERC20 implementation with configurable extensions (minting, burning, supply cap, and pausability).

Overview

The suite is built around a single abstract base contract, ABT20, and ships 12 concrete variants that cover every combination of optional features. Deployers select the variant that matches their asset's operational requirements and deploy it directly — no proxy, no upgradability, no post-deployment configuration required beyond role assignment at construction.

All contracts are compiled with Solidity 0.8.34 and depend on OpenZeppelin Contracts.


Architecture

Base Contract: ABT20

ABT20 (abstract)
 ├── ERC20           — standard fungible token
 ├── ERC20Permit     — gasless approvals via EIP-2612 signatures
 └── Multicall       — batch multiple calls in one transaction

ABT20 adds one extension on top of OpenZeppelin's ERC20: a configurable decimals value set at deployment time. Standard ERC20 hardcodes decimals to 18; RWA tokens often represent whole units (shares, units of property, bonds) and may use 0 or other non-standard values.

Contract Variants

Each concrete contract inherits ABT20 and layers optional extensions:

Contract Mint Burn Cap Pause
ABT20Basic
ABT20Mint
ABT20Burn
ABT20Pause
ABT20MintBurn
ABT20MintPause
ABT20BurnPause
ABT20MintCap
ABT20MintBurn
ABT20MintBurnPause
ABT20MintCapPause
ABT20MintBurnCap
ABT20MintBurnCapPause

Feature Reference

Mint

Contracts with minting expose:

function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE)

Only addresses holding MINTER_ROLE can issue new tokens. In non-capped variants, there is no upper bound on total supply — the minter can issue any amount.

Burn

Contracts with burning expose:

function burn(address from, uint256 amount) external onlyRole(BURNER_ROLE)

Important: This is a forced burn — the burner can destroy tokens from any address without that address's approval. This is intentional for RWA use cases that require regulatory clawback or forced redemption (e.g., AML compliance, asset maturity). Token holders should be made aware of this at onboarding. It differs from ERC20Burnable's burnFrom(), which requires an allowance.

Cap

Uses OpenZeppelin's ERC20Capped. The maximum supply is set at deployment and enforced on every mint. It cannot be changed after deployment.

Pause

Contracts with pause expose:

function pause()   external onlyRole(PAUSER_ROLE)
function unpause() external onlyRole(PAUSER_ROLE)

When paused, all token transfers (including mint and burn) revert. This is enforced via an _update override with whenNotPaused.


Roles and Access Control

All contracts except ABT20Basic use OpenZeppelin's AccessControlEnumerable, which supports on-chain enumeration of role members — useful for compliance dashboards.

Role Constant Capability
DEFAULT_ADMIN_ROLE 0x00 Grant and revoke all roles
MINTER_ROLE keccak256("MINTER_ROLE") Call mint()
BURNER_ROLE keccak256("BURNER_ROLE") Call burn() (forced, no allowance required)
PAUSER_ROLE keccak256("PAUSER_ROLE") Call pause() / unpause()

Roles are granted at construction time. The DEFAULT_ADMIN_ROLE holder can grant or revoke roles after deployment using the standard AccessControl interface (grantRole, revokeRole).

Operational security: The DEFAULT_ADMIN_ROLE should be held by a multisig (e.g., Gnosis Safe) rather than an EOA in production. A compromised admin key can grant minting or burning rights to any address.


Constructor Parameters

All variants

Parameter Type Description
name string ERC20 token name (also used as EIP-712 domain name for Permit)
symbol string ERC20 token symbol
decimals_ uint8 Token decimal places (commonly 0 for whole-unit RWA tokens, 18 for divisible assets)
initialSupply uint256 Tokens minted to initialHolder on deployment
initialHolder address Recipient of the initial supply

Role-based variants (all except ABT20Basic)

Parameter Type Description
defaultAdmin address Receives DEFAULT_ADMIN_ROLE; can manage all other roles
minter address Receives MINTER_ROLE (mint variants only)
burner address Receives BURNER_ROLE (burn variants only)
pauser address Receives PAUSER_ROLE (pause variants only)

Capped variants

Parameter Type Description
cap uint256 Maximum total supply (must be ≥ initialSupply)

Development

This project uses Foundry.

Prerequisites

curl -L https://foundry.paradigm.xyz | bash
foundryup

Install dependencies

forge install

Build

forge build

Test

forge test

Test with verbosity

forge test -vvv

Format

forge fmt

Gas snapshots

forge snapshot

Deploy a contract

Replace ABT20Basic and constructor args with your chosen variant:

forge script script/<ScriptName>.s.sol \
  --rpc-url <your_rpc_url> \
  --private-key <your_private_key> \
  --broadcast

Local node

anvil

Dependencies

Library Version Purpose
OpenZeppelin Contracts v5.x ERC20, AccessControl, Pausable, Multicall, ERC20Permit, ERC20Capped
forge-std latest Foundry testing utilities

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors