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;
}
}