Source code
1. Overview
1. Overview
RWAToken is not a plain ERC-20 used only for bookkeeping. From a system perspective, it serves two roles:- As the on-chain tokenized representation of RWA units, tracking balances, transfers, and burns.
- As the primary-sale entrypoint, receiving
USDTduring a sale window and minting tokens to buyers according to predefined rules.
2. Responsibilities and Business Goals
2. Responsibilities and Business Goals
- Binding token metadata, custody wallet,
USDTaddress, and the compliance module during initialization. - Managing supply under a fixed hard cap and minting the reserved tranche to
custodyWalletat deployment time. - Handling primary sales via
mint(). Before payingUSDT, a buyer must pass off-chain compliance authorization verification via a signature. - Integrating with
ComplianceManageon transfer paths to restrict blacklisted addresses. - Providing administrative capabilities for operations and compliance handling, such as forced transfers, token recovery, and transfer lock updates.
3. Architecture Positioning and External Dependencies
3. Architecture Positioning and External Dependencies
RWAToken depends on the following external components:USDT: the payment asset for the primary sale.ComplianceManage: the external compliance service contract responsible for blacklist checks, signature verification, and related controls.ArtStarERC1967Proxy: the proxy contract that holds state for the upgradeable deployment.
initialize() calldata. After that, the proxy address is registered in ComplianceManage under verifiedTokens.4. Standards, EIPs, and Base Components
4. Standards, EIPs, and Base Components
- ERC-20 & SafeERC20
- ERC-1967 & UUPS
- Governance and Pausing
- Security and Math
SafeERC20 to wrap transferFrom and transfer calls for more robust interactions and reduced integration risk.5. State Variables and Core Invariants
5. State Variables and Core Invariants
TOTAL_SUPPLY_CAP = 10,000,000 * 1e18RESERVED_AMOUNT = 2,000,000 * 1e18SALE_CAP = TOTAL_SUPPLY_CAP - RESERVED_AMOUNT
custodyWallet during initialization, leaving 8,000,000 as the maximum available amount for primary sales.Other key state variables:sold: total amount sold via primary sales.priceUSDT/minPurchaseUSDT/maxPurchaseUSDT: pricing and per-purchase bounds.saleActive/saleStartTime/saleEndTime: sale switch and time window.unlockTime: transfer unlock time;0means no lock.assetInfo: underlying asset metadata URI, valuation, and the last valuation update timestamp.
6. Initialization and Deployment
6. Initialization and Deployment
initialize() takes the token name and symbol, initial owner, custodyWallet, USDT address, and ComplianceManage address.The flow includes:- Calling an internal
initfunction. - Validating that external dependency addresses are non-zero and persisting references.
- Minting
RESERVED_AMOUNTdirectly tocustodyWallet.
7. Primary Sale Flow
7. Primary Sale Flow
Operational configuration
startSale().Compliance verification
ComplianceManage.RWAToken delegates compliance authorization to ComplianceManage. Token logic and compliance logic are separated, but primary-sale availability depends on the external compliance contract’s configuration and state.8. Transfers, Pausing, Lockups, and Blacklist Constraints
8. Transfers, Pausing, Lockups, and Blacklist Constraints
_update(), the contract centralizes multiple constraints at the state transition entrypoint:- Pause constraint: when paused, both regular transfers and primary sales (
mint) are rejected. - Lockup constraint: when
unlockTime != 0and the unlock time has not been reached, regular transfers are rejected. - Blacklist constraint: when the sender or recipient is blacklisted in
ComplianceManage, regular transfers are rejected.
9. Admin Capabilities and Operational Controls
9. Admin Capabilities and Operational Controls
- Configuring price, purchase bounds, sale window, and sale switch.
- Setting or clearing the transfer lock time (including emergency unlock).
- Pausing and unpausing the full token system.
- Forced transfers
forcedTransfer(), burningburn(), recoveryrecoverTokens(), and related controls. - Updating underlying asset information via
updateAssetInfo().
10. Asset Disclosure and Recovery Mechanisms
10. Asset Disclosure and Recovery Mechanisms
assetInfo stores the underlying asset’s metadataURI and valuation data. Valuation accuracy depends entirely on owner updates.Recovery-focused functions reflect real-world operations:recoverTokens(): recover anyERC-20mistakenly sent to the contract.recoverUnsoldTokens(): after the sale ends, mint the remaining sale capacity to the custody wallet in one action.forcedTransfer(): forcibly move tokens for compliance or dispute-resolution scenarios.
11. Upgrade Mechanism and Security Considerations
11. Upgrade Mechanism and Security Considerations
- The proxy address remains unchanged; state is stored in the proxy.
- Only the owner can pass
_authorizeUpgrade(). - New implementations must preserve storage layout compatibility.
- Compliance dependency: correct
ComplianceManageconfiguration is critical. - Concentrated privileges: high-privilege operations require strong key management.
- Price conversion:
priceUSDTprecision and conversion rules must be strictly consistent.