Skip to content

[WIP] feat: Fee on claim #122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion contracts/Distributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ contract Distributor is UUPSHelper {
/// @dev If the mapping is empty, by default rewards will accrue on the user address
mapping(address => mapping(address => address)) public claimRecipient;

uint256[36] private __gap;
/// @notice Minimum fee amount to be paid for claiming
uint256 public singleClaimFeeInWei;

uint256[35] private __gap;

/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EVENTS
Expand All @@ -115,6 +118,7 @@ contract Distributor is UUPSHelper {
event OperatorToggled(address indexed user, address indexed operator, bool isWhitelisted);
event Recovered(address indexed token, address indexed to, uint256 amount);
event Revoked(); // With this event an indexer could maintain a table (timestamp, merkleRootUpdate)
event SingleClaimFeeInWeiUpdated(uint256 newValue);
event TreeUpdated(bytes32 merkleRoot, bytes32 ipfsHash, uint48 endOfDisputePeriod);
event TrustedToggled(address indexed eoa, bool trust);
event UpgradeabilityRevoked();
Expand All @@ -129,6 +133,12 @@ contract Distributor is UUPSHelper {
_;
}

/// @notice Checks whether the `msg.sender` has the governor or the guardian role
modifier onlyGovernorOrGuardian() {
if (!accessControlManager.isGovernorOrGuardian(msg.sender)) revert Errors.NotGovernorOrGuardian();
_;
}

/// @notice Checks whether the `msg.sender` is the `user` address or is a trusted address
modifier onlyTrustedOrUser(address user) {
if (
Expand Down Expand Up @@ -190,6 +200,7 @@ contract Distributor is UUPSHelper {
uint256[] calldata amounts,
bytes32[][] calldata proofs
) external {
if (singleClaimFeeInWei > 0) revert Errors.InvalidFee();
address[] memory recipients = new address[](users.length);
bytes[] memory datas = new bytes[](users.length);
_claim(users, tokens, amounts, proofs, recipients, datas);
Expand All @@ -208,6 +219,34 @@ contract Distributor is UUPSHelper {
address[] calldata recipients,
bytes[] memory datas
) external {
if (singleClaimFeeInWei > 0) revert Errors.InvalidFee();
_claim(users, tokens, amounts, proofs, recipients, datas);
}

/// @notice Same as the function above but with the ability to pay a fee in ETH when claiming
function claimRewards(
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs
) external payable {
uint256 usersLength = users.length;
if (msg.value < singleClaimFeeInWei * usersLength) revert Errors.InvalidFee();
address[] memory recipients = new address[](usersLength);
bytes[] memory datas = new bytes[](usersLength);
_claim(users, tokens, amounts, proofs, recipients, datas);
}

/// @notice Same as the function above but with the ability to pay a fee in ETH when claiming
function claimRewardsWithRecipients(
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs,
address[] calldata recipients,
bytes[] memory datas
) external payable {
if (msg.value < singleClaimFeeInWei * users.length) revert Errors.InvalidFee();
_claim(users, tokens, amounts, proofs, recipients, datas);
}

Expand Down Expand Up @@ -345,6 +384,21 @@ contract Distributor is UUPSHelper {
emit DisputeAmountUpdated(_disputeAmount);
}

/// @notice Sets the minimum fee to claim a given reward token on Merkl
function updateSingleClaimFeeInWei(uint256 amount) external onlyGovernor {
singleClaimFeeInWei = amount;
emit SingleClaimFeeInWeiUpdated(amount);
}

/// @notice Withdraws the ETH accumulated on the contract
function withdrawETH(address payable recipient) external onlyGovernorOrGuardian {
uint256 balance = address(this).balance;
if (balance > 0) {
(bool success, ) = recipient.call{ value: balance }("");
if (!success) revert Errors.InvalidParam();
}
}

/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INTERNAL HELPERS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
Expand Down
1 change: 1 addition & 0 deletions contracts/utils/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ library Errors {
error CampaignRewardTooLow();
error CampaignShouldStartInFuture();
error InvalidDispute();
error InvalidFee();
error InvalidLengths();
error InvalidOverride();
error InvalidParam();
Expand Down