RWA token
Each asset is represented by its own RWAToken, an ERC-20 security token in the style of ERC-3643. It carries the asset's investor rules, its payout machinery and the controls a regulated issuer needs.
Lifecycle
- Create. An approved issuer calls
RWATokenFactory.createToken(config). The token is deployed as a beacon proxy and the issuer becomes itsadmin. Governance then registers it as a system contract. - Fund. Units are minted to investors through an offering, or directly by the admin with
mintFor, to eligible wallets only. - Operate. The issuer distributes revenue as dividends and funds the redemption pool; holders claim, redeem and trade.
- Mature. Once
maturityTimepasses, anyone can callcheckMaturity()to move the token to Matured. Ordinary transfers stop, units can still leave venues towards eligible holders, and redemptions continue.
Configuration
| Setting | Meaning | Changeable later? |
|---|---|---|
name, symbol, decimals | ERC-20 metadata; symbols are unique across the factory | No |
assetClass | A short tag such as solar, wind or storage | No |
settlementToken | The stablecoin for dividends, redemptions and offerings (must be allowlisted) | No |
requireKyc | Every party must hold valid KYC | No |
requireAccredited | Receivers must be accredited | Yes, by the admin |
allowedJurisdictions | Jurisdictions receivers may be in (empty = any, including unknown) | Yes |
redemptionPrice | Settlement units paid per 10^decimals token units (0 = redemption disabled) | Yes |
redemptionDelaySeconds | Notice period between request and execution (capped) | Yes |
perHolderCap | Maximum balance per holder (0 = unlimited) | Yes |
maturityTime | When the token matures (0 = perpetual) | Yes |
deviceIds | AssetHub devices producing this asset's revenue | Yes |
metadataURI | Offering documents and legal terms (IPFS or HTTPS) | Yes |
Holders should read "changeable later" carefully. The admin can lower the redemption price, move the maturity date, change the eligible jurisdictions and change the holder cap at any time with updateToken. The contract does not cap the supply either: the admin can mint more units to eligible wallets. Every change emits an event, but none requires holder consent.
Status
| Status | Transfers | Mints | Redemption requests | Dividends |
|---|---|---|---|---|
| Active | Allowed (subject to rules) | Allowed | Allowed | Allowed |
| Paused | Blocked | Blocked | Blocked | Claims still allowed |
| Matured | Only out of venues, to eligible holders | Blocked | Allowed | Allowed |
The admin can set any status at any time, including moving a matured token back to active. checkMaturity() is the permissionless path from Active to Matured.
Dividends
Revenue is paid with a per-unit accumulator, so the cost of a distribution does not depend on the number of holders.
- The issuer approves the token to pull settlement from the issuer's wallet (a standing allowance lets a keeper trigger distributions).
distributeDividend(amount)pullsamountand addsamount × 10²⁷ / eligibleSupplytoaccDividendPerUnit.- Each holder's claimable amount is
balance × (accDividendPerUnit − holder checkpoint) / 10²⁷, plus anything already settled. It is updated automatically whenever their balance changes. - Holders pull their share with
claimDividends()whenever they like. Claims are subject to receiver compliance.
Eligible supply is total supply minus units escrowed for redemption and minus balances of venues that do not earn dividends. Rounding dust stays in dividendResidual, which the admin can sweep. It never touches holder entitlements.
Dividends are not guaranteed. They exist only when the issuer distributes. The chain guarantees that a distribution is shared pro rata and can be claimed; it cannot guarantee that the asset earns revenue or that the issuer passes it on.
Redemptions
- The holder calls
requestRedemption(units). The units move into the token's escrow and stop earning dividends. The payout is fixed at request time:units × redemptionPrice / 10^decimals. - After
executeAfter(request time plus the notice period), anyone can callexecuteRedemption(id). The admin or governance may execute earlier. - Execution pays the holder from the redemption pool and burns the escrowed units. If the pool is short, execution reverts until the issuer tops it up with
fundRedemptionPool. Execution also applies the token's receiver rules to the holder, so a holder who has since lost eligibility (KYC, accreditation, jurisdiction, freeze) must regain it before being paid. - The admin can cancel a pending request with a reason; the units return to the holder.
Each holder may have a limited number of pending requests (64 by default). Redemption requests are refused while the token is paused.
Issuer powers
| Power | Function |
|---|---|
| Mint to eligible wallets | mintFor |
| Burn from any holder (clawback) | burn |
| Forced transfer between holders | forceTransfer |
| Freeze / unfreeze a holder for this token | setFrozen |
| Pause, resume or mature the token | setStatus |
| Update terms (see the table above) | updateToken |
| Approve venues and their dividend treatment | setVenue, setVenueDividends |
| Distribute dividends, sweep dust | distributeDividend, sweepDividendResidual |
| Fund the pool, cancel requests | fundRedemptionPool, cancelRedemption |
Governance holds every admin power as well, and can additionally replace the admin (setAdmin), change per-token parameters and upgrade all tokens through the beacon.
Device binding
A token lists the AssetHub devices behind its revenue. At creation, each device must exist, be active and be operated by the token's admin. Only governance can bind devices run by someone else. See AssetHub.
Events
Minted, Burned, ForceTransferred, FrozenSet, TokenStatusSet, TokenUpdated, VenueSet, VenueDividendsSet, DividendDistributed, DividendClaimed, PoolFunded, RedemptionRequested, RedemptionExecuted, RedemptionCancelled, plus standard ERC-20 events.