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 atid=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 == areaSqmScaledfor 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 toPropertyRegistry.FACTORY_ROLE— allows factory to call privileged inits on first deployment.- Use
AccessControlor 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 indata)
4.7 Example flows (end-to-end)
A) New property issuance
- Area proof: Oracle returns
areaSqmScaledandunitScaleforpropertyCode. - Factory.createSuite: deploys
SQMU1155 + Registry + RentManager + ComplianceRouter (+ Oracle)withsalt = keccak256(propertyCode). - Register:
SQMU1155.registerProperty(cfg);targetSupply = areaSqmScaled. - Primary mint: issuer mints up to
targetSupplyto distribution wallet(s). - Seal: once minted equals
targetSupply, callsealSupply(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
- Issuer
createEpoch(propertyId, start, end, USDC, feeBps). - Issuer/agent
deposit(propertyId, epochId, amount). finalizesnapshots balances atblock.number.- 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, adjusttargetSupplyaccordingly; 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
snapshotBlockatfinalize. 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 fromSQMU1155) to reduce hot-path costs. - Use
uint32 unitScaleanduint64 epochIdto 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,RentClaimedfor analytics.

Leave a Reply