Skip to content

Commit b74624d

Browse files
feat(merkle-distributor): Make claim only callable by recipient or whitelisted claimer (#195)
* feat(merkle-distributor): Make claim only callable by recipient Intended use case is for `claim` to reset user's off-chain reward rate (used to produce rewards that would be seeded into this contract). Therefore, claim should only be callable by end recipient * Add claimFor * Reset * Update MerkleDistributor.sol * Update MerkleDistributor.ts * Update MerkleDistributor.ts * Update MerkleDistributor.ts * Update MerkleDistributor.sol * Use interface * WIP * Bump contracts to 0.40 * Update contracts/merkle-distributor/AcrossMerkleDistributor.sol Co-authored-by: Chris Maree <christopher.maree@gmail.com> * Update package.json * Update AcrossMerkleDistributor.sol Co-authored-by: Chris Maree <christopher.maree@gmail.com>
1 parent 58e42f4 commit b74624d

File tree

7 files changed

+102
-324
lines changed

7 files changed

+102
-324
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// SPDX-License-Identifier: AGPL-3.0-only
2+
pragma solidity ^0.8.0;
3+
4+
import "@uma/core/contracts/merkle-distributor/implementation/MerkleDistributor.sol";
5+
6+
/**
7+
* @title Extended MerkleDistributor contract.
8+
* @notice Adds additional constraints governing who can claim leaves from merkle windows.
9+
*/
10+
contract AcrossMerkleDistributor is MerkleDistributor {
11+
// Addresses that can claim on user's behalf. Useful to get around the requirement that claim recipient
12+
// must also be claimer.
13+
mapping(address => bool) public whitelistedClaimers;
14+
15+
/****************************************
16+
* EVENTS
17+
****************************************/
18+
event WhitelistedClaimer(address indexed claimer, bool indexed whitelist);
19+
20+
/****************************
21+
* ADMIN FUNCTIONS
22+
****************************/
23+
24+
/**
25+
* @notice Updates whitelisted claimer status.
26+
* @dev Callable only by owner.
27+
* @param newContract Reset claimer contract to this address.
28+
* @param whitelist True to whitelist claimer, False otherwise.
29+
*/
30+
function whitelistClaimer(address newContract, bool whitelist) external onlyOwner {
31+
whitelistedClaimers[newContract] = whitelist;
32+
emit WhitelistedClaimer(newContract, whitelist);
33+
}
34+
35+
/****************************
36+
* NON-ADMIN FUNCTIONS
37+
****************************/
38+
39+
/**
40+
* @notice Batch claims to reduce gas versus individual submitting all claims. Method will fail
41+
* if any individual claims within the batch would fail.
42+
* @dev All claim recipients must be equal to msg.sender or claimer must be whitelisted.
43+
* @param claims array of claims to claim.
44+
*/
45+
function claimMulti(Claim[] memory claims) public override {
46+
if (!whitelistedClaimers[msg.sender]) {
47+
uint256 claimCount = claims.length;
48+
for (uint256 i = 0; i < claimCount; i++) {
49+
require(claims[i].account == msg.sender, "invalid claimer");
50+
}
51+
}
52+
super.claimMulti(claims);
53+
}
54+
55+
/**
56+
* @notice Claim amount of reward tokens for account, as described by Claim input object.
57+
* @dev Claim recipient must be equal to msg.sender or caller must be whitelisted.
58+
* @param _claim claim object describing amount, accountIndex, account, window index, and merkle proof.
59+
*/
60+
function claim(Claim memory _claim) public override {
61+
require(whitelistedClaimers[msg.sender] || _claim.account == msg.sender, "invalid claimer");
62+
super.claim(_claim);
63+
}
64+
}

contracts/merkle-distributor/MerkleDistributor.sol

Lines changed: 0 additions & 265 deletions
This file was deleted.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@across-protocol/contracts-v2",
3-
"version": "1.0.5",
3+
"version": "1.0.6",
44
"author": "UMA Team",
55
"license": "AGPL-3.0",
66
"repository": {
@@ -37,7 +37,7 @@
3737
"@openzeppelin/contracts": "^4.7.3",
3838
"@uma/common": "^2.28.0",
3939
"@uma/contracts-node": "^0.3.18",
40-
"@uma/core": "^2.38.0",
40+
"@uma/core": "^2.40.0",
4141
"@uma/merkle-distributor": "^1.3.38",
4242
"arb-bridge-eth": "^0.7.4",
4343
"arb-bridge-peripherals": "^1.0.5"

tasks/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async function _findL2TokenFromTokenList(l2ChainId: number, l1TokenAddress: stri
3131
}
3232
if (l2ChainId === 137) {
3333
const response = await fetch(
34-
"https://raw.githubusercontent.com/maticnetwork/polygon-token-list/master/src/tokens/allTokens.json"
34+
"https://raw.githubusercontent.com/maticnetwork/polygon-token-list/master/src/tokens/polygonTokens.json"
3535
);
3636
const body = await response.text();
3737
const tokenList = JSON.parse(body);

test/constants.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { toWei, utf8ToHex, toBN, createRandomBytes32, ethers, hre } from "./utils";
1+
import { toWei, utf8ToHex, toBN, createRandomBytes32 } from "./utils";
2+
3+
import { ethers } from "ethers";
24

35
export { TokenRolesEnum } from "@uma/common";
46

0 commit comments

Comments
 (0)