Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(RewardsStreamerMP): introduce emergency mode and ability to leave #72

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

0x-r4bbit
Copy link
Collaborator

This adds a new emergency mode that can be enabled by the owner of the system. When in emergency mode, stakers or StakeVaults can leave the system immediately.

Closes #66

Checklist

Ensure you completed all of the steps below before submitting your pull request:

  • Added natspec comments?
  • Ran pnpm adorno?
  • Ran pnpm verify?

@3esmit
Copy link
Contributor

3esmit commented Oct 28, 2024

The ideal logic would be:

Stake Manager contains a flag which is read by Stake Vault. When this flag is true, Stake Vault just allows withdraw and Stake Manager wont accept any iteractions anymore.

@0x-r4bbit 0x-r4bbit force-pushed the feat/emergency-exit branch 2 times, most recently from d5888dd to 2f4b5a0 Compare October 29, 2024 12:33
This adds a new emergency mode that can be enabled by the owner of the
system. When in emergency mode, stakers or `StakeVault`s can leave the
system immediately.

Closes #66
@0x-r4bbit
Copy link
Collaborator Author

@3esmit So, the reason I've done it this way (StakeManager sets flag, and reverts accordingly in functions where necessary), is because the logic for preventing interaction with the manager should stay the same no matter what stakevault you interact with.

For example, if we upgrade StakeVault to a different version, we'd otherwise have to ensure that it reverts in functions where it should revert.

If we keep the revert logic in the StakeManager, that's one thing less to keep in mind.

--

Are there any other good reasons to have StakeVault explicitly check emergency mode first, before interacting?

Happy to make the necessary changes in that case, but right now I don't see how that would improve the state.

@0x-r4bbit
Copy link
Collaborator Author

I've updated this PR with a certora rule that ensures only view functions, ownable functions, trusted codehash functions and leave() are callable when in emergency mode

@@ -132,6 +135,27 @@ contract RewardsStreamerMP is IStakeManager, TrustedCodehashAccess, ReentrancyGu
account.accountRewardIndex = rewardIndex;
}

function leave() external onlyTrustedCodehash nonReentrant {
Copy link
Contributor

Choose a reason for hiding this comment

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

emergency mode should not have any complex logic. what happens if there is a problem, such as underflow, inside of _updateGlobalState() or _updateAccountMP()?

Emergency exit suppousedly should not process any storage or anything, just allow withdraws.

uint256 aliceInitialRewardBalance = rewardToken.balanceOf(vaults[alice]);

streamer.enableEmergencyMode();

Copy link
Contributor

Choose a reason for hiding this comment

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

To properly test emergency mode, cause the code to make a division by zero in the logic, or whatever unexpected fail.

There would be no reason in having an emergency mode for expected cases, that wouldnt be called emergency mode.


uint256 accountRewards = calculateAccountRewards(msg.sender);
if (accountRewards > 0) {
distributeRewards(msg.sender, accountRewards);
Copy link
Contributor

Choose a reason for hiding this comment

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

In contrast with emergency exits on real world, they are usually used when there is a fire in the building. In that case, you don't go grab all your stuff before leave, you just run for your life directly to the exit.

Account storage account = accounts[msg.sender];

if (account.stakedBalance > 0) {
_updateGlobalState();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why need to update global state if its not going being used anymore?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Needs Review
Development

Successfully merging this pull request may close these issues.

Allow accounts to exit the system
2 participants