What it does:
A smart contract that tokenizes ownership of a real-world property into digital shares, allowing fractional ownership, transparent transfers, and automated revenue distribution.
Why it matters:
Real estate is illiquid and exclusive. Tokenization lowers entry barriers, improves liquidity, and makes ownership rights transparent and programmable.
How it works:
A property is represented by a fixed supply of ownership tokens.
Each token equals a fractional claim on the property.
Tokens can be transferred between owners.
Rental or sale income is distributed proportionally to token holders.
Ownership and payouts are fully auditable on-chain.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title TokenizedPropertyOwnership
* @author Nam
* @notice Fractional property ownership with on-chain income distribution
*/
interface IERC20Minimal {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
}
contract TokenizedPropertyOwnership {
// -------------------- STATE VARIABLES --------------------
IERC20Minimal public immutable ownershipToken;
address public propertyManager;
uint256 public totalIncomeReceived;
mapping(address => uint256) public claimedIncome;
// -------------------- EVENTS --------------------
event IncomeReceived(uint256 amount);
event IncomeClaimed(address indexed holder, uint256 amount);
// -------------------- MODIFIERS --------------------
modifier onlyManager() {
require(msg.sender == propertyManager, "Not manager");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor(address _ownershipToken) {
require(_ownershipToken != address(0), "Invalid token");
ownershipToken = IERC20Minimal(_ownershipToken);
propertyManager = msg.sender;
}
// -------------------- INCOME COLLECTION --------------------
/**
* @notice Receive rental or sale income
*/
receive() external payable {
require(msg.value > 0, "No income");
totalIncomeReceived += msg.value;
emit IncomeReceived(msg.value);
}
// -------------------- INCOME DISTRIBUTION --------------------
/**
* @notice Claim proportional income
*/
function claimIncome() external {
uint256 holderBalance = ownershipToken.balanceOf(msg.sender);
require(holderBalance > 0, "Not a holder");
uint256 entitled =
(totalIncomeReceived * holderBalance) /
ownershipToken.totalSupply();
uint256 payableAmount =
entitled - claimedIncome[msg.sender];
require(payableAmount > 0, "Nothing to claim");
claimedIncome[msg.sender] += payableAmount;
payable(msg.sender).transfer(payableAmount);
emit IncomeClaimed(msg.sender, payableAmount);
}
// -------------------- ADMIN --------------------
/**
* @notice Change property manager
*/
function updateManager(address _newManager)
external
onlyManager
{
require(_newManager != address(0), "Invalid manager");
propertyManager = _newManager;
}
}
Build and Grow By Nam Le Thanh