This repository contains the official reference implementation of ERC-1450, a standard for compliant security tokens controlled by a Registered Transfer Agent (RTA).
This reference implementation is part of a two-repository system:
-
Specification Repository: StartEngine/ERCs
- Fork of ethereum/ERCs
- Contains the formal ERC-1450 specification
- Location:
/Users/devendergollapally/StartEngineRepositories/ERCs - Spec file:
ERCS/erc-1450.md - Our pull request PR
-
Reference Implementation (this repository): StartEngine/erc1450-reference
- Solidity smart contracts implementing the spec
- Comprehensive test suite
- Location:
/Users/devendergollapally/StartEngineRepositories/erc1450-reference - Contracts:
contracts/ERC1450.sol,contracts/RTAProxy.sol
Important: Any changes to the contracts in this repository should be validated against the formal specification in the ERCs repository to ensure compliance.
ERC-1450 enables compliant securities offerings under SEC regulations by providing:
- Exclusive RTA Control: Only the designated transfer agent can execute token operations
- Multi-Signature Security: RTAProxy pattern prevents single key compromise
- Transfer Request System: Compliant transfer workflow with fees and approvals
- Regulatory Compliance: Built for SEC Rule 17Ad requirements
- Court Order Support: Forced transfers for legal compliance
- Account Restrictions: Freeze/unfreeze capabilities
- All transfers must go through the Registered Transfer Agent
- Direct ERC-20
transfer()andapprove()functions are disabled - Minting and burning controlled by RTA only
- Token holders or authorized brokers request transfers
- Fees collected at request time
- RTA reviews and approves/rejects requests
- Full audit trail of all transfer activities
- 2-of-3 multi-signature requirement for critical operations
- Time-locks for high-value transfers
- Protection against single point of failure
- Immutable transfer agent once set to RTAProxy
- Account freezing for regulatory compliance
- Court order execution capabilities
- Broker registration and management
- Configurable fee structures
- KYC/AML verification requirements
- Extended reason codes (0-14, 999) for detailed rejection tracking
This implementation now includes upgradeable versions of the contracts using OpenZeppelin's UUPS proxy pattern, allowing critical bug fixes without requiring token holder action.
ERC1450Upgradeable.sol- Upgradeable token implementationRTAProxyUpgradeable.sol- Upgradeable multi-sig RTA
- Bug Fixes: Deploy patches without changing contract addresses
- No Migration: Token holders keep the same addresses and balances
- Secure: Upgrades require multi-sig RTA approval
- Gas Efficient: UUPS pattern minimizes overhead
# Deploy standard (immutable) contracts
npx hardhat run scripts/deploy.js --network polygon
# Deploy upgradeable contracts (recommended for production)
npx hardhat run scripts/deploy-upgradeable.js --network polygon# Upgrade contracts (requires multi-sig approval)
npx hardhat run scripts/upgrade.js --network polygonFor detailed upgradeability documentation, see UPGRADEABILITY.md.
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Token Holder │────▶│ ERC1450 │◀────│ RTAProxy │
└─────────────────┘ └──────────────┘ └─────────────────┘
▲ ▲
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ Brokers │ │ RTA Signers │
└─────────────┘ └─────────────┘
- Node.js v16+ (tested with v22.14.0)
- npm v7+ (tested with v10.9.2)
# Clone the repository
git clone https://github.com/StartEngine/erc1450-reference.git
cd erc1450-reference
# Install dependencies (also installs git hooks via Husky)
npm install
# Compile contracts
npx hardhat compile
# Run tests
npm test
# Check test coverage
npx hardhat coverage
# Run security analysis (requires Python + Slither)
slither . --print human-summaryNote: The npm install command automatically sets up git hooks via Husky. These hooks will run hardhat compile and npm test before each commit to ensure code quality.
For contributors and developers working on this project:
-
Clone & Setup
git clone https://github.com/StartEngine/erc1450-reference.git cd erc1450-reference npm install # Auto-installs Husky pre-commit hooks
-
Compile Contracts
npx hardhat compile
-
Run Tests
npm test # Runs all 341 tests
-
Check Coverage
npx hardhat coverage # Current: 86.2% branch coverage -
Security Analysis (optional, requires Slither)
pip install slither-analyzer slither . -
Pre-Commit Hooks (automatic)
- Husky automatically runs before each commit:
- ✅ Compiles all Solidity contracts
- ✅ Runs full test suite (341 tests)
- To bypass (not recommended):
git commit --no-verify
- Husky automatically runs before each commit:
# Start local Hardhat node
npx hardhat node
# Deploy contracts (in new terminal)
npx hardhat run scripts/deploy.js --network localhost# Set up environment variables
export PRIVATE_KEY="your_private_key"
export RPC_URL="your_rpc_url"
# Deploy
npx hardhat run scripts/deploy.js --network sepoliaRun these scripts to see the ERC-1450 system in action:
# Display token information and run basic demo
npx hardhat run scripts/info.js
# Demo minting tokens through multi-sig
npx hardhat run scripts/demo-mint.js
# Demo complete transfer request workflow
npx hardhat run scripts/demo-transfer.jsFor production deployments, use the deployment and operations scripts:
# Deploy contracts
npx hardhat run scripts/deploy.js --network localhost
# After deployment, manage operations using the deployment file
# (Requires deployment-{network}.json file from deploy.js)// Request a transfer
await token.requestTransferWithFee(
fromAddress,
toAddress,
amount,
ethers.ZeroAddress, // ETH for fee
feeAmount,
{ value: feeAmount }
);
// Check transfer request status
const request = await token.transferRequests(requestId);
console.log("Status:", request.status);// Submit operation (first signer)
const operationId = await rtaProxy.submitOperation(
targetContract,
encodedFunctionData,
ethValue
);
// Confirm operation (second signer)
await rtaProxy.confirmOperation(operationId);
// Auto-executes when threshold reached
// Check operation status
const op = await rtaProxy.getOperation(operationId);
console.log("Executed:", op.executed);The main security token interface extending ERC-20:
interface IERC1450 is IERC20, IERC165 {
// RTA Functions
function changeIssuer(address newIssuer) external;
function setTransferAgent(address newTransferAgent) external;
function mint(address to, uint256 amount) external returns (bool);
function burnFrom(address from, uint256 amount) external returns (bool);
// Transfer Request System
function requestTransferWithFee(
address from,
address to,
uint256 amount,
address feeToken,
uint256 feeAmount
) external payable returns (uint256 requestId);
function processTransferRequest(uint256 requestId) external;
function rejectTransferRequest(uint256 requestId, uint16 reasonCode, bool refundFee) external;
// Compliance
function setAccountFrozen(address account, bool frozen) external;
function executeCourtOrder(address from, address to, uint256 amount, bytes32 documentHash) external;
}Multi-signature contract for RTA operations:
contract RTAProxy {
function submitOperation(address target, bytes memory data, uint256 value) external returns (uint256);
function confirmOperation(uint256 operationId) external;
function revokeConfirmation(uint256 operationId) external;
function executeOperation(uint256 operationId) external;
}The test suite covers all major functionality:
# Run all tests
npx hardhat test
# Run specific test file
npx hardhat test test/ERC1450.test.js
# Run with coverage
npx hardhat coverage
# Run with gas reporting
REPORT_GAS=true npx hardhat testTest coverage includes:
- ✅ Token deployment and initialization
- ✅ RTA-exclusive operations (mint, burn, transfer)
- ✅ Transfer request lifecycle
- ✅ Fee management
- ✅ Broker registration
- ✅ Account freezing
- ✅ Court order execution
- ✅ Multi-sig operations
- ✅ Interface detection (ERC-165)
The ERC-1450 specification includes comprehensive documentation for real-world securities operations:
- Stock Splits & Reverse Splits: Proportional mint/burn operations
- Dividends: Stablecoin distributions with off-chain calculations
- Mandatory Redemptions: Forced buybacks and bond calls
- Tender Offers: Voluntary redemption patterns
- Mergers & Acquisitions: Token swap mechanisms
- Record Dates: Off-chain snapshots or external snapshot contracts
- Proxy Voting: Vote recording with on-chain attestation
- Meeting Quorums: Threshold calculations and verification
- Document Management: Via ERC-1643 for proxy rules and notices
- W-9/W-8 Collection: Off-chain during KYC process
- Withholding Calculations: Per-jurisdiction off-chain processing
- 1099/1042-S Reporting: Annual tax form generation
- Document References: Encrypted storage via ERC-1643
- ATS Adapter Pattern: Integration with regulated trading venues
- Order Book Visibility: Via TransferRequested events
- Pre-Matched Trades: Through registered broker submissions
- Reason Code Analytics: Optimization using rejection reasons
- Similar to RTAProxy but optional for brokers
- Enables secure key rotation and multi-sig controls
- Provides business continuity for broker operations
- Private Key Management: RTA signers must secure their private keys
- Multi-Sig Threshold: Choose appropriate signature requirements
- Transfer Agent Lock: Once set to RTAProxy, cannot be changed
- Fee Collection: Ensure proper fee token validation
- Reentrancy Protection: All state-changing functions protected
- Access Control: Strict RTA-only modifier on critical functions
- Uses custom errors (ERC-6093) for gas efficiency
- Unchecked blocks where overflow impossible
- Efficient storage packing
- Minimal external calls
This implementation is designed to comply with:
- SEC Rule 17Ad (Transfer Agent regulations)
- Regulation S-T (Electronic filing requirements)
- Regulation A+ (Qualified offerings)
- Regulation D (Private placements)
- Regulation CF (Crowdfunding)
The implementation includes standardized reason codes for transfer rejections:
| Code | Constant | Description |
|---|---|---|
| 0 | REASON_INSUFFICIENT_BALANCE | Sender has fewer tokens than transfer amount |
| 1 | REASON_INVALID_SENDER | Sender address is invalid or blacklisted |
| 2 | REASON_INVALID_RECEIVER | Receiver address is invalid or zero |
| 3 | REASON_COMPLIANCE_FAILURE | Generic compliance check failure |
| 4 | REASON_TRANSFER_RESTRICTED | Transfer temporarily restricted |
| 5 | REASON_HOLDER_LIMIT_EXCEEDED | Would exceed maximum holder count |
| 6 | REASON_TRADING_HALT | Trading is currently halted |
| 7 | REASON_COURT_ORDER | Transfer blocked by court order |
| 8 | REASON_REGULATORY_FREEZE | Account frozen by regulator |
| 9 | REASON_LOCK_PERIOD | Tokens are in lock-up period |
| 10 | REASON_RECIPIENT_NOT_VERIFIED | Recipient hasn't completed KYC/AML |
| 11 | REASON_ADDRESS_NOT_LINKED | Address not linked to verified identity |
| 12 | REASON_SENDER_VERIFICATION_EXPIRED | Sender's KYC has expired |
| 13 | REASON_JURISDICTION_BLOCKED | Recipient in restricted jurisdiction |
| 14 | REASON_ACCREDITATION_REQUIRED | Recipient not accredited (Reg D) |
| 999 | REASON_OTHER | Other unspecified reason |
This is a reference implementation maintained by StartEngine. For questions or issues, please open a GitHub issue.
MIT License
For questions and support:
- Open an issue in this repository
- Join the discussion on Ethereum Magicians
- Contact the StartEngine team
This repository can be used as an npm package via git dependencies for JavaScript/TypeScript projects. The package provides both basic (immutable) and upgradeable contract implementations.
Add to your package.json:
{
"dependencies": {
"erc1450-reference": "git+https://github.com/StartEngine/erc1450-reference.git#v1.4.0"
}
}Or install directly:
npm install git+https://github.com/StartEngine/erc1450-reference.git#v1.4.0Import contract artifacts in your JavaScript/TypeScript project:
// Method 1: Import via main index.js (recommended)
const { ERC1450, RTAProxy, ERC1450Upgradeable, RTAProxyUpgradeable, ERC1967Proxy } = require('erc1450-reference');
// Method 2: Import specific artifacts directly
const RTAProxyUpgradeable = require('erc1450-reference/artifacts/contracts/upgradeable/RTAProxyUpgradeable.sol/RTAProxyUpgradeable.json');
const ERC1450Upgradeable = require('erc1450-reference/artifacts/contracts/upgradeable/ERC1450Upgradeable.sol/ERC1450Upgradeable.json');
// Use with ethers.js or web3.js
const abi = RTAProxyUpgradeable.abi;
const bytecode = RTAProxyUpgradeable.bytecode;
// Example: Deploy with ethers.js
const factory = new ethers.ContractFactory(abi, bytecode, signer);
const contract = await factory.deploy(...args);This package includes both basic and upgradeable versions:
Basic Contracts (Immutable)
ERC1450- Standard ERC1450 token implementationRTAProxy- Multi-sig RTA proxy
Upgradeable Contracts (UUPS Pattern)
ERC1450Upgradeable- Upgradeable ERC1450 tokenRTAProxyUpgradeable- Upgradeable multi-sig RTAERC1967Proxy- OpenZeppelin proxy for deployment
Interfaces & Libraries
IERC1450- ERC1450 interfaceERC1450Constants- Shared constants library
When updating contracts:
- Make contract changes and compile:
npm run compile - Update version in
package.json(follow semantic versioning) - Commit changes:
git commit -am "Release v1.4.0" - Create git tag:
git tag v1.4.0 - Push to GitHub:
git push origin main git push origin v1.4.0
- Update dependent projects to use the new version tag in their
package.json
Note: No build scripts needed - git tags are the release mechanism.
- Slither Analysis: Completed (November 2024) - No critical vulnerabilities found
- Static Analysis: All high-priority issues resolved in commit 9805925
- Test Coverage: 63 comprehensive tests passing
- Security Score: 9.5/10 based on automated analysis
This implementation has undergone initial security analysis but has NOT received a professional third-party audit. Production deployment should only proceed after:
- Formal security audit by a reputable firm (OpenZeppelin, Trail of Bits, ConsenSys, etc.)
- Thorough legal review for your jurisdiction
- Comprehensive integration testing
Built with ❤️ by StartEngine for the Ethereum community