Skip to content

Commit 0aa6e0f

Browse files
committed
Restore reward eligibility by operator addrss
The off-chain client can monitor the reward eligibility and restore it when the time comes but it is easier for the client to use the operator address instead of the operator ID. Looking at the public API so far, the reward eligibility was getting restored using the address so it makes sense to have all other reward-eligibility-related functions use the operator address as well, for consistency.
1 parent b3fcb43 commit 0aa6e0f

3 files changed

Lines changed: 57 additions & 6 deletions

File tree

contracts/Rewards.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ contract Rewards {
7272
}
7373

7474
/// @notice Return whether the operator is eligible for rewards or not.
75-
function isEligibleForRewards(uint32 operator) public view returns (bool) {
75+
function isEligibleForRewards(uint32 operator) internal view returns (bool) {
7676
return operatorRewards[operator].ineligibleUntil == 0;
7777
}
7878

7979
/// @notice Return the time the operator's reward eligibility can be restored.
8080
function rewardsEligibilityRestorableAt(uint32 operator)
81-
public
81+
internal
8282
view
8383
returns (uint256)
8484
{
@@ -87,10 +87,10 @@ contract Rewards {
8787
return (uint256(until) + ineligibleOffsetStart);
8888
}
8989

90-
/// @notice Return whether the operator is able
91-
/// to restore their eligibility for rewards right away.
90+
/// @notice Return whether the operator is able to restore their eligibility
91+
/// for rewards right away.
9292
function canRestoreRewardEligibility(uint32 operator)
93-
public
93+
internal
9494
view
9595
returns (bool)
9696
{

contracts/SortitionPool.sol

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ contract SortitionPool is SortitionTree, Rewards, Ownable, IReceiveApproval {
137137
}
138138
}
139139

140+
/// @notice Set the given operators as ineligible for rewards.
141+
/// The operators can restore their eligibility at the given time.
140142
function setRewardIneligibility(uint32[] calldata operators, uint256 until)
141143
public
142144
onlyOwner
@@ -145,12 +147,40 @@ contract SortitionPool is SortitionTree, Rewards, Ownable, IReceiveApproval {
145147
emit IneligibleForRewards(operators, until);
146148
}
147149

150+
/// @notice Restores reward eligibility for the operator.
148151
function restoreRewardEligibility(address operator) public {
149152
uint32 id = getOperatorID(operator);
150153
Rewards.restoreEligibility(id);
151154
emit RewardEligibilityRestored(operator, id);
152155
}
153156

157+
/// @notice Returns whether the operator is eligible for rewards or not.
158+
function isEligibleForRewards(address operator) public view returns (bool) {
159+
uint32 id = getOperatorID(operator);
160+
return Rewards.isEligibleForRewards(id);
161+
}
162+
163+
/// @notice Returns the time the operator's reward eligibility can be restored.
164+
function rewardsEligibilityRestorableAt(address operator)
165+
public
166+
view
167+
returns (uint256)
168+
{
169+
uint32 id = getOperatorID(operator);
170+
return Rewards.rewardsEligibilityRestorableAt(id);
171+
}
172+
173+
/// @notice Returns whether the operator is able to restore their eligibility
174+
/// for rewards right away.
175+
function canRestoreRewardEligibility(address operator)
176+
public
177+
view
178+
returns (bool)
179+
{
180+
uint32 id = getOperatorID(operator);
181+
return Rewards.canRestoreRewardEligibility(id);
182+
}
183+
154184
/// @notice Returns the amount of rewards withdrawable for the given operator.
155185
function getAvailableRewards(address operator) public view returns (uint96) {
156186
uint32 id = getOperatorID(operator);

test/sortitionPoolTest.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,17 +378,38 @@ describe("SortitionPool", () => {
378378
expect(ineligibleReward).to.equal(200)
379379
})
380380

381-
it("sets operator ineligibility correctly", async () => {
381+
it("sets and restores operator eligibility correctly", async () => {
382382
await token.connect(deployer).mint(deployer.address, 1000)
383383
await pool.connect(owner).insertOperator(alice.address, 10000)
384384
await pool.connect(owner).insertOperator(bob.address, 20000)
385+
385386
const now = await helpers.time.lastBlockTime()
386387
const bobID = await pool.getOperatorID(bob.address)
388+
387389
await pool.connect(owner).setRewardIneligibility([bobID], now + 100)
388390

391+
await expect(await pool.isEligibleForRewards(bob.address)).to.be.false
392+
await expect(await pool.isEligibleForRewards(alice.address)).to.be.true
393+
394+
await expect(await pool.canRestoreRewardEligibility(bob.address)).to.be
395+
.false
396+
await expect(
397+
await pool.rewardsEligibilityRestorableAt(bob.address),
398+
).to.equal(now + 100)
399+
389400
await expect(
390401
pool.restoreRewardEligibility(bob.address),
391402
).to.be.revertedWith("Operator still ineligible")
403+
404+
// Ineligibility is set for a duration. Bob was ineligible for 100
405+
// seconds, so we move forward 101 seconds to allow us to make him
406+
// eligible again.
407+
await helpers.time.increaseTime(101)
408+
409+
await expect(await pool.canRestoreRewardEligibility(bob.address)).to.be
410+
.true
411+
await pool.restoreRewardEligibility(bob.address)
412+
await expect(await pool.isEligibleForRewards(bob.address)).to.be.true
392413
})
393414

394415
it("can set many operators ineligible", async () => {

0 commit comments

Comments
 (0)