Home-Sharing Revenue Split

What it does:
Automatically splits rental income from home-sharing platforms among multiple stakeholders (owners, co-hosts, cleaners, investors) based on predefined percentages.

Why it matters:
Eliminates manual accounting, prevents disputes, and ensures every party is paid fairly and instantly when revenue arrives.

How it works:

  • Stakeholders and their revenue percentages are defined upfront.

  • Rental income is deposited into the contract.

  • Funds are split and claimable proportionally.

  • All payouts and balances are transparent on-chain.

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * @title HomeSharingRevenueSplit
 * @author Nam
 * @notice Automatically splits home-sharing rental income among stakeholders
 */
contract HomeSharingRevenueSplit {

    // -------------------- DATA STRUCTURES --------------------

    struct Stakeholder {
        address account;
        uint256 share; // percentage in basis points (10000 = 100%)
        uint256 released;
    }

    Stakeholder[] public stakeholders;
    uint256 public totalShares;
    uint256 public totalReleased;
    address public owner;

    // -------------------- EVENTS --------------------

    event RevenueReceived(uint256 amount);
    event PaymentReleased(address indexed to, uint256 amount);

    // -------------------- MODIFIERS --------------------

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------------------- CONSTRUCTOR --------------------

    constructor(
        address[] memory _accounts,
        uint256[] memory _shares
    ) {
        require(_accounts.length == _shares.length, "Length mismatch");
        require(_accounts.length > 0, "No stakeholders");

        owner = msg.sender;

        uint256 total;
        for (uint256 i = 0; i  0, "Zero share");

            stakeholders.push(
                Stakeholder({
                    account: _accounts[i],
                    share: _shares[i],
                    released: 0
                })
            );
            total += _shares[i];
        }

        require(total == 10000, "Shares must equal 100%");
        totalShares = total;
    }

    // -------------------- RECEIVE REVENUE --------------------

    receive() external payable {
        emit RevenueReceived(msg.value);
    }

    // -------------------- PAYOUT LOGIC --------------------

    /**
     * @notice Release funds to stakeholder
     */
    function release(uint256 index) external {
        Stakeholder storage s = stakeholders[index];

        uint256 totalReceived = address(this).balance + totalReleased;
        uint256 payment = (totalReceived * s.share) / totalShares - s.released;

        require(payment > 0, "Nothing to release");

        s.released += payment;
        totalReleased += payment;

        payable(s.account).transfer(payment);
        emit PaymentReleased(s.account, payment);
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function stakeholderCount() external view returns (uint256) {
        return stakeholders.length;
    }
}