harvest_split.sol in Solidity
Split proceeds by picking hours, paid by the pull pattern.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// Split each harvest's proceeds by recorded picking hours.
contract HarvestSplit {
mapping(address => uint256) public hours_;
mapping(address => uint256) public owed;
address[] public pickers;
uint256 public totalHours;
bool public seasonOpen = true;
event HoursLogged(address indexed picker, uint256 hoursWorked);
event ProceedsIn(uint256 amount);
event Paid(address indexed picker, uint256 amount);
function logHours(uint256 hoursWorked) external {
require(seasonOpen, "season closed");
if (hours_[msg.sender] == 0) {
pickers.push(msg.sender);
}
hours_[msg.sender] += hoursWorked;
totalHours += hoursWorked;
emit HoursLogged(msg.sender, hoursWorked);
}
// Proceeds arrive; each picker's share lands in owed.
function deposit() external payable {
require(totalHours > 0, "no hours logged");
seasonOpen = false;
emit ProceedsIn(msg.value);
for (uint256 i = 0; i < pickers.length; i++) {
address p = pickers[i];
owed[p] += (msg.value * hours_[p]) / totalHours;
}
}
// Pull payments: zero first, then send.
function withdraw() external {
uint256 amount = owed[msg.sender];
require(amount > 0, "nothing owed");
owed[msg.sender] = 0;
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "send failed");
emit Paid(msg.sender, amount);
}
}
How it works
logHourstracks pickers and the season total.depositcloses the season and portions by hours.withdrawzeroes before sending — effects first, always.
Keywords and builtins used here
addressboolcontractemiteventexternalfalseforfunctionifmappingpayablepublicrequiretrueuint256
The run, in numbers
- Lines
- 46
- Characters to type
- 1305
- Tokens
- 268
- Three-star pace
- 55 tpm
At the three-star pace of 55 tokens a minute, this run takes about 292 seconds.
Step 2 of 3 in Encore, step 27 of 28 in Language basics.