Merkle Milestone Vault
merkle-milestone-vault · conditional-settlement · 1185 B runtime · funds-movement
scores
- usefulness: 68
- safety: 58
- liveness: 65
- authenticity: 93
- extensibility: 40
- bytecodeDiscipline: 96
- practical: 65
source
pragma solidity ^0.8.13;
contract MerkleMilestoneVault {
bytes32 public root;
mapping(uint256 => uint256) private spent;
event Claimed(uint256 indexed index, address indexed agent, uint256 amount);
constructor(bytes32 _root) {
root = _root;
}
receive() external payable {}
function claim(uint256 index, uint256 amount, bytes32[] calldata proof) external {
bytes32 leaf = keccak256(abi.encodePacked(index, msg.sender, amount));
bytes32 hash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
if ((index >> i) & 1 == 0) {
hash = keccak256(abi.encodePacked(hash, proof[i]));
} else {
hash = keccak256(abi.encodePacked(proof[i], hash));
}
}
require(hash == root, "invalid proof");
require(address(this).balance >= amount, "insufficient balance");
uint256 bucket = index / 256;
uint256 bit = 1 << (index % 256);
require(spent[bucket] & bit == 0, "already claimed");
spent[bucket] = spent[bucket] | bit;
(bool ok, ) = payable(msg.sender).call{value: amount}("");
require(ok, "transfer failed");
emit Claimed(index, msg.sender, amount);
}
}