Multi-Signature Family Treasury

What it does:
A multi-signature smart contract wallet designed for families, where multiple trusted members must approve transactions before funds can be spent.

Why it matters:
Family funds often require shared decision-making and protection against mistakes or abuse. This contract enforces collective approval, transparency, and safety without relying on banks.

How it works:

  • Family members are registered as signers.

  • A minimum number of approvals is required for any transfer.

  • Transactions are proposed, reviewed, and approved on-chain.

  • Funds are released only after enough confirmations.

  • All actions are fully transparent and auditable.

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

/**
 * @title MultiSignatureFamilyTreasury
 * @author Nam
 * @notice Multi-signature wallet for family treasury management
 */
contract MultiSignatureFamilyTreasury {

    // -------------------- STATE VARIABLES --------------------

    address[] public signers;
    mapping(address => bool) public isSigner;
    uint256 public requiredApprovals;

    struct Transaction {
        address to;
        uint256 value;
        bool executed;
        uint256 approvals;
    }

    Transaction[] public transactions;

    mapping(uint256 => mapping(address => bool)) public approvedBy;

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

    event Deposit(address indexed sender, uint256 amount);
    event TransactionProposed(
        uint256 indexed txId,
        address indexed to,
        uint256 value
    );
    event TransactionApproved(
        uint256 indexed txId,
        address indexed signer
    );
    event TransactionExecuted(uint256 indexed txId);

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

    modifier onlySigner() {
        require(isSigner[msg.sender], "Not signer");
        _;
    }

    modifier txExists(uint256 _txId) {
        require(_txId  1, "At least 2 signers");
        require(
            _requiredApprovals > 0 &&
            _requiredApprovals <= _signers.length,
            "Invalid approval count"
        );

        for (uint256 i = 0; i < _signers.length; i++) {
            address signer = _signers[i];
            require(signer != address(0), "Invalid signer");
            require(!isSigner[signer], "Duplicate signer");

            isSigner[signer] = true;
            signers.push(signer);
        }

        requiredApprovals = _requiredApprovals;
    }

    // -------------------- RECEIVE FUNDS --------------------

    receive() external payable {
        emit Deposit(msg.sender, msg.value);
    }

    // -------------------- TRANSACTION FLOW --------------------

    /**
     * @notice Propose a transaction
     */
    function proposeTransaction(
        address _to,
        uint256 _value
    ) external onlySigner {
        require(_to != address(0), "Invalid recipient");
        require(_value = requiredApprovals,
            "Not enough approvals"
        );

        txn.executed = true;
        payable(txn.to).transfer(txn.value);

        emit TransactionExecuted(_txId);
    }

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

    function signerCount() external view returns (uint256) {
        return signers.length;
    }

    function transactionCount() external view returns (uint256) {
        return transactions.length;
    }
}