Skip to content

Commit

Permalink
feat(distribution): impl Distribution contract
Browse files Browse the repository at this point in the history
  • Loading branch information
robertu7 committed Dec 20, 2023
1 parent 8143d43 commit c4e9fe7
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 61 deletions.
75 changes: 75 additions & 0 deletions src/Billboard/Distribution.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

import "./IDistribution.sol";

// https://github.com/Uniswap/merkle-distributor
contract Distribution is IDistribution, Ownable {
using Counters for Counters.Counter;
Counters.Counter public lastTreeId;

// treeId_ => merkleRoot_
mapping(uint256 => bytes32) public merkleRoots;

// treeId_ => balance_
mapping(uint256 => uint256) public balances;

// treeId_ => cid_ => account_
mapping(uint256 => mapping(bytes32 => mapping(address => bool))) public hasClaimed;

/// @inheritdoc IDistribution
function drop(bytes32 merkleRoot_) external payable onlyOwner returns (uint256 treeId_) {
require(msg.value > 0, "no value");

lastTreeId.increment();
treeId_ = lastTreeId.current();

// Set the merkle root
merkleRoots[treeId_] = merkleRoot_;

// Set the balance
balances[treeId_] = msg.value;

emit Drop(treeId_, msg.value);
}

/// @inheritdoc IDistribution
function claim(
uint256 treeId_,
bytes32 cid_,
address account_,
uint256 amount_,
bytes32[] calldata merkleProof_
) external {
require(!hasClaimed[treeId_][cid_][account_], "already claimed.");

// Verify the merkle proof
bytes32 _leaf = keccak256(abi.encodePacked(cid_, account_, amount_));
require(MerkleProof.verify(merkleProof_, merkleRoots[treeId_], _leaf), "invalid proof.");

// Mark it as claimed
hasClaimed[treeId_][cid_][account_] = true;

// Transfer
(bool _success, ) = account_.call{value: amount_}("");
require(_success, "transfer failed");

// Update the balance
balances[treeId_] -= amount_;

emit Claim(cid_, account_, amount_);
}

/// @inheritdoc IDistribution
function sweep(uint256 treeId_, address target_) external onlyOwner {
uint256 _balance = balances[treeId_];

(bool _success, ) = target_.call{value: _balance}("");
require(_success, "transfer failed");
}
}
59 changes: 59 additions & 0 deletions src/Billboard/IDistribution.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

interface IDistribution {
/**
* @dev Emitted when an new drop is created.
*
* @param treeId_ Tree ID of the drop
* @param amount_ Total amount of the drop
*/
event Drop(uint256 indexed treeId_, uint256 amount_);

/**
* @dev Emitted when an claim is made.
*
* @param cid_ Content ID of claim
* @param account_ Address of claim
* @param amount_ Amount of claim
*/
event Claim(bytes32 cid_, address indexed account_, uint256 amount_);

/**
* @notice Create a new drop
*
* @param merkleRoot_ Merkle root of new drop
*
* Emits a {Drop} event on success.
*/
function drop(bytes32 merkleRoot_) external payable returns (uint256 treeId_);

/**
* @notice Claim and transfer tokens
*
* @param treeId_ Tree ID
* @param cid_ Content ID
* @param account_ Address of claim
* @param amount_ Amount of claim
* @param proof_ Merkle proof for (treeId_, cid_, account_, amount_)
*
* Emits a {Claim} event on success.
*/
function claim(
uint256 treeId_,
bytes32 cid_,
address account_,
uint256 amount_,
bytes32[] calldata proof_
) external;

/**
* @notice Sweep any unclaimed funds
*
* Transfers the full tokenbalance from the distributor contract to `target_` address.
*
* @param treeId_ Tree ID
* @param target_ Address that should receive the unclaimed funds
*/
function sweep(uint256 treeId_, address target_) external;
}
61 changes: 0 additions & 61 deletions src/Distribution/IDistribution.sol

This file was deleted.

0 comments on commit c4e9fe7

Please sign in to comment.