Shared Expense Settlement
What it does:
Enables groups to record, split, and settle shared expenses transparently on-chain, automating contributions, reimbursements, and balances.
Why it matters:
Eliminates disputes over who paid what, ensures fair settlement, prevents errors, and provides immutable records for all participants.
How it works:
-
Group members add expenses specifying amount, payer, and involved participants
-
Smart contract calculates owed balances automatically
-
Members can settle their shares by sending funds to the contract
-
Automatic reimbursement is triggered when contributions cover owed amounts
-
Integrates with Personal Wallets, Tokenized Payments, or Event Planning Escrow
-
Dashboards display group balances, pending payments, and history of settlements
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title SharedExpenseSettlement
* @author Nam
* @notice Tracks group expenses and automates settlement on-chain
*/
contract SharedExpenseSettlement is Ownable {
struct Expense {
string description;
uint256 amount;
address payer;
address[] participants;
bool settled;
}
mapping(uint256 => Expense) public expenses;
uint256 public expenseCount;
mapping(address => mapping(address => uint256)) public balances; // who owes whom
// -------------------- EVENTS --------------------
event ExpenseAdded(uint256 indexed expenseId, string description, uint256 amount, address payer);
event SettlementPaid(address from, address to, uint256 amount);
// -------------------- EXPENSE MANAGEMENT --------------------
function addExpense(string calldata _description, uint256 _amount, address[] calldata _participants) external {
require(_amount > 0, "Amount must be > 0");
require(_participants.length > 0, "No participants");
expenseCount += 1;
expenses[expenseCount] = Expense({
description: _description,
amount: _amount,
payer: msg.sender,
participants: _participants,
settled: false
});
uint256 share = _amount / _participants.length;
for (uint256 i = 0; i 0, "No balance owed");
require(msg.value == owed, "Incorrect payment amount");
balances[msg.sender][_to] = 0;
payable(_to).transfer(msg.value);
emit SettlementPaid(msg.sender, _to, msg.value);
}
// -------------------- VIEW FUNCTIONS --------------------
function getOwedBalance(address _from, address _to) external view returns (uint256) {
return balances[_from][_to];
}
}