Skip to content
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

SM-386 #185

Merged
merged 3 commits into from
Aug 6, 2024
Merged
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
14 changes: 14 additions & 0 deletions contracts/payments/IRewardsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ interface IRewardsManager {
uint256[] calldata cycles
) external view returns (uint256[] memory);

function getClaim(address node, address user, uint256 cycle) external view returns (uint256);

function getUnclaimedReward(
address node,
address user,
uint256 cycle
) external view returns (uint256);

function getUnclaimedRewards(
address node,
address user,
uint256[] calldata cycles
) external view returns (uint256[] memory);

function getUnclaimedNodeCommission(address node) external view returns (uint256);

function incrementRewardPool(address node, uint256 amount) external;
Expand Down
30 changes: 26 additions & 4 deletions contracts/payments/RewardsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,28 @@ contract RewardsManager is IRewardsManager, Initializable, AccessControl {
return rewardPools[node][cycle];
}

function getUnclaimedReward(address node, address user, uint256 cycle) external view returns (uint256) {
return _getUnclaimedReward(node, user, cycle);
}

function getUnclaimedRewards(address node, address user, uint256[] calldata cycles) external view returns (uint256[] memory) {
uint256 [] memory unclaimedRewards = new uint256[](cycles.length);

for (uint256 i = 0; i < cycles.length; i++) {
unclaimedRewards[i] = _getUnclaimedReward(node, user, cycles[i]);
}

return unclaimedRewards;
}

function _getUnclaimedReward(address node, address user, uint256 cycle) internal view returns (uint256) {
if (claims[node][user][cycle]) {
return 0;
}

return _getClaim(node, user, cycle);
}

function getClaim(address node, address user, uint256 cycle) external view returns (uint256) {
return _getClaim(node, user, cycle);
}
Expand All @@ -157,10 +179,6 @@ contract RewardsManager is IRewardsManager, Initializable, AccessControl {
uint256 claimAmount = (rewardPools[node][cycle] * userRewardCycleStake) /
nodeRewardCycleStake;

if (user == node) {
claimAmount += unclaimedNodeCommission[node];
}

return claimAmount;
}

Expand Down Expand Up @@ -201,6 +219,10 @@ contract RewardsManager is IRewardsManager, Initializable, AccessControl {

uint256 claimAmount = _getClaim(node, msg.sender, cycle);

if (msg.sender == node) {
claimAmount += unclaimedNodeCommission[node];
}

if (claimAmount == 0) {
revert CannotClaimZeroAmount();
}
Expand Down
49 changes: 46 additions & 3 deletions test/paymets/rewardsManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ describe('Rewards Manager', () => {
'function getUnclaimedNodeCommission(address node) external view returns (uint256)',
'function incrementRewardPool(address node, uint256 amount) external',
'function claim(address node, uint256 cycle) external',
'function getClaim(address node, address user, uint256 cycle) external view returns (uint256)',
'function getUnclaimedReward(address node, address user, uint256 cycle) external view returns (uint256)',
'function getUnclaimedRewards(address node, address user, uint256[] cycles) external view returns (uint256[])',
];

const interfaceId = getInterfaceId(abi);
Expand Down Expand Up @@ -291,6 +294,14 @@ describe('Rewards Manager', () => {
await setTimeSinceStart(1000);

await testClaim(node1.getAddress(), user, 1, rewardAmount);

const unclaimedReward = await rewardsManager.getUnclaimedReward(
node1.getAddress(),
user.address,
1,
);

expect(unclaimedReward).to.equal(0);
});

it('can claim reward over multiple cycles', async () => {
Expand All @@ -308,6 +319,16 @@ describe('Rewards Manager', () => {
await setTimeSinceStart(cycle * 1000);
}

const unclaimedRewards = await rewardsManager.getUnclaimedRewards(
node1.getAddress(),
user.getAddress(),
cycles,
);

for (const [i, r] of unclaimedRewards.entries()) {
expect(r).to.be.eq(BigInt(i + 1) * rewardAmount);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
expect(r).to.be.eq(BigInt(i + 1) * rewardAmount);
expect(r).to.be.equal(BigInt(i + 1) * rewardAmount);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think .eq is not ambiguous at all

}

for (const cycle of cycles) {
await testClaim(
node1.getAddress(),
Expand Down Expand Up @@ -363,7 +384,15 @@ describe('Rewards Manager', () => {

await setTimeSinceStart(1000);

await testClaim(node1.getAddress(), node1, 1, rewardAmount / 2n);
const balance = await contracts.syloToken.balanceOf(node1.getAddress());

await rewardsManager.connect(node1).claim(node1.getAddress(), 1);

const balanceAfter = await contracts.syloToken.balanceOf(
node1.getAddress(),
);

expect(balanceAfter).to.equal(balance + rewardAmount / 2n);
});

it('can claim as node and stakee', async () => {
Expand All @@ -381,7 +410,15 @@ describe('Rewards Manager', () => {

await setTimeSinceStart(1000);

await testClaim(node1.getAddress(), node1, 1, rewardAmount);
const balance = await contracts.syloToken.balanceOf(node1.getAddress());

await rewardsManager.connect(node1).claim(node1.getAddress(), 1);

const balanceAfter = await contracts.syloToken.balanceOf(
node1.getAddress(),
);

expect(balanceAfter).to.equal(balance + rewardAmount);
});

it('claim is distributed between nodes and stakers', async () => {
Expand Down Expand Up @@ -501,9 +538,15 @@ describe('Rewards Manager', () => {
const balance = await contracts.syloToken.balanceOf(user);

const claim = await rewardsManager.getClaim(node, user.getAddress(), cycle);

expect(claim).to.equal(expectedIncrease);

const unclaimed = await rewardsManager.getUnclaimedReward(
node,
user.getAddress(),
cycle,
);
expect(unclaimed).to.equal(expectedIncrease);

await rewardsManager.connect(user).claim(node, cycle);

const balanceAfter = await contracts.syloToken.balanceOf(user);
Expand Down
Loading