@bananapus/distributor-v6 0.0.34 → 0.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/package.json +2 -2
- package/references/operations.md +2 -1
- package/src/JB721Distributor.sol +357 -26
- package/src/JBDistributor.sol +348 -171
- package/src/JBTokenDistributor.sol +49 -17
- package/src/interfaces/IJB721Distributor.sol +139 -0
- package/src/interfaces/IJBDistributor.sol +22 -8
- package/src/structs/JBBorrowContext.sol +2 -0
- package/src/structs/JBClaimContext.sol +5 -0
- package/src/structs/JBVestContext.sol +5 -0
- package/src/structs/JBVestingLoan.sol +2 -0
|
@@ -60,9 +60,12 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
60
60
|
|
|
61
61
|
/// @notice The next reward round a staker has not yet claimed.
|
|
62
62
|
/// @custom:param hook The IVotes token whose stakers are claiming.
|
|
63
|
+
/// @custom:param groupId The reward group (0 = the default group).
|
|
63
64
|
/// @custom:param tokenId The encoded staker address.
|
|
64
65
|
/// @custom:param token The reward token being claimed.
|
|
65
|
-
mapping(
|
|
66
|
+
mapping(
|
|
67
|
+
address hook => mapping(uint256 groupId => mapping(uint256 tokenId => mapping(IERC20 token => uint256)))
|
|
68
|
+
) public nextClaimRoundOf;
|
|
66
69
|
|
|
67
70
|
//*********************************************************************//
|
|
68
71
|
// -------------------------- constructor ---------------------------- //
|
|
@@ -121,8 +124,8 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
if (msg.value != 0) {
|
|
124
|
-
//
|
|
125
|
-
_recordRewardFunding({hook: hook, token: IERC20(context.token), amount: msg.value});
|
|
127
|
+
// Split-funded pots go to the default group (0); a split cannot carry a tier set.
|
|
128
|
+
_recordRewardFunding({hook: hook, groupId: 0, token: IERC20(context.token), amount: msg.value});
|
|
126
129
|
}
|
|
127
130
|
} else {
|
|
128
131
|
// Validate that native ETH is not cross-booked under an ERC-20 token.
|
|
@@ -139,8 +142,8 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
139
142
|
uint256 delta =
|
|
140
143
|
_acceptErc20FundsFrom({token: IERC20(context.token), from: msg.sender, amount: context.amount});
|
|
141
144
|
|
|
142
|
-
// Assign only the amount actually received to this round's reward pot.
|
|
143
|
-
_recordRewardFunding({hook: hook, token: IERC20(context.token), amount: delta});
|
|
145
|
+
// Assign only the amount actually received to this round's reward pot (default group, 0).
|
|
146
|
+
_recordRewardFunding({hook: hook, groupId: 0, token: IERC20(context.token), amount: delta});
|
|
144
147
|
}
|
|
145
148
|
}
|
|
146
149
|
|
|
@@ -169,14 +172,28 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
169
172
|
/// @param hook The IVotes token whose stakers are claiming.
|
|
170
173
|
/// @param tokenIds The encoded staker addresses to claim for.
|
|
171
174
|
/// @param tokens The reward tokens to claim.
|
|
172
|
-
function _claimPastRewards(
|
|
175
|
+
function _claimPastRewards(
|
|
176
|
+
address hook,
|
|
177
|
+
uint256 groupId,
|
|
178
|
+
uint256[] calldata tokenIds,
|
|
179
|
+
IERC20[] calldata tokens
|
|
180
|
+
)
|
|
181
|
+
internal
|
|
182
|
+
override
|
|
183
|
+
{
|
|
173
184
|
// Round 0 has no completed reward rounds behind it, so nothing can be claimed yet.
|
|
174
185
|
uint256 round = currentRound();
|
|
175
186
|
if (round == 0) return;
|
|
176
187
|
|
|
177
|
-
// Current-round funding is excluded. It becomes claimable only after a later round starts.
|
|
178
|
-
|
|
179
|
-
|
|
188
|
+
// Current-round funding is excluded. It becomes claimable only after a later round starts. Token distributors
|
|
189
|
+
// have no tier concept, so `tierIds` stays empty; the group only isolates reward storage.
|
|
190
|
+
JBClaimContext memory ctx = JBClaimContext({
|
|
191
|
+
hook: hook,
|
|
192
|
+
groupId: groupId,
|
|
193
|
+
tierIds: new uint256[](0),
|
|
194
|
+
lastClaimableRound: round - 1,
|
|
195
|
+
vestingReleaseRound: round + VESTING_ROUNDS
|
|
196
|
+
});
|
|
180
197
|
|
|
181
198
|
// Process each reward token independently because each token has its own round funding and claim cursor.
|
|
182
199
|
for (uint256 i; i < tokens.length;) {
|
|
@@ -219,7 +236,7 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
219
236
|
returns (uint256 tokenAmount)
|
|
220
237
|
{
|
|
221
238
|
// Load this staker's cursor for the reward token. All earlier rounds have already been settled.
|
|
222
|
-
uint256 nextClaimRound = nextClaimRoundOf[ctx.hook][tokenId][token];
|
|
239
|
+
uint256 nextClaimRound = nextClaimRoundOf[ctx.hook][ctx.groupId][tokenId][token];
|
|
223
240
|
|
|
224
241
|
// If the cursor is already past the last completed round, this staker is current.
|
|
225
242
|
if (nextClaimRound > ctx.lastClaimableRound) return 0;
|
|
@@ -227,6 +244,7 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
227
244
|
// Sum this staker's pro-rata share from every unclaimed completed reward round.
|
|
228
245
|
tokenAmount = _claimRewardsFor({
|
|
229
246
|
hook: ctx.hook,
|
|
247
|
+
groupId: ctx.groupId,
|
|
230
248
|
tokenId: tokenId,
|
|
231
249
|
token: token,
|
|
232
250
|
firstRound: nextClaimRound,
|
|
@@ -234,17 +252,18 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
234
252
|
});
|
|
235
253
|
|
|
236
254
|
// Advance the cursor even when the amount is zero, so empty or zero-stake rounds are not rescanned forever.
|
|
237
|
-
nextClaimRoundOf[ctx.hook][tokenId][token] = ctx.lastClaimableRound + 1;
|
|
255
|
+
nextClaimRoundOf[ctx.hook][ctx.groupId][tokenId][token] = ctx.lastClaimableRound + 1;
|
|
238
256
|
if (tokenAmount == 0) return 0;
|
|
239
257
|
|
|
240
258
|
// All accumulated past rewards start a single fresh vesting schedule at the claim round.
|
|
241
|
-
vestingDataOf[ctx.hook][tokenId][token].push(
|
|
259
|
+
vestingDataOf[ctx.hook][ctx.groupId][tokenId][token].push(
|
|
242
260
|
JBVestingData({releaseRound: ctx.vestingReleaseRound, amount: tokenAmount, shareClaimed: 0})
|
|
243
261
|
);
|
|
244
262
|
|
|
245
263
|
emit Claimed({
|
|
246
264
|
hook: ctx.hook,
|
|
247
265
|
tokenId: tokenId,
|
|
266
|
+
groupId: ctx.groupId,
|
|
248
267
|
token: token,
|
|
249
268
|
amount: tokenAmount,
|
|
250
269
|
vestingReleaseRound: ctx.vestingReleaseRound,
|
|
@@ -265,6 +284,7 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
265
284
|
/// @return tokenAmount The cumulative unclaimed reward amount.
|
|
266
285
|
function _claimRewardsFor(
|
|
267
286
|
address hook,
|
|
287
|
+
uint256 groupId,
|
|
268
288
|
uint256 tokenId,
|
|
269
289
|
IERC20 token,
|
|
270
290
|
uint256 firstRound,
|
|
@@ -275,14 +295,14 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
275
295
|
{
|
|
276
296
|
// Walk every unclaimed historical round. The caller bounds this to completed rounds only.
|
|
277
297
|
for (uint256 rewardRoundNumber = firstRound; rewardRoundNumber <= lastRound;) {
|
|
278
|
-
// Load this round's reward data for the hook and reward token.
|
|
279
|
-
JBRewardRoundData storage rewardRound = rewardRoundOf[hook][token][rewardRoundNumber];
|
|
298
|
+
// Load this round's reward data for the hook, group, and reward token.
|
|
299
|
+
JBRewardRoundData storage rewardRound = rewardRoundOf[hook][groupId][token][rewardRoundNumber];
|
|
280
300
|
|
|
281
301
|
// Skip rounds that never received funding.
|
|
282
302
|
if (rewardRound.amount != 0) {
|
|
283
303
|
// Expired rounds can no longer be claimed as-is; recycle their unclaimed remainder instead.
|
|
284
304
|
if (_rewardRoundExpired(rewardRound)) {
|
|
285
|
-
_recycleExpiredRewardRound({hook: hook, token: token, round: rewardRoundNumber});
|
|
305
|
+
_recycleExpiredRewardRound({hook: hook, groupId: groupId, token: token, round: rewardRoundNumber});
|
|
286
306
|
} else if (rewardRound.totalStake != 0) {
|
|
287
307
|
// Use the funding round's snapshot block, not the block at which the staker finally claims.
|
|
288
308
|
uint256 tokenStakeAmount =
|
|
@@ -350,11 +370,23 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
|
|
|
350
370
|
}
|
|
351
371
|
|
|
352
372
|
/// @notice The total supply of votes at a specific block.
|
|
353
|
-
/// @dev Uses `IVotes.getPastTotalSupply` for checkpointed lookups.
|
|
373
|
+
/// @dev Uses `IVotes.getPastTotalSupply` for checkpointed lookups. Token distributors have no tier concept, so the
|
|
374
|
+
/// group only isolates reward storage and does not change the stake denominator.
|
|
354
375
|
/// @param hook The IVotes-compatible token contract.
|
|
376
|
+
/// @param groupId The reward group (unused for token distributors — kept for base-hook conformance).
|
|
355
377
|
/// @param blockNumber The block number to get the total supply at.
|
|
356
378
|
/// @return totalStakedAmount The total supply of votes at the given block.
|
|
357
|
-
function _totalStake(
|
|
379
|
+
function _totalStake(
|
|
380
|
+
address hook,
|
|
381
|
+
uint256 groupId,
|
|
382
|
+
uint256 blockNumber
|
|
383
|
+
)
|
|
384
|
+
internal
|
|
385
|
+
view
|
|
386
|
+
override
|
|
387
|
+
returns (uint256 totalStakedAmount)
|
|
388
|
+
{
|
|
389
|
+
groupId; // Silence unused variable warning — token distributors are group-agnostic in weight.
|
|
358
390
|
totalStakedAmount = IVotes(hook).getPastTotalSupply(blockNumber);
|
|
359
391
|
}
|
|
360
392
|
|
|
@@ -3,13 +3,152 @@ pragma solidity ^0.8.0;
|
|
|
3
3
|
|
|
4
4
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
5
5
|
import {IJBSplitHook} from "@bananapus/core-v6/src/interfaces/IJBSplitHook.sol";
|
|
6
|
+
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
6
7
|
|
|
7
8
|
import {IJBDistributor} from "./IJBDistributor.sol";
|
|
8
9
|
|
|
9
10
|
/// @notice A singleton distributor that distributes ERC-20 rewards to JB 721 NFT stakers with linear vesting.
|
|
10
11
|
/// @dev Also implements `IJBSplitHook` to receive tokens from payout splits.
|
|
11
12
|
/// @dev Projects configure their split with `hook = distributor` and `beneficiary = their721Hook`.
|
|
13
|
+
/// @dev Adds tier-scoped reward groups on top of the generic group plumbing: a group is a strictly-increasing tier
|
|
14
|
+
/// set, and only NFTs whose tier is in the set can claim that group's pot.
|
|
12
15
|
interface IJB721Distributor is IJBDistributor, IJBSplitHook {
|
|
16
|
+
//*********************************************************************//
|
|
17
|
+
// ----------------------------- views ------------------------------- //
|
|
18
|
+
//*********************************************************************//
|
|
19
|
+
|
|
13
20
|
/// @notice The JB directory used to verify terminal/controller callers.
|
|
14
21
|
function DIRECTORY() external view returns (IJBDirectory);
|
|
22
|
+
|
|
23
|
+
/// @notice Calculate how much of the token has been claimed for the given tokenId in a tier-scoped group.
|
|
24
|
+
/// @param hook The hook the tokenId belongs to.
|
|
25
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
26
|
+
/// @param tokenId The ID of the token to calculate the token amount for.
|
|
27
|
+
/// @param token The address of the token to check.
|
|
28
|
+
function claimedFor(
|
|
29
|
+
address hook,
|
|
30
|
+
uint256[] calldata tierIds,
|
|
31
|
+
uint256 tokenId,
|
|
32
|
+
IERC20 token
|
|
33
|
+
)
|
|
34
|
+
external
|
|
35
|
+
view
|
|
36
|
+
returns (uint256);
|
|
37
|
+
|
|
38
|
+
/// @notice Calculate how much of the token is currently ready to be collected for the given tokenId in a
|
|
39
|
+
/// tier-scoped group.
|
|
40
|
+
/// @param hook The hook the tokenId belongs to.
|
|
41
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
42
|
+
/// @param tokenId The ID of the token to calculate the token amount for.
|
|
43
|
+
/// @param token The address of the token to check.
|
|
44
|
+
function collectableFor(
|
|
45
|
+
address hook,
|
|
46
|
+
uint256[] calldata tierIds,
|
|
47
|
+
uint256 tokenId,
|
|
48
|
+
IERC20 token
|
|
49
|
+
)
|
|
50
|
+
external
|
|
51
|
+
view
|
|
52
|
+
returns (uint256);
|
|
53
|
+
|
|
54
|
+
/// @notice The tier set that defines a reward group, recorded when the group is first funded.
|
|
55
|
+
/// @dev Empty for the all-tiers group (0).
|
|
56
|
+
/// @param hook The hook the group belongs to.
|
|
57
|
+
/// @param groupId The reward group.
|
|
58
|
+
/// @return tierIds The strictly-increasing tier set defining the group.
|
|
59
|
+
function tierIdsOf(address hook, uint256 groupId) external view returns (uint256[] memory tierIds);
|
|
60
|
+
|
|
61
|
+
//*********************************************************************//
|
|
62
|
+
// ---------------------------- transactions ------------------------- //
|
|
63
|
+
//*********************************************************************//
|
|
64
|
+
|
|
65
|
+
/// @notice Claims tokens and begins vesting from a tier-scoped reward group.
|
|
66
|
+
/// @param hook The hook whose stakers are vesting.
|
|
67
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
68
|
+
/// @param tokenIds The IDs to claim rewards for.
|
|
69
|
+
/// @param tokens The tokens to claim.
|
|
70
|
+
function beginVesting(
|
|
71
|
+
address hook,
|
|
72
|
+
uint256[] calldata tierIds,
|
|
73
|
+
uint256[] calldata tokenIds,
|
|
74
|
+
IERC20[] calldata tokens
|
|
75
|
+
)
|
|
76
|
+
external;
|
|
77
|
+
|
|
78
|
+
/// @notice Borrow against one token ID's uncollected vesting rewards in a tier-scoped group.
|
|
79
|
+
/// @param hook The hook whose staker is borrowing against vesting rewards.
|
|
80
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
81
|
+
/// @param tokenIds The single token ID to borrow against.
|
|
82
|
+
/// @param tokens The single revnet reward token to collateralize.
|
|
83
|
+
/// @param sourceToken The token to borrow from the revnet.
|
|
84
|
+
/// @param minBorrowAmount The minimum amount to borrow, denominated in `sourceToken`.
|
|
85
|
+
/// @param prepaidFeePercent The fee percent to charge upfront.
|
|
86
|
+
/// @param beneficiary The recipient of the borrowed funds.
|
|
87
|
+
/// @return loanId The Revnet loan NFT ID held by this distributor.
|
|
88
|
+
/// @return collateralCount The amount of vesting rewards used as collateral.
|
|
89
|
+
function borrowAgainstVesting(
|
|
90
|
+
address hook,
|
|
91
|
+
uint256[] calldata tierIds,
|
|
92
|
+
uint256[] calldata tokenIds,
|
|
93
|
+
IERC20[] calldata tokens,
|
|
94
|
+
address sourceToken,
|
|
95
|
+
uint256 minBorrowAmount,
|
|
96
|
+
uint256 prepaidFeePercent,
|
|
97
|
+
address payable beneficiary
|
|
98
|
+
)
|
|
99
|
+
external
|
|
100
|
+
returns (uint256 loanId, uint256 collateralCount);
|
|
101
|
+
|
|
102
|
+
/// @notice Recycle unclaimed rewards from expired tier-scoped reward rounds into the current reward round.
|
|
103
|
+
/// @param hook The hook whose expired reward rounds should be recycled.
|
|
104
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
105
|
+
/// @param token The reward token to recycle.
|
|
106
|
+
/// @param rounds The reward rounds to recycle.
|
|
107
|
+
/// @return amount The total amount recycled.
|
|
108
|
+
function burnExpiredRewards(
|
|
109
|
+
address hook,
|
|
110
|
+
uint256[] calldata tierIds,
|
|
111
|
+
IERC20 token,
|
|
112
|
+
uint256[] calldata rounds
|
|
113
|
+
)
|
|
114
|
+
external
|
|
115
|
+
returns (uint256 amount);
|
|
116
|
+
|
|
117
|
+
/// @notice Collect vested tokens from a tier-scoped reward group.
|
|
118
|
+
/// @param hook The hook whose stakers are collecting.
|
|
119
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
120
|
+
/// @param tokenIds The IDs of the tokens to collect for.
|
|
121
|
+
/// @param tokens The addresses of the tokens to collect.
|
|
122
|
+
/// @param beneficiary The recipient of the collected tokens.
|
|
123
|
+
function collectVestedRewards(
|
|
124
|
+
address hook,
|
|
125
|
+
uint256[] calldata tierIds,
|
|
126
|
+
uint256[] calldata tokenIds,
|
|
127
|
+
IERC20[] calldata tokens,
|
|
128
|
+
address beneficiary
|
|
129
|
+
)
|
|
130
|
+
external;
|
|
131
|
+
|
|
132
|
+
/// @notice Fund a tier-scoped reward group: only holders of the given tiers can claim this pot.
|
|
133
|
+
/// @dev For native ETH, send `msg.value` and pass `IERC20(NATIVE_TOKEN)` as the token.
|
|
134
|
+
/// @param hook The hook to fund.
|
|
135
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
136
|
+
/// @param token The token to fund with.
|
|
137
|
+
/// @param amount The amount to fund.
|
|
138
|
+
function fund(address hook, uint256[] calldata tierIds, IERC20 token, uint256 amount) external payable;
|
|
139
|
+
|
|
140
|
+
/// @notice Recycle unlocked rewards from burned tokens in a tier-scoped group into the current reward round.
|
|
141
|
+
/// @param hook The hook whose tokens were burned.
|
|
142
|
+
/// @param tierIds The strictly-increasing tier set defining the group.
|
|
143
|
+
/// @param tokenIds The IDs of the burned tokens.
|
|
144
|
+
/// @param tokens The reward tokens to recycle.
|
|
145
|
+
/// @param beneficiary Unused for forfeiture.
|
|
146
|
+
function releaseForfeitedRewards(
|
|
147
|
+
address hook,
|
|
148
|
+
uint256[] calldata tierIds,
|
|
149
|
+
uint256[] calldata tokenIds,
|
|
150
|
+
IERC20[] calldata tokens,
|
|
151
|
+
address beneficiary
|
|
152
|
+
)
|
|
153
|
+
external;
|
|
15
154
|
}
|
|
@@ -45,6 +45,7 @@ interface IJBDistributor {
|
|
|
45
45
|
/// @notice Emitted when a staker begins vesting tokens.
|
|
46
46
|
/// @param hook The hook whose stakers are vesting.
|
|
47
47
|
/// @param tokenId The ID of the staked token that is claiming.
|
|
48
|
+
/// @param groupId The reward group claimed from (0 = the default group).
|
|
48
49
|
/// @param token The address of the token to vest.
|
|
49
50
|
/// @param amount The amount of tokens to vest.
|
|
50
51
|
/// @param vestingReleaseRound The round at which the tokens will be fully released.
|
|
@@ -52,6 +53,7 @@ interface IJBDistributor {
|
|
|
52
53
|
event Claimed(
|
|
53
54
|
address indexed hook,
|
|
54
55
|
uint256 indexed tokenId,
|
|
56
|
+
uint256 groupId,
|
|
55
57
|
IERC20 token,
|
|
56
58
|
uint256 amount,
|
|
57
59
|
uint256 vestingReleaseRound,
|
|
@@ -61,6 +63,7 @@ interface IJBDistributor {
|
|
|
61
63
|
/// @notice Emitted when vested tokens are collected.
|
|
62
64
|
/// @param hook The hook whose stakers are collecting.
|
|
63
65
|
/// @param tokenId The ID of the staked token collecting.
|
|
66
|
+
/// @param groupId The reward group collected from (0 = the default group).
|
|
64
67
|
/// @param token The address of the token collected.
|
|
65
68
|
/// @param amount The amount of tokens collected.
|
|
66
69
|
/// @param vestingReleaseRound The round at which the tokens will be fully released.
|
|
@@ -68,6 +71,7 @@ interface IJBDistributor {
|
|
|
68
71
|
event Collected(
|
|
69
72
|
address indexed hook,
|
|
70
73
|
uint256 indexed tokenId,
|
|
74
|
+
uint256 groupId,
|
|
71
75
|
IERC20 token,
|
|
72
76
|
uint256 amount,
|
|
73
77
|
uint256 vestingReleaseRound,
|
|
@@ -171,17 +175,27 @@ interface IJBDistributor {
|
|
|
171
175
|
|
|
172
176
|
/// @notice The active Revnet loan using one token ID's vesting rewards as collateral.
|
|
173
177
|
/// @param hook The hook the token ID belongs to.
|
|
178
|
+
/// @param groupId The reward group (0 = the default group).
|
|
174
179
|
/// @param tokenId The token ID whose vesting rewards are collateralized.
|
|
175
180
|
/// @param token The reward token used as loan collateral.
|
|
176
|
-
function activeVestingLoanIdOf(
|
|
181
|
+
function activeVestingLoanIdOf(
|
|
182
|
+
address hook,
|
|
183
|
+
uint256 groupId,
|
|
184
|
+
uint256 tokenId,
|
|
185
|
+
IERC20 token
|
|
186
|
+
)
|
|
187
|
+
external
|
|
188
|
+
view
|
|
189
|
+
returns (uint256);
|
|
177
190
|
|
|
178
|
-
/// @notice Calculate how much of the token has been claimed for the given tokenId.
|
|
191
|
+
/// @notice Calculate how much of the token has been claimed for the given tokenId in the default group.
|
|
179
192
|
/// @param hook The hook the tokenId belongs to.
|
|
180
193
|
/// @param tokenId The ID of the token to calculate the token amount for.
|
|
181
194
|
/// @param token The address of the token to check.
|
|
182
195
|
function claimedFor(address hook, uint256 tokenId, IERC20 token) external view returns (uint256);
|
|
183
196
|
|
|
184
|
-
/// @notice Calculate how much of the token is currently ready to be collected for the given tokenId
|
|
197
|
+
/// @notice Calculate how much of the token is currently ready to be collected for the given tokenId in the
|
|
198
|
+
/// default group.
|
|
185
199
|
/// @param hook The hook the tokenId belongs to.
|
|
186
200
|
/// @param tokenId The ID of the token to calculate the token amount for.
|
|
187
201
|
/// @param token The address of the token to check.
|
|
@@ -217,7 +231,7 @@ interface IJBDistributor {
|
|
|
217
231
|
// ---------------------------- transactions ------------------------- //
|
|
218
232
|
//*********************************************************************//
|
|
219
233
|
|
|
220
|
-
/// @notice Claims tokens and begins vesting.
|
|
234
|
+
/// @notice Claims tokens and begins vesting from the default group.
|
|
221
235
|
/// @param hook The hook whose stakers are vesting.
|
|
222
236
|
/// @param tokenIds The IDs to claim rewards for.
|
|
223
237
|
/// @param tokens The tokens to claim.
|
|
@@ -245,7 +259,7 @@ interface IJBDistributor {
|
|
|
245
259
|
external
|
|
246
260
|
returns (uint256 loanId, uint256 collateralCount);
|
|
247
261
|
|
|
248
|
-
/// @notice Collect vested tokens.
|
|
262
|
+
/// @notice Collect vested tokens from the default group.
|
|
249
263
|
/// @param hook The hook whose stakers are collecting.
|
|
250
264
|
/// @param tokenIds The IDs of the tokens to collect for.
|
|
251
265
|
/// @param tokens The addresses of the tokens to collect.
|
|
@@ -258,14 +272,14 @@ interface IJBDistributor {
|
|
|
258
272
|
)
|
|
259
273
|
external;
|
|
260
274
|
|
|
261
|
-
/// @notice Fund the distributor for a specific hook.
|
|
275
|
+
/// @notice Fund the distributor's default group for a specific hook.
|
|
262
276
|
/// @dev For native ETH, send `msg.value` and pass `IERC20(NATIVE_TOKEN)` as the token.
|
|
263
277
|
/// @param hook The hook to fund.
|
|
264
278
|
/// @param token The token to fund with.
|
|
265
279
|
/// @param amount The amount to fund.
|
|
266
280
|
function fund(address hook, IERC20 token, uint256 amount) external payable;
|
|
267
281
|
|
|
268
|
-
/// @notice Recycle unclaimed rewards from expired reward rounds into the current reward round.
|
|
282
|
+
/// @notice Recycle unclaimed rewards from expired default-group reward rounds into the current reward round.
|
|
269
283
|
/// @param hook The hook whose expired reward rounds should be recycled.
|
|
270
284
|
/// @param token The reward token to recycle.
|
|
271
285
|
/// @param rounds The reward rounds to recycle.
|
|
@@ -287,7 +301,7 @@ interface IJBDistributor {
|
|
|
287
301
|
payable
|
|
288
302
|
returns (uint256 paidOffLoanId);
|
|
289
303
|
|
|
290
|
-
/// @notice Recycle unlocked rewards from burned tokens into the current reward round.
|
|
304
|
+
/// @notice Recycle unlocked rewards from burned tokens in the default group into the current reward round.
|
|
291
305
|
/// @param hook The hook whose tokens were burned.
|
|
292
306
|
/// @param tokenIds The IDs of the burned tokens.
|
|
293
307
|
/// @param tokens The reward tokens to recycle.
|
|
@@ -5,6 +5,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
5
5
|
|
|
6
6
|
/// @notice Parameters used while opening a distributor-owned Revnet loan.
|
|
7
7
|
/// @custom:member hook The hook whose token ID owns the vesting rewards.
|
|
8
|
+
/// @custom:member groupId The reward group whose vesting rewards are collateralized (0 = the default group).
|
|
8
9
|
/// @custom:member tokenId The token ID whose vesting rewards are collateralized.
|
|
9
10
|
/// @custom:member token The revnet reward token used as loan collateral.
|
|
10
11
|
/// @custom:member sourceToken The token borrowed from the revnet.
|
|
@@ -14,6 +15,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
14
15
|
/// @custom:member revnetId The revnet whose project token is collateralized.
|
|
15
16
|
struct JBBorrowContext {
|
|
16
17
|
address hook;
|
|
18
|
+
uint256 groupId;
|
|
17
19
|
uint256 tokenId;
|
|
18
20
|
IERC20 token;
|
|
19
21
|
address sourceToken;
|
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
4
|
/// @custom:member hook The stake source whose historical rewards are being claimed.
|
|
5
|
+
/// @custom:member groupId The reward group being claimed (0 = the default group).
|
|
6
|
+
/// @custom:member tierIds The tier set defining the group (empty for the default group); used to filter eligible
|
|
7
|
+
/// token IDs on the tier-scoped path.
|
|
5
8
|
/// @custom:member lastClaimableRound The last completed reward round included in the claim.
|
|
6
9
|
/// @custom:member vestingReleaseRound The round at which newly materialized rewards finish vesting.
|
|
7
10
|
struct JBClaimContext {
|
|
8
11
|
address hook;
|
|
12
|
+
uint256 groupId;
|
|
13
|
+
uint256[] tierIds;
|
|
9
14
|
uint256 lastClaimableRound;
|
|
10
15
|
uint256 vestingReleaseRound;
|
|
11
16
|
}
|
|
@@ -4,6 +4,9 @@ pragma solidity ^0.8.0;
|
|
|
4
4
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
5
5
|
|
|
6
6
|
/// @custom:member hook The stake source whose rewards are being vested.
|
|
7
|
+
/// @custom:member groupId The reward group being claimed (0 = the default group).
|
|
8
|
+
/// @custom:member tierIds The tier set defining the group (empty for the default group); used to filter eligible
|
|
9
|
+
/// token IDs on the tier-scoped path.
|
|
7
10
|
/// @custom:member token The reward token being vested.
|
|
8
11
|
/// @custom:member distributable The reward amount assigned to the round.
|
|
9
12
|
/// @custom:member totalStakeAmount The total checkpointed stake sharing the round's rewards.
|
|
@@ -12,6 +15,8 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
12
15
|
/// @custom:member snapshotBlock The block used for historical stake and ownership lookups.
|
|
13
16
|
struct JBVestContext {
|
|
14
17
|
address hook;
|
|
18
|
+
uint256 groupId;
|
|
19
|
+
uint256[] tierIds;
|
|
15
20
|
IERC20 token;
|
|
16
21
|
uint256 distributable;
|
|
17
22
|
uint256 totalStakeAmount;
|
|
@@ -5,12 +5,14 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
5
5
|
|
|
6
6
|
/// @notice Tracks a Revnet loan collateralized by one token ID's vesting rewards.
|
|
7
7
|
/// @custom:member hook The hook the token ID belongs to.
|
|
8
|
+
/// @custom:member groupId The reward group whose vesting rewards are collateralized (0 = the default group).
|
|
8
9
|
/// @custom:member tokenId The token ID whose vesting rewards are collateralized.
|
|
9
10
|
/// @custom:member token The revnet reward token used as loan collateral.
|
|
10
11
|
/// @custom:member vestingDataCount The vesting-entry boundary collateralized by the loan.
|
|
11
12
|
/// @custom:member collateralCount The amount of vesting rewards collateralized.
|
|
12
13
|
struct JBVestingLoan {
|
|
13
14
|
address hook;
|
|
15
|
+
uint256 groupId;
|
|
14
16
|
uint256 tokenId;
|
|
15
17
|
IERC20 token;
|
|
16
18
|
uint48 vestingDataCount;
|