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.
// Deploy contract with recipients and shares
address[] memory addresses = [address1, address2, address3];
uint256[] memory shares = [50, 30, 20]; // Totals to 100%
RevenueSplitter splitter = new RevenueSplitter(addresses, shares);
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.
// Send funds to contract (distributes automatically)
address(splitter).transfer(amount);
Withdrawing Funds
Each recipient can call the withdraw()
function to claim their balance.
// Recipient calls to withdraw funds
splitter.withdraw();
Viewing Allocation
Each recipient’s share and balance can be viewed with getShare()
and getBalance()
functions, respectively.
// Check recipient’s share and balance
splitter.getShare(recipientAddress);
splitter.getBalance(recipientAddress);
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
emit
events to log deposits and withdrawals for clear transaction records.Testing: Thoroughly test for various scenarios, especially with multiple recipients or varying balances.
Last updated