Skip to content

Conversation

@Flocqst
Copy link
Contributor

@Flocqst Flocqst commented Jul 5, 2024

Remove escrow on inflationary rewards + Remove staking cooldown

@Flocqst Flocqst marked this pull request as ready for review July 16, 2024 16:53
@Flocqst Flocqst requested review from JaredBorders and etn0m July 16, 2024 16:53
@Flocqst Flocqst mentioned this pull request Jul 17, 2024
}
}

function _getRewardCompounding(address _account)
Copy link
Contributor

Choose a reason for hiding this comment

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

needs natspec. i am confused what this is supposed to do

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is called when compounding, basically it is doing the same as _getReward but without transfering because the rewards are staked right after this (can be staked immediatly after calling this (see _compound()).

Added natspec to specify this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, is there a difference to this vs. the code in _getReward other than transferring? I see duplicate code. I was thinking that this reward calculating logic would be shared between the two and getReward only has the distinction of transferring to the user.

ie.

getReward() {
    (kwenta, usdc) = _calculateReward()
    transfer kwenta
    transfer USDC
}

compound() {
    (kwenta, usdc) = _calculateReward()
    stake kwenta
    transfer USDC
}

_calculateReward() {
...
}

TLDR; we should be practicing DRY here to minimize room for error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored with a _processReward so that there is no duplicate logic

@Flocqst
Copy link
Contributor Author

Flocqst commented Aug 27, 2024

I've merged the 'Staking Cooldown Removal' feature into this branch and also pulled the USDC rewards from main branch. This PR should be the one that goes live with the KSX deployment.

Copy link
Contributor

@JaredBorders JaredBorders left a comment

Choose a reason for hiding this comment

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

Everything LGTM! Nice work

/// @author Originally inspired by SYNTHETIX RewardEscrow
/// @author Kwenta's RewardEscrow V1 by JaredBorders (jaredborders@proton.me), JChiaramonte7 (jeremy@bytecode.llc)
/// @author RewardEscrowV2 by tommyrharper (tom@zkconsulting.xyz)
/// @author RewardEscrowV2 by tommyrharper (tom@zkconsulting.xyz), Flocqst (florian@kwenta.io)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I would break each author up on separate lines

@Flocqst Flocqst changed the title 👷 Remove escrow on inflationary rewards 👷 KSX - Remove escrow on inflationary rewards and remove staking cooldown Sep 3, 2024
@notion-workspace
Copy link

@notion-workspace
Copy link

}
}

function _getRewardCompounding(address _account)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, is there a difference to this vs. the code in _getReward other than transferring? I see duplicate code. I was thinking that this reward calculating logic would be shared between the two and getReward only has the distinction of transferring to the user.

ie.

getReward() {
    (kwenta, usdc) = _calculateReward()
    transfer kwenta
    transfer USDC
}

compound() {
    (kwenta, usdc) = _calculateReward()
    stake kwenta
    transfer USDC
}

_calculateReward() {
...
}

TLDR; we should be practicing DRY here to minimize room for error.

@Flocqst Flocqst requested a review from etn0m September 11, 2024 13:07
whenNotPaused
updateReward(_account)
returns (uint256 reward)
returns (uint256 kwentaReward)
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't seem you're using kwentaReward outside of _processReward, but for consistency sake you should either return both kwenta and USDC reward as a tuple or return neither.

Copy link
Contributor

@cmontecoding cmontecoding left a comment

Choose a reason for hiding this comment

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

initial review of main contracts
looks pretty straight forward so far

uint256 public rewardPerTokenStored;

/// @inheritdoc IStakingRewardsV2
uint256 public cooldownPeriod;
Copy link
Contributor

Choose a reason for hiding this comment

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

are we redeploying staking v2 or upgrading? because im pretty sure if we upgrade this removal will brick everything


/// @notice represents the rewardPerToken
/// value the last time the staker calculated earned() rewards
mapping(address => uint256) public userRewardPerTokenPaid;
Copy link
Contributor

Choose a reason for hiding this comment

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

it wont let me comment a couple lines below for some reason but mapping(address => uint256) public userLastStakeTime; should be removed because we remove the use of it everywhere in the code


// emit reward claimed event and index account
emit RewardPaid(_account, reward);
emit RewardPaid(_account, kwentaReward);
Copy link
Contributor

Choose a reason for hiding this comment

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

the other event is called RewardPaidUSDC

this should be called RewardPaidKwenta to match

kwentaReward = rewards[_account];
if (kwentaReward > 0) {
// update state (first)
rewards[_account] = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

if transferKwenta is set to false meaning they want to compound their rewards then doesnt this line ruin that?

their rewards are set to 0 but they dont get transferred their kwenta, so next time this is called again (im assuming after they waited for it to compound in this contract), then their rewards will be 0 or close to 0 and therefore they lost their kwenta entirely?

if im understanding this correctly then this rewards[_account] = 0; line shouldnt apply if transferKwenta == false

Copy link
Contributor

Choose a reason for hiding this comment

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

oh upon further look, kwentaReward is extrapolating this value? and it hopefully gets relogged when calling _stake in _compound?

function _compound(address _account) internal {
_getReward(_account);
_stakeEscrow(_account, unstakedEscrowedBalanceOf(_account));
uint256 reward = _processReward(_account, _account, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

will reward be 0 here?

Copy link
Contributor

@cmontecoding cmontecoding left a comment

Choose a reason for hiding this comment

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

just reviewed all the tests. aside: i cant find where we explicitly test these new _processReward changes.

important: we need to test the upgrade from a current fork --> new deployment (much like how cc-vesting does it). this should be done before we upgrade to ensure everything will be good, especially storage slots.
this may be doable in stakingV2.upgrade.t.sol. if not then we might have to add a new file. this may be difficult because i think everthing (testing and upgrading) is baked together and deeply webbed

Get Reward On Behalf
//////////////////////////////////////////////////////////////*/

function test_getRewardOnBehalf() public {
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we remove this test and the accompanying fuzz test?

//////////////////////////////////////////////////////////////*/

function test_Get_Reward_And_Stake_On_Behalf() public {
function test_Get_Reward_On_Behalf() public {
Copy link
Contributor

Choose a reason for hiding this comment

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

its good that we are testing getReward() by itself now (im assuming we didnt before) but why are we just replacing the "on behalf" test? we no longer test getting the reward AND staking anymore

we should have both this test & the test_Get_Reward_And_Stake. not either or

Copy link
Contributor

Choose a reason for hiding this comment

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

this reminds me: where do we test getReward (at least the new changes)? cant find it


// move beyond cold period
vm.warp(block.timestamp + stakingRewardsV2.cooldownPeriod());
vm.warp(block.timestamp + 2 weeks);
Copy link
Contributor

Choose a reason for hiding this comment

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

how come we mostly remove the cooldown period in this test file but then sometimes we add back this warp forward 2 weeks?

rewardsUsdc = usdc.balanceOf(user1);
assertEq(rewards, expectedRewards);
assertApproxEqAbs(rewardsUsdc, expectedUsdcRewards, 10);
assertApproxEqAbs(rewardsUsdc, expectedUsdcRewards, 50);
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we change this from 10 to 50? does that make the assert less accurate?

i just tested this locally with 10 and it still passes

assertEq(2 ether + 1 weeks, stakingRewardsV2.balanceOf(user1));
assertEq(1 ether + 1 weeks, stakingRewardsV2.escrowedBalanceOf(user1));
assertEq(1 ether, stakingRewardsV2.escrowedBalanceOf(user1));
assertEq(0, rewardEscrowV2.unstakedEscrowedBalanceOf(user1));
Copy link
Contributor

@cmontecoding cmontecoding Oct 28, 2024

Choose a reason for hiding this comment

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

this test suite needs to also test that all the accessible storage slots are not bricked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants