Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Commit

Permalink
Transferring KEEP rewards in notifyRewardAmount
Browse files Browse the repository at this point in the history
Instead of adding approveAndCall function, it is cleaner to add a
'transfer' function in notifyRewardAmount which has to be called anyway
by the reward distributor. Reward distributor in our case is escrow's
beneficiary which is going to be set by PhasedEscrow contract.

In tests, the role of PhasedEscrow beneficiary takes rewardDistribution
account. We need to transfer funds from KEEP token owner to rewardDistribution
address first, before we can call notifyRewardAmount().
  • Loading branch information
dimpar committed Dec 18, 2020
1 parent 0e2e07c commit b148edc
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 48 deletions.
17 changes: 4 additions & 13 deletions solidity/contracts/LPRewards.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/

/// @notice These contracts reward users for adding liquidity to Uniswap https://uniswap.org/
/// @dev These contracts were obtained from Synthetix and added some minor changes.
/// These contracts reward users for adding liquidity to Uniswap https://uniswap.org/
/// These contracts were obtained from Synthetix and added some minor changes.
/// You can find the original contracts here:
/// https://etherscan.io/address/0x48d7f315fedcad332f68aafa017c7c158bc54760#code

Expand Down Expand Up @@ -143,6 +143,8 @@ contract LPRewards is LPTokenWrapper, IRewardDistributionRecipient {
onlyRewardDistribution
updateReward(address(0))
{
keepToken.safeTransferFrom(msg.sender, address(this), reward);

if (block.timestamp >= periodFinish) {
rewardRate = reward.div(DURATION);
} else {
Expand Down Expand Up @@ -181,17 +183,6 @@ contract LPRewards is LPTokenWrapper, IRewardDistributionRecipient {
.add(rewards[account]);
}

function receiveApproval(
address from,
uint256 value,
address token,
bytes memory
) public {
require(IERC20(token) == keepToken, "Unsupported token");

keepToken.safeTransferFrom(from, address(this), value);
}

// stake visibility is public as overriding LPTokenWrapper's stake() function
function stake(uint256 amount) public updateReward(msg.sender) {
require(amount > 0, "Cannot stake 0");
Expand Down
81 changes: 46 additions & 35 deletions solidity/test/LPRewardsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,43 @@ const chai = require("chai")
chai.use(require("bn-chai")(BN))
const expect = chai.expect

describe.only("LPRewards", () => {
describe("LPRewards", () => {
const tokenDecimalMultiplier = web3.utils.toBN(10).pow(web3.utils.toBN(18))
const allocationForDistribution = web3.utils
.toBN(10000000)
.mul(tokenDecimalMultiplier)

const staker1 = accounts[1]
const staker2 = accounts[2]
const rewardDistribution = accounts[3]
const wrappedTokenOwner = accounts[4]
const lpRewardsOwner = accounts[5]
const keepTokenOwner = accounts[6]

let keepToken
let lpRewards
let wrappedToken
let rewardDistribution
let staker1
let staker2
let keepTokenContractOwner
let wrappedTokenContractOwner
let lpRewardsContractOwner

before(async () => {
staker1 = accounts[1]
staker2 = accounts[2]
keepTokenContractOwner = accounts[3]
wrappedTokenContractOwner = accounts[4]
lpRewardsContractOwner = accounts[5]
rewardDistribution = accounts[6]

keepToken = await KeepToken.new({from: keepTokenContractOwner})
keepToken = await KeepToken.new({from: keepTokenOwner})
// This is a "Pair" Uniswap Token which is created here:
// https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.sol#L23
//
// There are 3 addresses for the following pairs:
// - KEEP/ETH (https://info.uniswap.org/pair/0xe6f19dab7d43317344282f803f8e8d240708174a)
// - TBTC/ETH (https://info.uniswap.org/pair/0x854056fd40c1b52037166285b2e54fee774d33f6)
// - KEEP/TBTC (https://info.uniswap.org/pair/0x38c8ffee49f286f25d25bad919ff7552e5daf081)
wrappedToken = await WrappedToken.new({from: wrappedTokenContractOwner})
lpRewards = await LPRewards.new(keepToken.address, wrappedToken.address, {from: lpRewardsContractOwner})
wrappedToken = await WrappedToken.new({from: wrappedTokenOwner})
lpRewards = await LPRewards.new(keepToken.address, wrappedToken.address, {
from: lpRewardsOwner,
})

await keepToken.approve(rewardDistribution, allocationForDistribution, {
from: keepTokenOwner,
})
await keepToken.transfer(rewardDistribution, allocationForDistribution, {
from: keepTokenOwner,
})
})

beforeEach(async () => {
Expand All @@ -53,12 +59,19 @@ describe.only("LPRewards", () => {
})

describe("tokens allocation", () => {
it("should successfully allocate KEEP tokens via receiveApproval function", async () => {
it("should successfully transfer KEEP and notify LPRewards contract on rewards distribution", async () => {
const initialBalance = await keepToken.balanceOf(lpRewards.address)
const rewards = web3.utils.toBN(1042).mul(tokenDecimalMultiplier)

const rewards = web3.utils.toBN(1000042).mul(tokenDecimalMultiplier)

await keepToken.approveAndCall(lpRewards.address, rewards, "0x0", {from: keepTokenContractOwner})
await lpRewards.setRewardDistribution(rewardDistribution, {
from: lpRewardsOwner,
})
await keepToken.approve(lpRewards.address, rewards, {
from: rewardDistribution,
})
await lpRewards.notifyRewardAmount(rewards, {
from: rewardDistribution,
})

const finalBalance = await keepToken.balanceOf(lpRewards.address)
expect(finalBalance).to.eq.BN(rewards.add(initialBalance))
Expand Down Expand Up @@ -133,18 +146,14 @@ describe.only("LPRewards", () => {
.toBN(10000)
.mul(tokenDecimalMultiplier)

await fundKEEPReward(lpRewards.address, keepRewards)
await mintAndApproveWrappedTokens(
wrappedToken,
lpRewards.address,
staker1,
wrappedTokenStakerBallance
)

await lpRewards.setRewardDistribution(rewardDistribution, {from: lpRewardsContractOwner})
await lpRewards.notifyRewardAmount(keepRewards, {
from: rewardDistribution,
})
await fundAndNotifyLPRewards(lpRewards.address, keepRewards)

const wrappedTokensToStake = web3.utils
.toBN(2000)
Expand Down Expand Up @@ -184,18 +193,14 @@ describe.only("LPRewards", () => {
.toBN(10000)
.mul(tokenDecimalMultiplier)

await fundKEEPReward(lpRewards.address, keepAllocated)
await mintAndApproveWrappedTokens(
wrappedToken,
lpRewards.address,
staker1,
wrappedTokenStakerBallance
)

await lpRewards.setRewardDistribution(rewardDistribution, {from: lpRewardsContractOwner})
await lpRewards.notifyRewardAmount(keepAllocated, {
from: rewardDistribution,
})
await fundAndNotifyLPRewards(lpRewards.address, keepAllocated)

const wrappedTokensToStake = web3.utils
.toBN(2000)
Expand All @@ -221,15 +226,21 @@ describe.only("LPRewards", () => {
})
})

async function fundAndNotifyLPRewards(address, amount) {
await lpRewards.setRewardDistribution(rewardDistribution, {
from: lpRewardsOwner,
})
await keepToken.approve(address, amount, {from: rewardDistribution})
await lpRewards.notifyRewardAmount(amount, {
from: rewardDistribution,
})
}

async function mintAndApproveWrappedTokens(token, address, staker, amount) {
await token.mint(staker, amount)
await token.approve(address, amount, {from: staker})
}

async function fundKEEPReward(address, amount) {
await keepToken.approveAndCall(address, amount, "0x0", {from: keepTokenContractOwner})
}

async function timeIncreaseTo(seconds) {
const delay = 10 - new Date().getMilliseconds()
await new Promise((resolve) => setTimeout(resolve, delay))
Expand Down

0 comments on commit b148edc

Please sign in to comment.