Revenue Splitter: Automated Revenue Distribution
1.1 Revenue Splitter Overview
1.2 Key Smart Contract Features for Revenue Splitting
Roles and Percentages: Define roles (e.g., “Creator,” “Developer,” “Marketer”) and their associated percentages of total revenue.
Automatic Splitting: Funds are automatically divided according to roles when received.
Withdrawals: Each collaborator can withdraw their allocated portion based on the defined role percentages.
Event Logging: Transactions are logged for auditing purposes.
1.3 Smart Contract
Below is a sample Solidity contract that implements role-based revenue splitting. This contract defines each collaborator’s role, their revenue percentage, and allows them to withdraw their allocated revenue.
RevenueSplitter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract RevenueSplitter {
struct Recipient {
uint256 share; // Share percentage (e.g., 30 means 30%)
uint256 balance; // Balance available for withdrawal
}
mapping(address => Recipient) public recipients;
address[] public recipientAddresses;
uint256 public totalShares;
event RevenueReceived(uint256 amount);
event Withdrawn(address indexed recipient, uint256 amount);
modifier onlyRecipient() {
require(recipients[msg.sender].share > 0, "Not an authorized recipient");
_;
}
constructor(address[] memory _recipients, uint256[] memory _shares) {
require(_recipients.length == _shares.length, "Recipients and shares length mismatch");
for (uint256 i = 0; i < _recipients.length; i++) {
recipients[_recipients[i]] = Recipient({
share: _shares[i],
balance: 0
});
recipientAddresses.push(_recipients[i]);
totalShares += _shares[i];
}
}
// Receive funds and distribute based on shares
receive() external payable {
require(msg.value > 0, "No funds sent");
uint256 totalAmount = msg.value;
emit RevenueReceived(totalAmount);
for (uint256 i = 0; i < recipientAddresses.length; i++) {
address recipientAddr = recipientAddresses[i];
uint256 recipientShare = (totalAmount * recipients[recipientAddr].share) / totalShares;
recipients[recipientAddr].balance += recipientShare;
}
}
// Withdraw funds allocated to the caller
function withdraw() external onlyRecipient {
uint256 amount = recipients[msg.sender].balance;
require(amount > 0, "No balance available for withdrawal");
recipients[msg.sender].balance = 0;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
emit Withdrawn(msg.sender, amount);
}
// Get recipient share percentage
function getShare(address _recipient) public view returns (uint256) {
return recipients[_recipient].share;
}
// Get recipient balance available for withdrawal
function getBalance(address _recipient) public view returns (uint256) {
return recipients[_recipient].balance;
}
}1.4 Usage and Deployment
Initializing the Contract
To deploy this contract, initialize with:
A list of recipient addresses.
A list of corresponding shares for each recipient.
Receiving and Distributing Revenue
When funds are sent to the contract address, they are distributed automatically to each recipient’s balance based on their share.
Withdrawing Funds
Each recipient can call the withdraw() function to claim their balance.
Viewing Allocation
Each recipient’s share and balance can be viewed with getShare() and getBalance() functions, respectively.
1.5 Best Practices and Security Considerations
Accurate Role Definition: Ensure roles and shares add up correctly to prevent errors in allocation.
Avoid Overflows: Use safe math operations if Solidity <0.8 is in use to avoid overflow errors.
Access Control: Only allow recipients to withdraw their allocated balance.
Event Logging: Use
emitevents to log deposits and withdrawals for clear transaction records.Testing: Thoroughly test for various scenarios, especially with multiple recipients or varying balances.
Last updated
