Static Background LinesBackground AnimationStatic Background Lines LeftBackground Animation Left
module digital_asset::composable_rwa {
    use std::signer;
    use std::string::String;
    use digital_asset::object::{Self, Object};
    use digital_asset::primary_fungible_store;
    use digital_asset::fungible_asset::{Self, MintRef, TransferRef, BurnRef};

    struct AssetMetadata has key {
        asset_name: String,
        asset_class: String,
        issuer: address,
        total_units: u64,
        unit_value: u64,
        custody_ref: CustodyRef,
        transfer_ref: TransferRef,
        redemption_ref: RedemptionRef,
    }

    struct ComposableDigitalAsset has key, store {
        custodian: address,
        underlying_asset: Option<Object<ComposableDigitalAsset>>,
        linked_assets: vector<Object<ComposableDigitalAsset>>,
        metadata: Object<AssetMetadata>,
        compliance_status: bool,
    }

    const E_NOT_AUTHORIZED: u64 = 1;
    const E_INSUFFICIENT_HOLDINGS: u64 = 2;
    const E_ASSET_LOCKED: u64 = 3;
    const E_COMPLIANCE_FAILED: u64 = 4;

    public entry fun register_asset(
        issuer: &signer,
        asset_name: String,
        asset_class: String,
        total_units: u64,
        unit_value: u64,
        prospectus_uri: String,
    ) {
        let issuer_addr = signer::address_of(issuer);
        let constructor_ref = &object::create_named_object(issuer, *string::bytes(&asset_name));

        primary_fungible_store::create_primary_store_enabled_fungible_asset(
            constructor_ref,
            option::some(total_units),
            asset_name,
            asset_class,
            8,
            prospectus_uri,
        );

        let custody_ref = fungible_asset::generate_mint_ref(constructor_ref);
        let redemption_ref = fungible_asset::generate_burn_ref(constructor_ref);
        let transfer_ref = fungible_asset::generate_transfer_ref(constructor_ref);

        move_to(&object::generate_signer(constructor_ref), AssetMetadata {
            asset_name,
            asset_class,
            issuer: issuer_addr,
            total_units,
            unit_value,
            custody_ref,
            transfer_ref,
            redemption_ref,
        });
    }

    public entry fun issue(custodian: &signer, investor: address, units: u64) acquires AssetMetadata {
        let custodian_addr = signer::address_of(custodian);
        let metadata = borrow_global_mut<AssetMetadata>(custodian_addr);
        let digital_asset = fungible_asset::mint(&metadata.custody_ref, units);
        primary_fungible_store::deposit(investor, digital_asset);
        metadata.total_units = metadata.total_units + units;
    }

    public entry fun transfer_ownership(holder: &signer, recipient: address, units: u64) {
        let holder_addr = signer::address_of(holder);
        primary_fungible_store::transfer(holder, metadata_object(), recipient, units);
    }

    public entry fun redeem(holder: &signer, units: u64) acquires AssetMetadata {
        let holder_addr = signer::address_of(holder);
        let metadata = borrow_global_mut<AssetMetadata>(@digital_asset);
        let asset = primary_fungible_store::withdraw(holder, metadata_object(), units);
        fungible_asset::burn(&metadata.redemption_ref, asset);
        metadata.total_units = metadata.total_units - units;
    }

    public fun compose_assets(custodian: &signer, linked: Object<ComposableDigitalAsset>) acquires ComposableDigitalAsset {
        let custodian_addr = signer::address_of(custodian);
        let linked_asset = borrow_global_mut<ComposableDigitalAsset>(object::object_address(&linked));
        assert!(linked_asset.custodian == custodian_addr, E_NOT_AUTHORIZED);
        linked_asset.underlying_asset = option::some(parent_asset);
    }

    public fun separate_assets(custodian: &signer, linked: Object<ComposableDigitalAsset>) acquires ComposableDigitalAsset {
        let custodian_addr = signer::address_of(custodian);
        let linked_asset = borrow_global_mut<ComposableDigitalAsset>(object::object_address(&linked));
        linked_asset.underlying_asset = option::none();
    }

    #[view]
    public fun holdings(investor: address): u64 {
        primary_fungible_store::balance(investor, metadata_object())
    }

    #[view]
    public fun total_issuance(): u64 acquires AssetMetadata {
        borrow_global<AssetMetadata>(@digital_asset).total_units
    }
}
Bits & Blocks

Advancing Digital Asset Infrastructure

Developing foundational protocols and technical standards for institutional-grade tokenized economies.

Partner with us

We Are

A Qatar-based research lab advancing foundational protocols and technical standards for compliant digital asset infrastructure.

Research & Development

Our work spans protocol architecture, compliance frameworks, and institutional-grade systems. We enable scalable tokenization of real-world assets.

Footer Animation

Let's get in touch

info@bitsandblocks.tech
LinkedIn

Copyright © 2026 Bits and Blocks LLC.
All rights reserved

Licensed by QFCQatar flag