ERC-1450 RTA-Controlled Security Token

Final · Tokens · created 2018-09-25

A standard that records securities issued under US securities regulations (Reg CF, D, A) as tokens and allows only the Registered Transfer Agent (RTA) to execute transfers, issuance and burns.

Why it is needed

Turning securities such as stocks into blockchain tokens makes recording and transferring ownership easier, but a regular ERC-20 token can be sent freely by anyone, which conflicts with securities regulation. US securities regulation requires a Registered Transfer Agent (RTA) to have exclusive control over securities transfers. It also requires investor identity verification (KYC), anti-money laundering (AML), recovery of lost or stolen securities, forced transfers under court orders (divorce, inheritance, recovery of fraud losses and so on), and record keeping for regulatory examination. The existing ERC-20 has no such regulatory role, and other security token standards have not directly addressed the US RTA system. ERC-1450 fills this gap by making every token movement execute only through the RTA.

What to implement

In depth

A restricted ERC-20 interface that blocks direct transfers

ERC-1450 extends ERC-20 but behaves differently. transfer, approve and transferFrom must always revert with the ERC1450TransferDisabled error, and allowance must always return 0. Actual value movement happens only through the RTA-only functions transferFromRegulated, mint and burnFrom. This keeps read functions such as balanceOf and totalSupply compatible with existing ERC-20 infrastructure while routing every token movement through a single regulated RTA. Errors follow the ERC-6093 standard error format for tooling compatibility.

Separation of three roles and the security design of changeIssuer

Roles are divided into three: issuer (Owner/Issuer), RTA, and token holder. The issuer creates and owns the securities but cannot control token transfers, and only the RTA has the authority to transfer, issue and burn. In particular, changeIssuer can be called only by the RTA, not by the issuer. This differs from OpenZeppelin Ownable, where the owner hands over ownership themselves, so even if the issuer's private key is stolen, an attacker cannot replace the RTA or steal tokens. setTransferAgent is for the issuer to set an RTAProxy once at the start, after which it is locked and only the RTA can replace itself through the proxy.

Tracking regulation type and issuance date per batch

Every issuance must specify a regulation type (regulationType, uint16) and the original issuance date (issuanceDate), and no security exists without a regulation. A TokensMinted event must be emitted for every mint and a TokensBurned event for every burn, so the full shareholder register (cap table) can be reconstructed from events alone. When tokenizing an existing security, issuanceDate is recorded as the time the investor originally bought it, and the RTA uses it to calculate the holding period. getHolderRegulations, getRegulationSupply and getDetailedBatchInfo let you query a holder's composition by batch and the total issuance by regulation, and batchMint, batchTransferFrom and batchBurnFrom handle bulk operations such as dividend distribution or redemption.

Transfer requests, fees and the broker system

A holder can request a transfer with requestTransferWithFee, but no value moves until the RTA approves and executes it. If msg.sender is not the holder, it must be a broker registered with setBrokerStatus, and the RTA approves a broker after an off-chain application, KYC and AML screening, and contract signing. The fee is paid in the fee token set by the RTA (getFeeToken), and is either flat or a percentage based on basis points. A request follows the state machine Requested, UnderReview, Approved, Rejected, Executed, Expired, and each requestId is executed only once. On rejection, a uint16 reason code (for example 1 for KYC failure, 13 for jurisdiction restriction, 14 for failing the accredited investor requirement) and whether the fee is refunded are recorded, and the implementation must clearly document its refund policy.

Lost wallet recovery and court-ordered transfers

The essential basis for recovery is controllerTransfer. The RTA verifies the investor's identity using existing off-chain KYC records, executes the transfer immediately, and must emit a ControllerTransfer event (compatible with ERC-1644). The same function is used for court orders such as divorce, inheritance and recovery of fraud losses. The optional structured recovery process uses initiateRecovery to submit supporting documents (name, URI and hash in the ERC-1643 style), and executes with executeRecovery after a time lock against disputes (for example 30 days) has passed. If evidence of fraud emerges or the original owner proves access, it is cancelled with cancelRecovery. Personal information is not stored on-chain directly, and only the document URI and hash are submitted. Separately, setAccountFrozen can freeze an account to block sending and receiving.

Interface detection and optional extensions

supportsInterface must return true for the ERC-165 ID (0x01ffc9a7) and the IERC1450 specific ID, and must return false for the ERC-20 ID (0x36372b07). The ABI is compatible with ERC-20, but because transfer always fails, the design is meant to keep wallets from wrongly assuming the behavior is compatible as well. isSecurityToken always returns true to signal a restricted token. Optional extensions include document management (setDocument and so on), a structured recovery process, KYC status lookup (isKYCVerified), gasless fee approval using EIP-2612 permit (requestTransferWithPermit), and off-chain pre-compliance checks based on EIP-3668 (CCIP-Read) (preCheckCompliance). The pre-check is for reference only and is not binding, and final authority always rests with the RTA. This standard has been finalized with Final status.

Original ERC · ← ERCs