Asset Tokenization Platform Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Asset Tokenization Platform Development
Complex
from 2 weeks to 3 months
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1238
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1167
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    867
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1080
  • image_logo-advance_0.png
    B2B Advance company logo design
    563
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    829

Asset Tokenization Platform Development

Asset tokenization is the representation of ownership rights or a share in a real asset as a token on the blockchain. Sounds conceptual, but there's a concrete set of legal and technical problems to solve sequentially. Technology is the smaller part of the task. Legal framework, compliance, KYC/AML, secondary trading within regulatory constraints—these are 60-70% of the work on any serious tokenization project.

Asset types vary and require different approaches: real estate, SPV equity, debt instruments, artworks, intellectual property, commodity reserves. But the basic platform components are shared.

Token Standards for RWA

Standard ERC-20 doesn't fit regulated assets. You need:

ERC-1400 (Security Token Standard) — an extension of ERC-20 with transfer restrictions, forced transfers, and document management. Developed under securities regulator requirements. Supports partitions (tranches with different rights):

// ERC-1400 key interfaces
interface IERC1400 is IERC20 {
    // Check if transfer can be executed (returns status code + reason)
    function canTransferByPartition(
        bytes32 partition,
        address from,
        address to,
        uint256 value,
        bytes calldata data
    ) external view returns (byte, bytes32, bytes32);
    
    // Transfer with data (for compliance metadata)
    function transferByPartition(
        bytes32 partition,
        address to,
        uint256 value,
        bytes calldata data
    ) external returns (bytes32);
    
    // Forced transfer (for regulator or court order)
    function operatorTransferByPartition(
        bytes32 partition,
        address from,
        address to,
        uint256 value,
        bytes calldata data,
        bytes calldata operatorData
    ) external returns (bytes32);
    
    // Documents attached to token (prospectus, audit, legal)
    function getDocument(bytes32 name) 
        external view returns (string memory, bytes32);
}

ERC-3643 (T-REX: Token for Regulated EXchanges) — a more modern standard developed by Tokeny Solutions and adopted as the foundation by many platforms (Société Générale Forge, ABN AMRO). Includes identity layer (ONCHAINID) and automated compliance checks:

// T-REX compliance check example
contract TokenCompliance {
    IIdentityRegistry public identityRegistry;
    ICompliance public compliance;
    
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal {
        if (from != address(0) && to != address(0)) {
            // Check recipient identity
            require(
                identityRegistry.isVerified(to),
                "Recipient identity not verified"
            );
            
            // Check compliance rules
            require(
                compliance.canTransfer(from, to, amount),
                "Transfer not compliant"
            );
        }
    }
}

ERC-1155 for fractional assets — when one asset is divided into multiple types of rights (e.g., a building with different types of spaces, or artwork with different usage rights).

Identity Layer: KYC/AML On-Chain

Every token holder of a regulated asset must be verified. On-chain identity is more complex than just address → bool mapping.

ONCHAINID (ERC-734/735)

Standard for decentralized identity, compatible with T-REX:

// Identity contract (one per user)
interface IIdentity {
    // Claims — verified claims from claim issuers
    function getClaim(bytes32 claimId) 
        external view returns (
            uint256 topic,     // claim type: KYC, AML, accredited investor
            uint256 scheme,    // verification method
            address issuer,
            bytes memory signature,
            bytes memory data,
            string memory uri
        );
    
    function addClaim(
        uint256 topic,
        uint256 scheme,
        address issuer,
        bytes memory signature,
        bytes memory data,
        string memory uri
    ) external returns (bytes32 claimId);
}

// Claim Topics for securities
uint256 constant KYC_CLAIM = 1;
uint256 constant AML_CLAIM = 2;
uint256 constant ACCREDITED_INVESTOR_CLAIM = 3;
uint256 constant COUNTRY_CLAIM = 4;
uint256 constant PROFESSIONAL_INVESTOR_CLAIM = 5;

KYC provider (Sumsub, Fractal, Identix) conducts verification and issues a claim with signature. The claim is recorded in the user's ONCHAINID contract. When attempting to transfer a token, the compliance module checks for required claims.

Jurisdiction Restrictions

Regulators require limiting sales in certain jurisdictions (e.g., cannot sell to US residents without SEC registration):

contract CountryRestrictionsCompliance {
    // Allowed country codes (ISO 3166-1 numeric)
    mapping(uint16 => bool) public allowedCountries;
    
    // Ownership limits per country
    mapping(uint16 => uint256) public countryMaxInvestors;
    mapping(uint16 => uint256) public countryCurrentInvestors;
    
    function canTransfer(
        address from,
        address to,
        uint256 amount
    ) external view returns (bool) {
        uint16 recipientCountry = getInvestorCountry(to);
        
        if (!allowedCountries[recipientCountry]) {
            return false;
        }
        
        // Don't exceed investor limit per country
        if (isNewInvestor(to, recipientCountry)) {
            if (countryCurrentInvestors[recipientCountry] >= 
                countryMaxInvestors[recipientCountry]) {
                return false;
            }
        }
        
        return true;
    }
}

Lifecycle of Tokenized Asset

Issuance

Before minting tokens:

  1. Legal structure: SPV, trust, or other structure holding the real asset
  2. Legal opinion that tokens are not unregistered securities (or registration)
  3. Prospectus/offering memorandum (depends on jurisdiction and volume)
  4. Custody arrangement: who holds documents, who is transfer agent
function mintSecurityTokens(
    address investor,
    uint256 amount,
    bytes32 partition,       // e.g.: "CLASS_A_SHARES"
    bytes calldata data      // reference to legal document hash
) external onlyRole(ISSUER_ROLE) {
    require(identityRegistry.isVerified(investor), "Not verified");
    require(compliance.canTransfer(address(0), investor, amount), "Not compliant");
    
    _issueByPartition(partition, investor, amount, data);
    emit TokensIssued(investor, amount, partition, data);
}

Corporate Actions

Tokenized equity requires handling corporate events:

Dividends:

contract DividendDistributor {
    IERC1400 public securityToken;
    IERC20 public paymentToken;  // Usually USDC
    
    function distributeDividends(
        uint256 totalDividend,
        uint256 snapshotId
    ) external onlyRole(CORPORATE_ACTIONS_ROLE) {
        uint256 totalSupplyAtSnapshot = securityToken.totalSupplyAt(snapshotId);
        
        // Each holder gets proportionally
        // Use snapshot for accurate calculation (ERC20Snapshot or ERC20Votes)
        uint256 dividendPerToken = totalDividend * 1e18 / totalSupplyAtSnapshot;
        
        // Save snapshot dividend for claiming
        dividendSnapshots[snapshotId] = DividendSnapshot({
            totalDividend: totalDividend,
            dividendPerToken: dividendPerToken,
            paymentToken: address(paymentToken),
            snapshotBlock: block.number
        });
    }
    
    function claimDividend(uint256 snapshotId) external {
        uint256 balance = securityToken.balanceOfAt(msg.sender, snapshotId);
        require(balance > 0, "No balance at snapshot");
        require(!claimed[msg.sender][snapshotId], "Already claimed");
        
        claimed[msg.sender][snapshotId] = true;
        
        uint256 amount = balance * dividendSnapshots[snapshotId].dividendPerToken / 1e18;
        paymentToken.safeTransfer(msg.sender, amount);
    }
}

Splits and reverse splits:

function executeSplit(uint256 splitRatio) external onlyRole(CORPORATE_ACTIONS_ROLE) {
    // splitRatio = 200 means 2:1 split (each token → 2 tokens)
    // splitRatio = 50 means 1:2 reverse split
    
    address[] memory holders = getAllHolders();  // maintained separately via events
    for (uint i = 0; i < holders.length; i++) {
        uint256 currentBalance = balanceOf(holders[i]);
        if (splitRatio > 100) {
            // Forward split: mint additional tokens
            _mint(holders[i], currentBalance * (splitRatio - 100) / 100);
        } else {
            // Reverse split: burn
            _burn(holders[i], currentBalance * (100 - splitRatio) / 100);
        }
    }
    emit SplitExecuted(splitRatio, block.timestamp);
}

Secondary Market and Liquidity

Secondary trading of tokenized assets is a separate problem. Unlike regular ERC-20, you can't just list on Uniswap: each buyer must pass KYC and the purchase must pass compliance check.

Permissioned DEX — custom AMM or order book with built-in compliance gate:

contract ComplianceAwareOrderBook {
    ICompliance public compliance;
    
    struct Order {
        address seller;
        uint256 amount;
        uint256 pricePerToken;  // in USDC wei
        bool isActive;
    }
    
    mapping(uint256 => Order) public orders;
    
    function fillOrder(uint256 orderId, uint256 amount) external nonReentrant {
        Order storage order = orders[orderId];
        require(order.isActive, "Order not active");
        
        // Compliance check BEFORE any transfers
        require(
            compliance.canTransfer(order.seller, msg.sender, amount),
            "Transfer not compliant"
        );
        
        uint256 cost = amount * order.pricePerToken / 1e18;
        
        // Atomic swap
        paymentToken.safeTransferFrom(msg.sender, order.seller, cost);
        securityToken.operatorTransferByPartition(
            "DEFAULT",
            order.seller,
            msg.sender,
            amount,
            "",
            ""
        );
        
        emit OrderFilled(orderId, msg.sender, amount, cost);
    }
}

Integration with regulated platforms — INX, tZERO, STO Global X accept T-REX standard tokens. This is ready-made liquidity for issuers without building their own trading platform.

Oracles and Asset Valuation

For collateralized lending of tokenized assets you need on-chain price. Unlike crypto assets—there's no liquid market. Solutions:

Verified appraiser model — accredited appraiser signs valuation and publishes on-chain. Contract accepts valuations from N accredited appraisers, takes median:

contract AssetValuationOracle {
    struct Valuation {
        uint256 value;       // in USD, 8 decimals
        uint256 timestamp;
        address appraiser;
        bytes signature;
    }
    
    mapping(bytes32 => Valuation[]) public valuations;  // assetId → valuations
    uint256 public constant MAX_VALUATION_AGE = 90 days;
    uint256 public constant MIN_APPRAISERS = 2;
    
    function getAssetValue(bytes32 assetId) external view returns (uint256) {
        Valuation[] storage vals = valuations[assetId];
        
        // Filter fresh valuations
        uint256[] memory freshValues = new uint256[](vals.length);
        uint256 freshCount = 0;
        
        for (uint i = 0; i < vals.length; i++) {
            if (block.timestamp - vals[i].timestamp <= MAX_VALUATION_AGE) {
                freshValues[freshCount++] = vals[i].value;
            }
        }
        
        require(freshCount >= MIN_APPRAISERS, "Insufficient fresh valuations");
        
        return median(freshValues, freshCount);
    }
}

Technology Stack

Component Choice Rationale
Token standard ERC-3643 (T-REX) Wide adoption in RWA, compliance built-in
Identity ONCHAINID T-REX ecosystem standard
KYC provider Sumsub / Synaps API + claim issuance
Settlement chain Polygon PoS / Base Cheap, EVM, active RWA ecosystem
Payment USDC / EURC Circle stability, regulatory clarity
Document storage IPFS + Filecoin Long-term storage for legal documents

Project Phases

Phase Content Timeline
Legal & structure Legal structure, compliance requirements 4–8 weeks
Core contracts ERC-3643 + identity + compliance modules 4–6 weeks
Corporate actions Dividends, splits, forced transfer 2–3 weeks
KYC integration Identity registry + KYC provider API 2–3 weeks
Secondary market Order book or DEX with compliance 3–4 weeks
Investor portal Dashboard, claims, documents 3–4 weeks
Audit Contracts 3–4 weeks
Issuance pilot Real asset in test environment 2–3 weeks

Total: 23–35 weeks. Legal phase is the variable with the largest spread: depends on asset type, jurisdiction, and availability of experienced securities lawyer in client's team.