Skip to content

Commit 204f036

Browse files
committed
refactor: merge deploy scripts?
1 parent b53fa14 commit 204f036

File tree

12 files changed

+969
-566
lines changed

12 files changed

+969
-566
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.27;
3+
4+
import "forge-std/Script.sol";
5+
6+
import "src/contracts/core/RewardsCoordinator.sol";
7+
8+
/// @notice Claim RewardsCoordinator rewards using an externally-provided claim JSON.
9+
///
10+
/// Intended usage:
11+
/// - Your coworker/Sidecar produces a claim JSON (already in the correct shape/encoding).
12+
/// - You run this script against preprod-hoodi (or any Zeus env) to call `processClaim`.
13+
///
14+
/// Example:
15+
/// forge script script/operations/e2e/ClaimRewards.s.sol \
16+
/// --rpc-url "$RPC_HOODI" --private-key "$PRIVATE_KEY" --broadcast \
17+
/// --sig "run(string,address,address)" \
18+
/// -- "path/to/claim.json" 0xEarner 0xRecipient
19+
contract ClaimRewards is Script {
20+
/// @notice Claim using the RewardsCoordinator address from env var `REWARDS_COORDINATOR`.
21+
function run(
22+
string memory claimFile,
23+
address earner,
24+
address recipient
25+
) public {
26+
address rc = vm.envAddress("REWARDS_COORDINATOR");
27+
vm.startBroadcast();
28+
_claim(RewardsCoordinator(rc), claimFile, earner, recipient);
29+
vm.stopBroadcast();
30+
}
31+
32+
/// @notice Claim using an explicitly provided RewardsCoordinator address.
33+
function runWithRewardsCoordinator(
34+
address rewardsCoordinator,
35+
string memory claimFile,
36+
address earner,
37+
address recipient
38+
) public {
39+
vm.startBroadcast();
40+
_claim(RewardsCoordinator(rewardsCoordinator), claimFile, earner, recipient);
41+
vm.stopBroadcast();
42+
}
43+
44+
function _claim(
45+
RewardsCoordinator rc,
46+
string memory claimFile,
47+
address earner,
48+
address recipient
49+
) internal {
50+
IRewardsCoordinatorTypes.RewardsMerkleClaim memory claim = _loadClaimFromFile(claimFile);
51+
require(claim.earnerLeaf.earner == earner, "claim earner mismatch");
52+
rc.processClaim(claim, recipient);
53+
}
54+
55+
function _loadClaimFromFile(
56+
string memory claimPath
57+
) internal view returns (IRewardsCoordinatorTypes.RewardsMerkleClaim memory claim) {
58+
string memory fullPath = _resolvePath(claimPath);
59+
string memory json = vm.readFile(fullPath);
60+
61+
// Accept either:
62+
// - direct object: { rootIndex, earnerIndex, earnerTreeProof, earnerLeaf, tokenIndices, tokenTreeProofs, tokenLeaves }
63+
// - wrapped: { proof: { ... } } (Sidecar-style)
64+
if (_hasJsonPath(json, ".proof")) {
65+
claim.rootIndex = uint32(abi.decode(vm.parseJson(json, ".proof.rootIndex"), (uint256)));
66+
claim.earnerIndex = uint32(abi.decode(vm.parseJson(json, ".proof.earnerIndex"), (uint256)));
67+
claim.earnerTreeProof = abi.decode(vm.parseJson(json, ".proof.earnerTreeProof"), (bytes));
68+
claim.earnerLeaf =
69+
abi.decode(vm.parseJson(json, ".proof.earnerLeaf"), (IRewardsCoordinatorTypes.EarnerTreeMerkleLeaf));
70+
71+
// If the proof contains scalar token fields, wrap them into single-element arrays.
72+
claim.tokenIndices = new uint32[](1);
73+
claim.tokenIndices[0] = uint32(abi.decode(vm.parseJson(json, ".proof.tokenIndices"), (uint256)));
74+
claim.tokenTreeProofs = new bytes[](1);
75+
claim.tokenTreeProofs[0] = abi.decode(vm.parseJson(json, ".proof.tokenTreeProofs"), (bytes));
76+
claim.tokenLeaves = new IRewardsCoordinatorTypes.TokenTreeMerkleLeaf[](1);
77+
claim.tokenLeaves[0] =
78+
abi.decode(vm.parseJson(json, ".proof.tokenLeaves"), (IRewardsCoordinatorTypes.TokenTreeMerkleLeaf));
79+
return claim;
80+
}
81+
82+
claim.rootIndex = uint32(abi.decode(vm.parseJson(json, ".rootIndex"), (uint256)));
83+
claim.earnerIndex = uint32(abi.decode(vm.parseJson(json, ".earnerIndex"), (uint256)));
84+
claim.earnerTreeProof = abi.decode(vm.parseJson(json, ".earnerTreeProof"), (bytes));
85+
claim.earnerLeaf =
86+
abi.decode(vm.parseJson(json, ".earnerLeaf"), (IRewardsCoordinatorTypes.EarnerTreeMerkleLeaf));
87+
claim.tokenIndices = abi.decode(vm.parseJson(json, ".tokenIndices"), (uint32[]));
88+
claim.tokenTreeProofs = abi.decode(vm.parseJson(json, ".tokenTreeProofs"), (bytes[]));
89+
claim.tokenLeaves =
90+
abi.decode(vm.parseJson(json, ".tokenLeaves"), (IRewardsCoordinatorTypes.TokenTreeMerkleLeaf[]));
91+
}
92+
93+
function _hasJsonPath(
94+
string memory json,
95+
string memory path
96+
) internal pure returns (bool) {
97+
try vm.parseJson(json, path) returns (bytes memory raw) {
98+
return raw.length != 0;
99+
} catch {
100+
return false;
101+
}
102+
}
103+
104+
function _resolvePath(
105+
string memory path
106+
) internal view returns (string memory) {
107+
bytes memory b = bytes(path);
108+
if (b.length > 0 && b[0] == bytes1("/")) return path;
109+
return string.concat(vm.projectRoot(), "/", path);
110+
}
111+
}
112+

0 commit comments

Comments
 (0)