{"componentChunkName":"component---src-pages-sips-sip-markdown-remark-frontmatter-sip-tsx","path":"/sips/sip-68/","result":{"data":{"markdownRemark":{"fileAbsolutePath":"/vercel/path0/content/sips/sip-68.md","frontmatter":{"sip":68,"sccp":null,"title":"Minor enhancements to StakingRewards.sol","network":"Ethereum","author":"Clinton Ennis (@hav-noms), Anton Jurisevic (@zyzek)","type":"Governance","proposal":null,"implementor":null,"release":null,"created":"2020-07-06T00:00:00.000Z","updated":null,"status":"Implemented"},"html":"<!--You can leave these HTML comments in your merged SIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. This is the suggested template for new SIPs. Note that an SIP number will be assigned by an editor. When opening a pull request to submit your SIP, please use an abbreviated title in the filename, `sip-draft_title_abbrev.md`. The title should be 44 characters or less.-->\n<h2 id=\"simple-summary\" style=\"position:relative;\"><a href=\"#simple-summary\" aria-label=\"simple summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Simple Summary</h2>\n<!--\"If you can't explain it simply, you don't understand it well enough.\" Simply describe the outcome the proposed changes intends to achieve. This should be non-technical and accessible to a casual community member.-->\n<p>The <code>StakingRewards</code> contracts for liquidity mining need some minor enhancements.</p>\n<h2 id=\"abstract\" style=\"position:relative;\"><a href=\"#abstract\" aria-label=\"abstract permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Abstract</h2>\n<!--A short (~200 word) description of the proposed change, the abstract should clearly describe the proposed change. This is what *will* be done if the SIP is implemented, not *why* it should be done or *how* it will be done. If the SIP proposes deploying a new contract, write, \"we propose to deploy a new contract that will do x\".-->\n<p>Enhancements include:</p>\n<ul>\n<li>Recover airdropped rewards tokens from other protocols such as BAL &#x26; CRV</li>\n<li>Ability to update the rewards duration</li>\n<li>Remove the redundant <code>LPTokenWrapper</code></li>\n<li>Refactor to set rewards and staking tokens via the constructor on deployment</li>\n<li>Adding <code>Pausable</code> and <code>notPaused</code> to stake() to prevent staking into deprecated pools</li>\n<li>Fix a potential overflow bug in the reward notification function</li>\n</ul>\n<h2 id=\"motivation\" style=\"position:relative;\"><a href=\"#motivation\" aria-label=\"motivation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Motivation</h2>\n<!--This is the problem statement. This is the *why* of the SIP. It should clearly explain *why* the current state of the protocol is inadequate.  It is critical that you explain *why* the change is needed, if the SIP proposes changing how something is calculated, you must address *why* the current calculation is inaccurate or wrong. This is not the place to describe how the SIP will address the issue!-->\n<h3 id=\"recover-airdropped-rewards-tokens-from-other-protocols-such-as-bal--crv\" style=\"position:relative;\"><a href=\"#recover-airdropped-rewards-tokens-from-other-protocols-such-as-bal--crv\" aria-label=\"recover airdropped rewards tokens from other protocols such as bal  crv permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recover airdropped rewards tokens from other protocols such as BAL &#x26; CRV</h3>\n<p>When providing liquidity to <a href=\"https://pools.balancer.exchange/#/\">Balancer</a> or <a href=\"https://www.curve.fi/susdv2/deposit\">Curve.fi</a> and you stake your LP tokens in the Synthetix <code>StakingRewards</code> contract you will also be eligible for BAL and CRV Liquidity Mining rewards also and potentially other AMMs in the future.</p>\n<p>This would include a <code>recoverERC20</code> function that is accessible by the owner only, the <a href=\"https://etherscan.io/address/protocoldao.snx.eth\">protocolDAO</a> and can recover any ERC20 except the staking and rewards tokens to protect the stakers that their LP tokens and their rewards tokens are not accessible by the owner. These additional LP rewards will then be distributed to the LP providers.</p>\n<h3 id=\"update-the-rewards-duration\" style=\"position:relative;\"><a href=\"#update-the-rewards-duration\" aria-label=\"update the rewards duration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Update the rewards duration</h3>\n<p>Synthetix often runs trials on Liquidity Mining. Right now the Rewards duration is 7 days hard coded. Allowing a configurable <code>rewardsDuration</code> means the sDAO can set the duration and supply the total duration rewards for the trial without having to send the rewards manually each week. i.e. the curve renBTC/sBTC/wBTC pool gets 10 BPT per week. Where the trial is 10 weeks we could have set the duration to 10 weeks and send all 100 BPT upfront and it will distribute for the full term of the trial.</p>\n<p>When a trial is complete the contract can either be shut down or wired into the Synthetix Inflationary supply via the Rewards Distribution contract where the <code>rewardsDuration</code> can be set back to 7 days and automatically receive SNX weekly. Similar to current LP SNX rewards incentives.</p>\n<h3 id=\"remove-the-redundant-lptoken-wrapper\" style=\"position:relative;\"><a href=\"#remove-the-redundant-lptoken-wrapper\" aria-label=\"remove the redundant lptoken wrapper permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Remove the redundant LPToken Wrapper</h3>\n<p>The <code>LPTokenWrapper</code> added additional complexity to the code without adding any additional benefits. To simplify the code we propose to remove it.</p>\n<h3 id=\"refactor-to-set-rewards-and-staking-tokens-via-the-constructor-on-deployment\" style=\"position:relative;\"><a href=\"#refactor-to-set-rewards-and-staking-tokens-via-the-constructor-on-deployment\" aria-label=\"refactor to set rewards and staking tokens via the constructor on deployment permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refactor to set rewards and staking tokens via the constructor on deployment</h3>\n<p>The staking and rewards tokens were hard coded addresses in each contract. Now that there are many of these on MAINNET and deploying almost 1 a week, instead of having to edit the code directly it is prefered to send the staking and rewards tokens as arguments to the constructor on contract creation.</p>\n<h3 id=\"pause-stake-when-rewards-completed\" style=\"position:relative;\"><a href=\"#pause-stake-when-rewards-completed\" aria-label=\"pause stake when rewards completed permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Pause stake when rewards completed</h3>\n<p>When a <code>StakingRewards</code> campaign has completed the contract needs to prevent anyone from staking into it. They won't accrue rewards and can cause blocking issues with inverse Synths that need to be rebalanced which need to be purged.\nAdding <code>Pausable.sol</code> and modifier <code>notPaused</code> to <code>stake()</code> will allow the admin to set <code>paused</code> to <code>true</code> preventing anyone from staking. <code>SelfDestructible</code> has not been implemented and given the amount of value in these contracts probably best not to implement.</p>\n<h3 id=\"potential-overflow-bug-fix\" style=\"position:relative;\"><a href=\"#potential-overflow-bug-fix\" aria-label=\"potential overflow bug fix permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Potential overflow bug fix</h3>\n<h4 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h4>\n<p>There is a multiplication overflow that can occur inside the rewardPerToken function, on <a href=\"https://github.com/Synthetixio/synthetix/blob/c4dd4413cbbd3c0b40dfee2f9119af2dcb6a82e5/contracts/StakingRewards.sol#L66\">line 66</a>:</p>\n<pre><code>lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply)\n</code></pre>\n<p>An overflow occurs whenever <code>rewardRate >= 2^256 / (10^18 * (lastTimeRewardApplicable() - lastUpdateTime))</code>.</p>\n<p>This can happen when the updateReward modifier is invoked, which will cause the following functions to revert:</p>\n<ul>\n<li><code>earned</code></li>\n<li><code>stake</code></li>\n<li><code>withdraw</code></li>\n<li><code>getReward</code></li>\n<li><code>exit</code></li>\n<li><code>notifyRewardAmount</code></li>\n</ul>\n<p>The reward rate is set inside <code>notifyRewardAmount</code>, if a value that is too large is provided to the function.\nOf particular note is that <code>notifyRewardAmount</code> is itself affected by this problem, which means that if the provided\nreward is incorrect, then the problem is unrecoverable.</p>\n<h4 id=\"solution\" style=\"position:relative;\"><a href=\"#solution\" aria-label=\"solution permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution</h4>\n<p>The <code>notifyRewardAmount</code> transaction should be reverted if a value greater than <code>2^256 / 10^18</code> is provided.\nAs an additional safety mechanism, this value will be required to be no greater than the remaining\nbalance of the rewards token in the contract. This will both prevent the overflow, and also provide an additional check\nthat the reward rate is being set to a value in the appropriate range (for example, no extra/missing zeroes).</p>\n<h4 id=\"details\" style=\"position:relative;\"><a href=\"#details\" aria-label=\"details permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Details</h4>\n<p>Specifically, this problem occurs when rewardRate is too high; it is set inside the <code>notifyRewardAmount</code> function on\nlines <a href=\"https://github.com/Synthetixio/synthetix/blob/c4dd4413cbbd3c0b40dfee2f9119af2dcb6a82e5/contracts/StakingRewards.sol#L114\">114</a> and <a href=\"https://github.com/Synthetixio/synthetix/blob/c4dd4413cbbd3c0b40dfee2f9119af2dcb6a82e5/contracts/StakingRewards.sol#L118\">118</a>.</p>\n<pre><code>rewardRate = floor(reward / rewardsDuration) = (reward - k) / rewardsDuration\n</code></pre>\n<p>for some <code>0 &#x3C;= k &#x3C; rewardsDuration</code>.</p>\n<p>For the bug to occur, we need:</p>\n<pre><code>(reward - k) / rewardsDuration >= 2^256 / (10^18 * (lastTimeRewardApplicable - lastUpdateTime))\nreward                         >= rewardsDuration * 2^256 / (10^18 * (lastTimeRewardApplicable - lastUpdateTime)) + k\n</code></pre>\n<p>Hence, we can ensure the bug does not occur if we force:</p>\n<pre><code>reward &#x3C; rewardsDuration * 2^256 / (10^18 * (lastTimeRewardApplicable - lastUpdateTime))\n</code></pre>\n<p>So we should constrain <code>reward</code> to be less than the minimum value of the RHS.</p>\n<p>The smallest possible value of <code>lastUpdateTime</code> is the block timestamp when <code>notifyRewardAmount</code> was last called.\nThe largest possible value of <code>lastTimeRewardApplicable</code> is <code>periodFinish</code>,\nand <code>periodFinish = notificationBlock.timestamp + rewardsDuration</code> (<a href=\"https://github.com/Synthetixio/synthetix/blob/c4dd4413cbbd3c0b40dfee2f9119af2dcb6a82e5/contracts/StakingRewards.sol#L121\">line 121</a>).\nPutting these together we have:</p>\n<pre><code>(lastTimeRewardApplicable - lastUpdateTime) &#x3C;= rewardsDuration\n</code></pre>\n<p>Ergo, we need:</p>\n<pre><code>reward &#x3C; rewardsDuration * 2^256 / (10^18 * rewardsDuration)\n\t                     = 2^256 / 10^18\n</code></pre>\n<p>So the problem will not emerge whenever we require</p>\n<pre><code>    reward &#x3C; uint(-1) / UNIT\n</code></pre>\n<h3 id=\"technical-specification\" style=\"position:relative;\"><a href=\"#technical-specification\" aria-label=\"technical specification permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Technical Specification</h3>\n<!--The technical specification should outline the public API of the changes proposed. That is, changes to any of the interfaces Synthetix currently exposes or the creations of new ones.-->\n<ul>\n<li>Add  <code>recoverERC20</code> and <code>setRewardsDuration</code> that have <code>onlyOwner</code> modifiers.</li>\n<li><code>constructor</code> to take <code>_rewardsToken</code> &#x26; <code>_stakingToken</code> as arguments</li>\n<li>Refactor to remove the <code>LPTokenWrapper</code> contract. The original implementation to not include this.</li>\n<li>Revert the <code>notifyRewardAmount</code> transaction if the computer reward rate would pay out more than the balance of the contract over the reward period.</li>\n<li>Inherit the <code>Pausable.sol</code> contract and add modifier <code>notPaused</code> to <code>stake()</code></li>\n</ul>\n<h3 id=\"test-cases\" style=\"position:relative;\"><a href=\"#test-cases\" aria-label=\"test cases permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test Cases</h3>\n<!--Test cases for an implementation are mandatory for SIPs but can be included with the implementation..-->\n<ul>\n<li>External Rewards Recovery\n<ul>\n<li>only owner can call recoverERC20</li>\n<li>should revert if recovering staking token</li>\n<li>should revert if recovering rewards token (SNX)</li>\n<li>should revert if recovering the SNX Proxy</li>\n<li>should retrieve external token from StakingRewards and reduce contracts balance</li>\n<li>should retrieve external token from StakingRewards and increase owners balance</li>\n<li>should emit RewardsDurationUpdated event</li>\n</ul>\n</li>\n<li>setRewardsDuration\n<ul>\n<li>should increase rewards duration</li>\n<li>should emit RewardsDurationUpdated event</li>\n<li>should revert when setting setRewardsDuration before the period has finished</li>\n<li>should distribute rewards</li>\n</ul>\n</li>\n<li>Constructor &#x26; Settings\n<ul>\n<li>should set rewards token on constructor</li>\n<li>should staking token on constructor</li>\n</ul>\n</li>\n<li>Pausable\n<ul>\n<li>should revert when stake is called when paused is true</li>\n</ul>\n</li>\n<li>Overflow bugfix\n<ul>\n<li>should revert <code>notifyRewardAmount</code> if reward is greater than the contract balance</li>\n<li>should revert <code>notifyRewardAmount</code> if reward plus any leftover from the previous period is greater than the contract balance</li>\n<li>should not revert <code>notifyRewardAmount</code> if reward is equal to the contract balance</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"configurable-values-via-sccp\" style=\"position:relative;\"><a href=\"#configurable-values-via-sccp\" aria-label=\"configurable values via sccp permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configurable Values (Via SCCP)</h3>\n<!--Please list all values configurable via SCCP under this implementation.-->\n<p>Please list all values configurable via SCCP under this implementation.</p>\n<h2 id=\"copyright\" style=\"position:relative;\"><a href=\"#copyright\" aria-label=\"copyright permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Copyright</h2>\n<p>Copyright and related rights waived via <a href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0</a>.</p>"}},"pageContext":{"id":"366928d5-9d06-52ef-919c-418efa521770","frontmatter__sip":68,"__params":{"frontmatter__sip":"68"}}},"staticQueryHashes":[]}