Proposal: The SQMU Standard — An Open Protocol for Real Estate Tokenisation


Executive Summary

Real estate is the world’s largest asset class, but it remains one of the least liquid and most difficult to access. Traditional transactions are slow, costly, and fragmented across jurisdictions. Tokenisation promises to change this by making property ownership fractional, transferable, and globally accessible. Yet, without a common protocol, the industry risks splintering into isolated pilots and incompatible systems.

The SQMU Prime Standard is designed to become the global open protocol for real estate tokenisation. Built on the principle that 1 SQMU = 1 Square Metre, it provides a transparent, verifiable, and extensible way to represent real estate on-chain. SQMU extends ERC-1155 with modules for property metadata, rent distribution, compliance, and oracle integrations. A factory system makes it easy for agencies, developers, and investors to deploy tokenised property suites in a consistent and interoperable way.

SQMU is:

  • Directly linked to physical assets (each token tied to verified square metres).
  • Open yet permissionable, with optional compliance modules.
  • Composable with wallets, marketplaces, and DeFi protocols.
  • Upgradeable to evolve with new technologies.
  • Neutral and open-source, designed as a public good.

For investors, SQMU enables fractional ownership and borderless access. For property managers and agencies, it offers whitelabel deployment and seamless rent distribution in stablecoins. For developers, it opens a modular framework for compliance, oracles, and DeFi integrations.

By standardising real estate tokenisation, SQMU can do for property markets what ERC-20 did for fungible tokens: create a universal language that drives adoption, interoperability, and innovation. We invite developers, agencies, regulators, and enthusiasts to review, contribute, and shape this protocol into the global standard for property ownership on-chain.


Introduction

Real estate is the world’s largest asset class, estimated at over $300 trillion globally. Yet, despite its scale, it remains stubbornly illiquid, fragmented, and costly to transact. High friction in property transfers, lack of interoperability across jurisdictions, and barriers to fractional ownership limit access for global investors. Tokenisation offers a path to change this — unlocking liquidity, enabling fractional ownership, and creating borderless access to property markets.

But here lies the issue: without a shared protocol, real estate tokens risk becoming siloed, incompatible, and unsustainable. Early experiments in tokenised real estate have been fragmented, often focused on narrow regulatory compliance or localised pilot projects. These do not scale globally.

The SQMU Prime Standard is designed to fill this gap — providing a neutral, open, and extensible framework for real estate tokenisation. Its guiding principle is straightforward: 1 SQMU = 1 Square Metre. This direct mapping ensures clarity, transparency, and trust across all contexts.

4. SQMU Token Architecture (ERC-11RE Proposal) — Draft Spec

Audience: engineers and advanced enthusiasts. Goal: a practical, minimal, and extensible ERC-1155–based suite for tokenising real estate where 1 SQMU = 1 square metre per property, enforced by contract invariants and optional compliance/oracle modules.


4.1 Contract suite (at a glance)

  • SQMU1155 — ERC-1155 extension for property tokens and (optionally) a governance token at id=0.
  • SQMUPropertyRegistry — on-chain “golden record” for each property’s metadata, area, and supply/seal state.
  • SQMURentManager — rent/expense accrual, escrow, and pro-rata distribution to holders (push or pull).
  • SQMUComplianceRouter — pluggable pre-transfer hooks (allowlist, jurisdiction caps, freezes, zk-attestations).
  • SQMUPropertyOracle — optional oracle interface for area verification and registry sync.
  • SQMUFactory — deterministic deployment (CREATE2) of a full suite per property; whitelabel entry point.
  • Upgrade — UUPS (or equivalent) on each module; explicit version() + implementation() accessors.

4.2 Core data model

struct PropertyConfig {
  uint256 propertyId;        // ERC-1155 id (>0 for properties)
  bytes32 propertyCode;      // e.g., "DXB-MAR-APT-1204" hashed
  string  geohash;           // geo index (e.g., 6–9 precision)
  string  countryCode;       // ISO-3166-1 alpha-2
  string  registryURI;       // link to title/folio registry page
  bytes32 legalDocHash;      // hash of deed / off-chain pack
  uint256 areaSqmScaled;     // area * unitScale (see below)
  uint32  unitScale;         // e.g., 100 = 2 decimal places of sqm
  address issuer;            // controlling issuer/DAO
  bool    supplySealed;      // hard seal once supply == target
}

struct FractionSpec {
  // Supply must equal `areaSqmScaled` (invariant once sealed)
  uint256 targetSupply;      // areaSqmScaled
  uint256 mintedSoFar;
  bool    mintingPaused;
}

Invariants

  • targetSupply == areaSqmScaled for each property.
  • Once sealed: mintedSoFar == targetSupply, mintingPaused == true, and further mint/burn disabled.
  • Transfers can be conditioned by compliance router (if configured).

4.3 Interfaces (Solidity signatures)

4.3.1 ISQMU1155

interface ISQMU1155 /* is IERC1155, IERC1155MetadataURI, IERC165 */ {
  // --- Property lifecycle ---
  function registerProperty(PropertyConfig calldata cfg) external;
  function setPropertyURI(uint256 id, string calldata newURI) external;
  function sealSupply(uint256 id) external;

  // --- Mint/Burn (issuer/agent only; disabled after seal) ---
  function mintProperty(address to, uint256 id, uint256 amount, bytes calldata data) external;
  function burnProperty(address from, uint256 id, uint256 amount) external;

  // --- Views ---
  function property(uint256 id) external view returns (PropertyConfig memory);
  function fraction(uint256 id) external view returns (FractionSpec memory);
  function unitScale(uint256 id) external view returns (uint32);

  // --- Governance token (optional id=0) ---
  function mintGovernance(address to, uint256 amount) external;
  function burnGovernance(address from, uint256 amount) external;

  // --- Admin / Modules ---
  function setComplianceRouter(address router) external;
  function setRentManager(address rentManager) external;
  function setOracle(address oracle) external;

  // --- Upgrade Introspection ---
  function version() external view returns (uint64);
  function implementation() external view returns (address);
}

4.3.2 ISQMUPropertyRegistry

interface ISQMUPropertyRegistry {
  function upsert(PropertyConfig calldata cfg) external;
  function get(uint256 id) external view returns (PropertyConfig memory);
  function setLegalDocHash(uint256 id, bytes32 legalDocHash) external;
  function setRegistryURI(uint256 id, string calldata uri) external;
  function setAreaFromOracle(uint256 id, uint256 areaSqmScaled) external; // access: oracle
}

4.3.3 ISQMURentManager

struct RentEpoch {
  uint64  epochId;
  uint64  startTs;
  uint64  endTs;
  address payToken;       // e.g., USDC
  uint256 totalDeposit;   // deposited by issuer/agent
  uint256 feeBps;         // protocol fee taken on distribution
  bool    finalized;      // snapshot fixed
}

interface ISQMURentManager {
  function createEpoch(uint256 propertyId, uint64 startTs, uint64 endTs, address payToken, uint16 feeBps) external;
  function deposit(uint256 propertyId, uint64 epochId, uint256 amount) external; // issuer/agent
  function finalize(uint256 propertyId, uint64 epochId) external;                // snapshot balances

  // Distribution models:
  function claim(uint256 propertyId, uint64 epochId, address recipient) external returns (uint256 paid);
  function sweepUnclaimed(uint256 propertyId, uint64 epochId, address to) external; // after timeout

  function epoch(uint256 propertyId, uint64 epochId) external view returns (RentEpoch memory);
}

4.3.4 ISQMUComplianceRouter

interface ISQMUComplianceModule {
  // MUST NOT reenter; return (ok, reason) for debugging UIs
  function preTransfer(address operator, address from, address to, uint256 id, uint256 amount, bytes calldata data)
    external view returns (bool ok, bytes32 reason);
}

interface ISQMUComplianceRouter {
  function addModule(address module) external;
  function removeModule(address module) external;
  function listModules() external view returns (address[] memory);
}

4.3.5 ISQMUPropertyOracle

interface ISQMUPropertyOracle {
  function getAreaSqmScaled(bytes32 propertyCode) external view returns (uint256 areaSqmScaled, uint32 unitScale);
  function getRegistryURI(bytes32 propertyCode) external view returns (string memory);
  function source() external view returns (string memory); // e.g., "Dubai DLD API vX"
}

4.3.6 ISQMUFactory

struct CreateArgs {
  PropertyConfig cfg;
  string tokenURI;
  bytes extraInit; // module-specific init packed
}

interface ISQMUFactory {
  event SuiteDeployed(
    uint256 indexed propertyId,
    address sqmu1155,
    address registry,
    address rentManager,
    address complianceRouter,
    address oracle,
    bytes32  salt
  );

  function createSuite(CreateArgs calldata args, bytes32 salt) external returns (
    address sqmu1155, address registry, address rentManager, address complianceRouter, address oracle
  );

  function predictSuite(bytes32 salt) external view returns (address predictedSQMU1155 /* etc. */);
}

4.4 Events & custom errors

// Events
event PropertyRegistered(uint256 indexed id, bytes32 propertyCode, uint256 targetSupply);
event SupplySealed(uint256 indexed id);
event RentEpochCreated(uint256 indexed id, uint64 epochId, address payToken);
event RentDeposited(uint256 indexed id, uint64 epochId, uint256 amount);
event RentFinalized(uint256 indexed id, uint64 epochId, uint256 snapshotBlock);
event RentClaimed(uint256 indexed id, uint64 epochId, address indexed holder, uint256 amount);
event ComplianceModuleAdded(address module);
event ComplianceModuleRemoved(address module);
event OracleSet(address oracle);

// Errors
error NotIssuer();
error MintingPaused();
error SupplyMismatch();        // targetSupply != areaSqmScaled
error AlreadySealed();
error ComplianceRejected(bytes32 reason);
error EpochNotFinalized();
error NothingToClaim();

4.5 Access control (minimal)

  • ISSUER_ROLE — can register properties, mint pre-seal, set modules, create rent epochs.
  • ORACLE_ROLE — can push area/registry updates to PropertyRegistry.
  • FACTORY_ROLE — allows factory to call privileged inits on first deployment.
  • Use AccessControl or equivalent; emit role changes.

4.6 Transfer pipeline (with hooks)

_beforeTokenTransfer(...) in SQMU1155 invokes ComplianceRouter.preTransfer(...) across installed modules. If any returns (false, reason), revert with ComplianceRejected(reason).

Examples of modules:

  • AllowlistModule (simple address list)
  • JurisdictionCapModule (cap holders per country)
  • FreezeModule (emergency pause)
  • ZKAttestModule (validates zk-proof attestation bytes in data)

4.7 Example flows (end-to-end)

A) New property issuance

  1. Area proof: Oracle returns areaSqmScaled and unitScale for propertyCode.
  2. Factory.createSuite: deploys SQMU1155 + Registry + RentManager + ComplianceRouter (+ Oracle) with salt = keccak256(propertyCode).
  3. Register: SQMU1155.registerProperty(cfg); targetSupply = areaSqmScaled.
  4. Primary mint: issuer mints up to targetSupply to distribution wallet(s).
  5. Seal: once minted equals targetSupply, call sealSupply(id) — disables mint/burn.

B) Secondary transfer

  • User calls safeTransferFrom.
  • Router iterates modules; if all OK, transfer proceeds. Otherwise revert with ComplianceRejected.

C) Rent distribution

  1. Issuer createEpoch(propertyId, start, end, USDC, feeBps).
  2. Issuer/agent deposit(propertyId, epochId, amount).
  3. finalize snapshots balances at block.number.
  4. Holders call claim (pull) or the issuer triggers a batched push. Protocol fee retained.

D) Oracle update (optional)

  • ORACLE_ROLE.setAreaFromOracle(id, newArea). If supply not sealed, adjust targetSupply accordingly; if sealed, disallow.

4.8 Minimal JSON metadata (per property token id)

{
  "name": "SQMU • DXB Marina Apt 1204 • 1 sqm units",
  "description": "Fractional property token. 1 SQMU = 1 square metre.",
  "image": "ipfs://.../dxb-marina-1204.png",
  "external_url": "https://sqmu.net/p/DXB-MAR-APT-1204",
  "attributes": [
    {"trait_type": "Property Code", "value": "DXB-MAR-APT-1204"},
    {"trait_type": "Geohash", "value": "thrr3x..."},
    {"trait_type": "Country", "value": "AE"},
    {"trait_type": "Area (sqm)", "value": 112.75},
    {"trait_type": "Unit Scale", "value": 100},
    {"trait_type": "Registry URI", "value": "https://dld.gov.ae/folio/…"},
    {"trait_type": "Legal Pack Hash", "value": "0xabc…"}
  ]
}

4.9 Rent/Yield math (deterministic, gas-aware)

  • Snapshot: store snapshotBlock at finalize. Holder entitlement:
share = balanceOf(holder, id, snapshotBlock) / totalSupply(id)
payout = (totalDeposit * (1 - feeBps/10000)) * share
  • Claim accounting: per (propertyId, epochId, holder) record to prevent double claim.
  • Push mode: optional batch with bounded list sizes; large sets handled off-chain via merkle proofs to a claimWithProof(...).

4.10 Compliance hooks (examples)

// Allowlist
function preTransfer(...) view returns (bool, bytes32) {
  if (!allowlisted[to]) return (false, "NOT_ALLOWLISTED");
  return (true, 0x0);
}

// Jurisdiction cap
// requires country code map stored by issuer/agents

ZK flow: holder attaches data with a proof that attests “over-18, not sanctioned, resident=AE or SG” without revealing PII; module verifies proof key.


4.11 Gas & storage notes

  • Keep heavy metadata in Registry (separate from SQMU1155) to reduce hot-path costs.
  • Use uint32 unitScale and uint64 epochId to compact storage.
  • Prefer pull-based claims; push only for small cohorts.
  • CREATE2 salts based on propertyCode → stable addresses across chains.

4.12 Security considerations

  • Reentrancy guards on rent deposit/claim and factory deploys.
  • Pausable transfers via FreezeModule.
  • Sealing is irreversible; test oracle sync paths before sealing.
  • Upgrades gated by multi-sig/DAO and explicit timelock.

4.13 Interop notes

  • Works with any ERC-20 pay token for rent.
  • Bridges: represent property balances as wrapped tokens cross-chain; maintain seal invariant on home chain.
  • Indexers: expose PropertyRegistered, SupplySealed, RentFinalized, RentClaimed for analytics.

Leave a Reply

Reset password

Enter your email address and we will send you a link to change your password.

Get started with your account

to save your favourite homes and more

Sign up with email

Get started with your account

to save your favourite homes and more

Create an agent account

Manage your listings, profile and more

Phone

Buyers will use it to contact you.

Create an agent account

Manage your listings, profile and more

Sign up with email