From 830bc856be2cb56f8ded16832da80104a399b4b1 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 31 Jan 2022 14:26:23 +0100 Subject: [PATCH] Update the tBTC rewards page Adjust the tBTC rewards page to the proposal[1] that extends stakedrop rewards for an additional 4 months. We will have two more allocations so to simplify calculating the period of the reward we hardcoded the `merkleRoot` in the `ExtendedECDSARewards.intervalsDates` array. After generating the new merkle tree we must add the `merkleRoot` hash to a given interval. Ref: [1]: https://forum.keep.network/t/proposal-to-extend-stakedrop-rewards-for-an-additional-4-months/351 --- .../src/pages/rewards/TBTCRewardsPage.jsx | 15 ++- solidity-v1/dashboard/src/services/rewards.js | 9 +- .../dashboard/src/utils/rewardsHelper.js | 111 ++++++++++++++++-- 3 files changed, 115 insertions(+), 20 deletions(-) diff --git a/solidity-v1/dashboard/src/pages/rewards/TBTCRewardsPage.jsx b/solidity-v1/dashboard/src/pages/rewards/TBTCRewardsPage.jsx index 7fe3f713f8..db290f1a27 100644 --- a/solidity-v1/dashboard/src/pages/rewards/TBTCRewardsPage.jsx +++ b/solidity-v1/dashboard/src/pages/rewards/TBTCRewardsPage.jsx @@ -8,7 +8,7 @@ import { SubmitButton } from "../../components/Button" // import ProgressBar from "../../components/ProgressBar" import Timer from "../../components/Timer" import TBTCRewardsDataTable from "../../components/TBTCRewardsDataTable" -import { ECDSARewardsHelper } from "../../utils/rewardsHelper" +import { ExtendedECDSARewardsHelper } from "../../utils/rewardsHelper" import { useWeb3Address } from "../../components/WithWeb3Context" import { TokenAmountSkeleton, @@ -22,9 +22,9 @@ import EmptyStatePage from "./EmptyStatePage" const TBTCRewardsPage = () => { const dispatch = useDispatch() const yourAddress = useWeb3Address() - const currentIntervalEndOf = ECDSARewardsHelper.intervalEndOf( - ECDSARewardsHelper.currentInterval - ).unix() + const currentIntervalEndOf = ExtendedECDSARewardsHelper.intervalEndOf( + ExtendedECDSARewardsHelper.currentInterval + ) const { ecdsaAvailableRewardsFetching, @@ -78,7 +78,8 @@ const TBTCRewardsPage = () => { const RewardsOverview = ({ balance, isBalanceFetching, withdrawRewards }) => { const remainingPeriods = - ECDSARewardsHelper.intervals - ECDSARewardsHelper.currentInterval + ExtendedECDSARewardsHelper.intervals - + ExtendedECDSARewardsHelper.currentInterval return (
@@ -93,7 +94,9 @@ const RewardsOverview = ({ balance, isBalanceFetching, withdrawRewards }) => {
current rewards period
- {ECDSARewardsHelper.periodOf(ECDSARewardsHelper.currentInterval)} + {ExtendedECDSARewardsHelper.periodOf( + ExtendedECDSARewardsHelper.currentInterval + )}
diff --git a/solidity-v1/dashboard/src/services/rewards.js b/solidity-v1/dashboard/src/services/rewards.js index 365a267515..a4a5a8f07c 100644 --- a/solidity-v1/dashboard/src/services/rewards.js +++ b/solidity-v1/dashboard/src/services/rewards.js @@ -1,6 +1,6 @@ import web3Utils from "web3-utils" import { ContractsLoaded, getContractDeploymentBlockNumber } from "../contracts" -import { ECDSARewardsHelper } from "../utils/rewardsHelper" +import { ECDSAPeriodOfResolver } from "../utils/rewardsHelper" import { add } from "../utils/arithmetics.utils" import { isEmptyArray } from "../utils/array.utils" import rewardsData from "../rewards-allocation/rewards.json" @@ -85,7 +85,7 @@ export const fetchECDSAAvailableRewards = async (operators) => { merkleRoot, interval, amount: web3Utils.toBN(operatorClaim.amount).toString(), - rewardsPeriod: ECDSARewardsHelper.periodOf(interval), + rewardsPeriod: ECDSAPeriodOfResolver.resolve(interval, merkleRoot), }) } } @@ -108,11 +108,12 @@ export const fetchECDSAClaimedRewards = async (operators) => { filter: { operator: operators }, }) ).map((event) => { - const intervalOf = merkleRoots.indexOf(event.returnValues.merkleRoot) + const merkleRoot = event.returnValues.merkleRoot + const intervalOf = merkleRoots.indexOf(merkleRoot) return { ...event.returnValues, - rewardsPeriod: ECDSARewardsHelper.periodOf(intervalOf), + rewardsPeriod: ECDSAPeriodOfResolver.resolve(intervalOf, merkleRoot), } }) } diff --git a/solidity-v1/dashboard/src/utils/rewardsHelper.js b/solidity-v1/dashboard/src/utils/rewardsHelper.js index 5b910f2570..1cd254c289 100644 --- a/solidity-v1/dashboard/src/utils/rewardsHelper.js +++ b/solidity-v1/dashboard/src/utils/rewardsHelper.js @@ -2,35 +2,54 @@ import moment from "moment" import BigNumber from "bignumber.js" import { formatDate } from "../utils/general.utils" -class RewardsHelper { +class RewardsInterface { + intervalStartOf = (interval) => { + throw Error("Implement first") + } + + intervalEndOf = (interval) => { + throw Error("Implement first") + } + + get currentInterval() { + throw Error("Implement first") + } + + periodOf = (interval) => { + const startDate = formatDate(moment.unix(this.intervalStartOf(interval))) + const endDate = formatDate(moment.unix(this.intervalEndOf(interval))) + + return `${startDate} - ${endDate}` + } +} + +class RewardsHelper extends RewardsInterface { firstIntervalStart = 0 termLength = 0 minimumKeepsPerInterval = 0 constructor(_firstIntervalStart, _termLength, _minimumKeepsPerInterval) { + super() this.firstIntervalStart = _firstIntervalStart this.termLength = _termLength this.minimumKeepsPerInterval = _minimumKeepsPerInterval - this.currentInterval = Math.floor( - (moment().unix() - this.firstIntervalStart) / this.termLength - ) } intervalStartOf = (interval) => { return moment .unix(this.firstIntervalStart) .add(interval * this.termLength, "seconds") + .unix() } intervalEndOf = (interval) => { return this.intervalStartOf(interval + 1) } - periodOf = (interval) => { - const startDate = formatDate(this.intervalStartOf(interval)) - const endDate = formatDate(this.intervalEndOf(interval)) - - return `${startDate} - ${endDate}` + get currentInterval() { + return Math.floor( + (moment().unix() - this.firstIntervalStart) / this.termLength + ) } } @@ -104,9 +123,81 @@ class ECDSARewards extends RewardsHelper { } } +class ExtendedECDSARewards extends RewardsInterface { + // https://forum.keep.network/t/proposal-to-extend-stakedrop-rewards-for-an-additional-4-months/351 + intervalsDates = [ + // 2021-12-03 -> 2021-12-21 + { + start: 1638489600, + end: 1640044800, + merkleRoot: + "0x83f51475c210aff536867981fcc803ace41787a6b0b256fced9802ec37127dd7", + }, + // 2021-12-21 -> 2022-01-22 + { + start: 1640044800, + end: 1642809600, + merkleRoot: + "0xdc8026bc52c1d200477e8aa8d374e934e57c79d1d0c9fa65d121a8f6607987b0", + }, + // 2021-01-22 -> 2022-02-22 + { start: 1642809600, end: 1645488000, merkleRoot: "" }, + // 2021-02-22 -> 2022-03-22 + { start: 1645488000, end: 1647907200, merkleRoot: "" }, + ] + + get currentInterval() { + const currentTimestamp = moment().unix() + const index = this.intervalsDates.findIndex( + (_) => _.start <= currentTimestamp && _.end >= currentTimestamp + ) + if (index < 0) return this.intervals + + return index + 1 + } + + get intervals() { + return this.intervalsDates.length + } + + intervalStartOf = (interval) => { + const _interval = interval - 1 + + if (_interval < 0) return this.intervalsDates[0].start + else if (_interval > this.intervalsDates.length) + return this.intervalsDates[this.intervalsDates.length - 1].start + + return this.intervalsDates[_interval].start + } + + intervalEndOf = (interval) => { + const _interval = interval - 1 + + if (_interval < 0) return this.intervalsDates[0].end + if (_interval > this.intervalsDates.length) + return this.intervalsDates[this.intervalsDates.length - 1].end + + return this.intervalsDates[_interval].end + } +} + const BeaconRewardsHelper = new BeaconRewards() const ECDSARewardsHelper = new ECDSARewards() +const ExtendedECDSARewardsHelper = new ExtendedECDSARewards() + +export class ECDSAPeriodOfResolver { + static resolve(interval, merkleRoot) { + const index = ExtendedECDSARewardsHelper.intervalsDates.findIndex( + (_) => _.merkleRoot === merkleRoot + ) + if (index >= 0) { + return ExtendedECDSARewardsHelper.periodOf(index + 1) + } + + return ECDSARewardsHelper.periodOf(interval) + } +} export default BeaconRewardsHelper -export { ECDSARewardsHelper } +export { ECDSARewardsHelper, ExtendedECDSARewardsHelper }