Contract descriptions
AnkaraChainBaseToken
The abstract ERC-20 base inherited by all six token templates. Extends OpenZeppelin’s ERC20Upgradeable, ERC20PausableUpgradeable, OwnableUpgradeable, and UUPSUpgradeable. Adds:
assetId— immutablebytes32identifier set at initializationcountryCode— ISO 3166-1 alpha-2 string (e.g."NG","KE")status—AssetStatusenum (DRAFT=0,ACTIVE=1,SUSPENDED=2,REDEEMED=3,EXPIRED=4)identityVerifier— optionalIIdentityVerifierthat gates transfers and mintingmetadataVersion— increments on every metadata update for off-chain indexing
TokenFactory
Deploys ERC-1967 proxies against registered template implementations. Key functions:
TokenDeployed(uint8 template, address tokenAddress, address deployer, bytes32 assetId, string countryCode, uint256 timestamp).
Six template contracts
All six share the
AnkaraChainBaseToken interface (mint, burn, pause, unpause, setStatus, setIdentityVerifier, getMetadata).
WhitelistVerifier
Implements the IIdentityVerifier interface. An admin-managed address allowlist. Attach it to any token at deploy time via identityVerifier in BaseDeployOptions, or update it later via setIdentityVerifier.
Upgrade pattern
The contracts use UUPS (Universal Upgradeable Proxy Standard, EIP-1822) with OpenZeppelin v5. Under UUPS, the upgrade logic lives in the implementation contract itself — not the proxy. This means the implementation can enforce authorization (only the owner can upgrade) and can be replaced without changing the proxy address your users interact with. To upgrade a deployed token:- Deploy a new implementation contract (e.g.
FarmlandTokenV2). - Call
upgradeToAndCallon the proxy address from the owner wallet.
The
TokenFactory deploys proxies using OpenZeppelin’s ERC1967Proxy. The upgradeToAndCall function is available on any proxy address and can be called from the owner wallet.Roles and access control
Role management is handled by OpenZeppelin’sOwnableUpgradeable. The owner of a token (the admin address set at deployment, defaulting to the deployer) controls:
- Minting:
mint(address to, uint256 amount)— owner only - Burning:
burn(uint256 amount)— token holder (anyone burns their own tokens) - Status updates:
setStatus(uint8 newStatus)— owner only - Metadata updates:
updateValuation,updateTitleDocument, etc. — owner only - Pause / unpause:
pause()/unpause()— owner only - Identity verifier:
setIdentityVerifier(address verifier)— owner only - Upgrades:
upgradeToAndCall— owner only
transferOwnership.
Compiling and testing locally
Clone the repository and install dependencies, then use these commands from the repo root or frompackages/contracts-evm:
.env.example in packages/contracts-evm):
Deployment with the CLI
For production deployments, use thenpx ankara CLI rather than running Hardhat scripts directly.
Source code
The EVM contracts are open source under the MIT License: github.com/ankarachain/ankara-core/tree/main/packages/contracts-evm The package is@ankarachain/contracts-evm (private — not published to npm). Build with Hardhat ^2.22.0 and OpenZeppelin Contracts ^5.0.0.