Skip to content

Commit

Permalink
Merge pull request #10 from Synthetixio/drop-duration-as-input
Browse files Browse the repository at this point in the history
Drop duration as input in notifyRewards
  • Loading branch information
jacko125 authored Feb 10, 2020
2 parents 7d1ffb2 + d9056eb commit 53df522
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 20 deletions.
2 changes: 1 addition & 1 deletion contracts/IRewardDistributionRecipient.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "@openzeppelin/contracts/ownership/Ownable.sol";
contract IRewardDistributionRecipient is Ownable {
address rewardDistribution;

function notifyRewardAmount(uint256 reward, uint256 duration) external;
function notifyRewardAmount(uint256 reward) external;

modifier onlyRewardDistribution() {
require(_msgSender() == rewardDistribution, "Caller is not reward distribution");
Expand Down
15 changes: 8 additions & 7 deletions contracts/Unipool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@ contract Unipool is LPTokenWrapper, IRewardDistributionRecipient {

IERC20 public snx = IERC20(0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F);

uint256 public constant DURATION = 7 days;

uint256 public periodFinish = 0;
uint256 public rewardRate = 0;
uint256 public lastUpdateTime;
uint256 public rewardPerTokenStored;
mapping(address => uint256) public userRewardPerTokenPaid;
mapping(address => uint256) public rewards;

event RewardAdded(uint256 reward, uint256 duration);
event RewardAdded(uint256 reward);
event Staked(address indexed user, uint256 amount);
event Withdrawn(address indexed user, uint256 amount);
event RewardPaid(address indexed user, uint256 reward);
Expand Down Expand Up @@ -110,17 +112,16 @@ contract Unipool is LPTokenWrapper, IRewardDistributionRecipient {
}
}

// Duration is the time diff from (now - when snx rewards will be mintable again) to handle slippage in minting
function notifyRewardAmount(uint256 reward, uint256 duration) external onlyRewardDistribution updateReward(address(0)) {
function notifyRewardAmount(uint256 reward) external onlyRewardDistribution updateReward(address(0)) {
if (block.timestamp >= periodFinish) {
rewardRate = reward.div(duration);
rewardRate = reward.div(DURATION);
} else {
uint256 remaining = periodFinish.sub(block.timestamp);
uint256 leftover = remaining.mul(rewardRate);
rewardRate = reward.add(leftover).div(duration);
rewardRate = reward.add(leftover).div(DURATION);
}
lastUpdateTime = block.timestamp;
periodFinish = block.timestamp.add(duration);
emit RewardAdded(reward, duration);
periodFinish = block.timestamp.add(DURATION);
emit RewardAdded(reward);
}
}
29 changes: 17 additions & 12 deletions test/Unipool.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const Snx = artifacts.require('SnxMock');
const Unipool = artifacts.require('UnipoolMock');

async function timeIncreaseTo (seconds) {
const delay = 1000 - new Date().getMilliseconds();
const delay = 10 - new Date().getMilliseconds();
await new Promise(resolve => setTimeout(resolve, delay));
await time.increaseTo(seconds);
}
Expand Down Expand Up @@ -66,7 +66,7 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {

it('Two stakers with the same stakes wait 1 w', async function () {
// 72000 SNX per week for 3 weeks
await this.pool.notifyRewardAmount(web3.utils.toWei('216000'), time.duration.weeks(3), { from: wallet1 });
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });

expect(await this.pool.rewardPerToken()).to.be.bignumber.almostEqualDiv1e18('0');
expect(await this.pool.earned(wallet1)).to.be.bignumber.equal('0');
Expand All @@ -87,8 +87,8 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {
});

it('Two stakers with the different (1:3) stakes wait 1 w', async function () {
// 72000 SNX per week for 3 weeks
await this.pool.notifyRewardAmount(web3.utils.toWei('216000'), time.duration.weeks(3), { from: wallet1 });
// 72000 SNX per week
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });

expect(await this.pool.rewardPerToken()).to.be.bignumber.almostEqualDiv1e18('0');
expect(await this.pool.balanceOf(wallet1)).to.be.bignumber.equal('0');
Expand Down Expand Up @@ -116,8 +116,8 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {
// 3x: +--------+ = 0k for 1w + 54k for 2w
//

// 72000 SNX per week for 3 weeks
await this.pool.notifyRewardAmount(web3.utils.toWei('216000'), time.duration.weeks(3), { from: wallet1 });
// 72000 SNX per week
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });

await this.pool.stake(web3.utils.toWei('1'), { from: wallet1 });

Expand All @@ -129,7 +129,11 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {
expect(await this.pool.earned(wallet1)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('72000'));
expect(await this.pool.earned(wallet2)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('0'));

await timeIncreaseTo(this.started.add(time.duration.weeks(2)));
// Forward to week 3 and notifyReward weekly
for (let i = 1; i < 3; i++) {
await timeIncreaseTo(this.started.add(time.duration.weeks(i + 1)));
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });
}

expect(await this.pool.rewardPerToken()).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('90000'));
expect(await this.pool.earned(wallet1)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('90000'));
Expand All @@ -144,7 +148,7 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {
//

// 72000 SNX per week for 3 weeks
await this.pool.notifyRewardAmount(web3.utils.toWei('216000'), time.duration.weeks(3), { from: wallet1 });
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });

await this.pool.stake(web3.utils.toWei('1'), { from: wallet1 });
await this.pool.stake(web3.utils.toWei('3'), { from: wallet2 });
Expand All @@ -157,6 +161,7 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {
expect(await this.pool.earned(wallet1)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('18000'));
expect(await this.pool.earned(wallet2)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('54000'));

await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });
await timeIncreaseTo(this.started.add(time.duration.weeks(2)));

expect(await this.pool.rewardPerToken()).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('26000')); // 18k + 8k
Expand All @@ -166,6 +171,7 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {

await this.pool.exit({ from: wallet2 });

await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });
await timeIncreaseTo(this.started.add(time.duration.weeks(3)));

expect(await this.pool.rewardPerToken()).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('38000')); // 18k + 8k + 12k
Expand All @@ -176,7 +182,7 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {

it('One staker on 2 durations with gap', async function () {
// 72000 SNX per week for 1 weeks
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), time.duration.weeks(1), { from: wallet1 });
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });

await this.pool.stake(web3.utils.toWei('1'), { from: wallet1 });

Expand All @@ -186,7 +192,7 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {
expect(await this.pool.earned(wallet1)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('72000'));

// 72000 SNX per week for 1 weeks
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), time.duration.weeks(1), { from: wallet1 });
await this.pool.notifyRewardAmount(web3.utils.toWei('72000'), { from: wallet1 });

await timeIncreaseTo(this.started.add(time.duration.weeks(3)));

Expand All @@ -195,9 +201,8 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4]) {
});

it('Notify Reward Amount from mocked distribution to 10,000', async function () {

// 10000 SNX per week for 1 weeks
await this.pool.notifyRewardAmount(web3.utils.toWei('10000'), time.duration.weeks(1), { from: wallet1 });
await this.pool.notifyRewardAmount(web3.utils.toWei('10000'), { from: wallet1 });

expect(await this.pool.rewardPerToken()).to.be.bignumber.almostEqualDiv1e18('0');
expect(await this.pool.balanceOf(wallet1)).to.be.bignumber.equal('0');
Expand Down

0 comments on commit 53df522

Please sign in to comment.