Commit Graph

50 Commits

Author SHA1 Message Date
r4bbit
1304846f2c feat(Karma): add AccessControl to Karma
This commit introduces `AccessControl` capabilities to Karma. The reason this is done so that there can be multiple actors in the system with different privileges.

The main changes done here are:

- Introduce internal functions for most of the `Karma` specific logic (this is necessary to allow properly extending the contract's functionality via modifiers) later on
- Inherit AccessControlUpgradeable contract
- Introduce OPERATOR_ROLE next to the already provided DEFAULT_ADMIN_ROLE

This is an alternative solution to the PR in #209.
Instead of providing an upgrade version, this commit is a breaking
change as it introduces a storage layout conflict.

BREAKING CHANGE

This commit introduces a storage layout conflict.
Redeployment required.

Closes #207
2025-05-14 11:23:06 +02:00
r4bbit
05cccfc662 refactor(StakeManager): move lockUntil into StakeVault
Most of the reasoning has been discussed in #208.
Primarily what's happening here is:

- `StakeManager.VaultData.lockUntil` has been removed
- `StakeVault.lockUntil` has been introduced
- `StakeVault.updateLockUntil(uint256 value)` has been introduced
- `StakeVault.leave()` performs normal `leave()` action but keeps funds
  in vault if lockup period hasn't expired
- `StakeVault.withdrawFromVault()` has been introduced to withdraw
  remaining *stake* funds in vault

BREAKING CHANGE:

- `StakeManager.VaultData.lockUntil` has been removed
- `StakeVault.lockUntil` has been introduced
- `StakeVault.leave()` performs normal `leave()` action but keeps funds
  in vault if lockup period hasn't expired

Closes #208
2025-05-13 14:05:02 +02:00
r4bbit
801740f74f !refactor(RewardsStreamerMP): rename RewardsStreamerMP to StakeManager
This renames `RewardsStreamerMP` to `StakeManager`. The original name
only exists because the project has started with different versions of
the contract. Since the contract is no longer just dealing with MPs but
actually distributes rewards, it makes sense to make this the official
stake manager of the protocol.

**BREAKING CHANGE:**

- `RewardsStreamerMP` is now `StakeManager`
- `StakingManager__*` error selectors are now `StakeManager__*`
  selectors
2025-03-28 14:45:31 +01:00
r4bbit
7bd0c16872 !refactor(RewardsStreamerMP): remove VaultData.mpStaked
After doing somme work on merging `compound()` into `updateVault()`, we
noticed that both, `vault.mpStaked` and `vault.mpAccrued` are always
equal.

Therefore, we're removing `vault.mpStaked`.

BREAKING CHANGE:

- `VaultData.mpStaked` no longer exists, use `VaultData.mpAccrued`
instead.

- `Compound(address,uint256)` is now `VaultUpdated(address,uint256,uint256)`

- `AccountLeft(address)` is now `VaultLeft(address)`
2025-03-26 13:19:05 +01:00
Ricardo Guilherme Schmidt
8df475aab8 fix(StakeManager): Allow extending the lock after increasing stake to allow account reaching absolute max MP
fix(MultiplierPointMath): Fix helper function to correctly estimate avaliable lock time

chore(spec): remove additional field which does not exist anymore
2025-03-25 17:14:17 +01:00
r4bbit
2e01e0d03b refactor(RewardsStreamerMP): merge compound() with _updateVault()
This commit merges `compound()` into `_updateVault()` as there's no
reason not to update vault without compounding it.

This was discussed in #187.

BREAKING CHANGE: A couple of APIs have been removed or replaced.

-> inline _compound into _updateVault()
-> remove compond() in favor of updateVaultMP()
-> rename updateVaultMP() to updateVault()
-> rename compoundAccount() to updateAccount()

Closes #187
2025-03-25 16:09:04 +01:00
Andrea Franz
14eaf35091 test(certora): add rule to check Karma externalSupply is always <= totalDistributorAllocation 2025-03-20 16:28:45 +01:00
r4bbit
4fa3eb06e0 feat(RewardsStreamerMP): allow for staking multiple times with lock
This commit enables users to stake multiple times into the same vault
with a lock increase.

If their total lock increase goes beyond the maximum lock period,
staking will revert. In this case users will have to create a new vault.

Closes #152

Co-authored-by: Andrea Franz <andrea@gravityblast.com>
2025-03-19 15:36:55 +01:00
r4bbit
5e2dcbabd1 feat(RewardsStreamerMP): add function to compound all MPs for an account
Closes #175
2025-03-14 15:00:26 +01:00
Andrea Franz
4d10993cc9 chore(certora): add rule to test the sum of all distributors allocation 2025-03-11 13:25:00 +01:00
Andrea Franz
26926c1d5e test(certora): Karma.totalDistributorAllocation can only increase (#166) 2025-03-11 08:24:57 +01:00
r4bbit
828d65ad65 refactor(specs): exclude rule instead of including other rules 2025-03-07 15:05:27 +01:00
r4bbit
6c89793854 fix(certora): fix timeout on certora with specific config 2025-03-07 13:17:46 +01:00
Andrea Franz
50439be124 test(certora): ensure Karma owneable functions are callable only by the owner 2025-03-06 16:04:27 +01:00
Andrea Franz
7e30c0b718 test(certora): transfer not allowed in the Karma token 2025-03-06 11:51:40 +01:00
r4bbit
aa1addbfcd chore: downgrade to paris
We put `cancun` as evm version into the foundry toml by mistake and
ended up building on top of it with certain assumptions.

Turns out that the network we're deploying to does not support that
version so we have to compile with `paris`.

This however, also requires a downgrade of the open zeppelin libraries,
which in turn requires changes in our code base. Primarily related to
initialization of `OwnableUpgradeable` and upgrades via UUPSUpgradeable.

This commit makes all the necessary changes.
2025-03-05 11:47:30 +01:00
Andrea Franz
aa3442b577 feat(Karma): make karma upgradeable 2025-02-28 14:39:15 +01:00
Andrea Franz
ed3577f8c4 feat(Karma): allocate external rewards using the Karma contract 2025-02-27 20:48:39 +01:00
r4bbit
73e5b38da0 specs(EmergencyMode): add complementary rule for emergency mode
This rule checks explicitly which functions should not be callable when
emegency mode is enabled.
2025-02-26 08:31:09 +01:00
Andrea Franz
50b6d1a545 chore(XPToken): rename XP to Karma 2025-02-21 11:43:12 +01:00
r4bbit
b4b91873ed fix(certora): add prover args to config to prevent timeouts 2025-02-21 09:35:14 +01:00
Andrea Franz
58f43d07ce feature(RewardsStreamerMP): add compound function and track rewards accrued by each vault 2025-02-20 17:15:17 +01:00
r4bbit
e3d50bf695 specs: fix expected struct size 2025-02-19 17:58:15 +01:00
r4bbit
6f199313ec feat(RewardsStreamerMP): allow vaults to migrate to other vaults
This commit introduces a function `migrateToVault(address)` that allows
`StakeVault`s to migrate to other `StakeVault` instances.

The idea is that, when an upgrade was done on the stake manager, it
might introduces functions that can't be accessed through the stake
vaults that are out there.

Users will have to create new stake vault instances that provide the
necessary functionality.

`migrateToVault()` allows them to do so.

Closes #127
2025-02-19 17:58:15 +01:00
r4bbit
59226ef107 test(RewardsStreamerMP): ensure lock() reverts when vault is empty
Closes #126
2025-02-19 17:29:03 +01:00
r4bbit
fb79e249fb fix(RewardsStreamerMP): ensure registerVault reverts in emergency mode
Originally, I just wanted to simplify the certora rule that,
when emergency mode is enabled, only a few selected functions can be
called.

Instead of listing all the view function as "allowed", I've moved to
using CVLs `isView` flag on the function under verification.

This however uncovered a violation where
`RewardsStreamerMP.registerVault` is allowed to be called in emergency
mode.

In theory there's no harm in registering a vault when the system is in
emergency mode, but semantically it doesn't really make sense.

`registerVault` has been accidentally added to `isViewFunction()`.
This commit fixes this by adding `onlyNotEmergencyMode` modifier to
`registerVault()`.
2025-02-19 16:17:10 +01:00
Ricardo Guilherme Schmidt
a22da253c3 refactor(RewardStreamerMP): extract MP and Stake mathematical formulas to abstract contracts 2025-01-30 17:06:16 +01:00
r4bbit
44deb52c58 refactor: update terminology in contract
Closes #87
2025-01-28 12:20:04 +01:00
Andrea Franz
a413f4cbbb feat(RewardsStreamerMP): rewardsBalanceOf uses account's accrued + pending MPs 2024-12-20 07:40:55 +01:00
Andrea Franz
f601050dbe refactor(RewardsStreamerMP): rename functions to be appropriate 2024-12-20 07:40:55 +01:00
Ricardo Guilherme Schmidt
106ec98839 fix(EmergencyMode.spec): add YEAR() to isViewFunction 2024-12-06 12:44:51 +01:00
r4bbit
ebfb426d0b refactor(RewardsStreamerMP): use Math.mulDiv to reduce likelyhood of
precision loss

Closes #85
2024-12-06 12:44:51 +01:00
r4bbit
c041d5dd85 test: formally verify that MPs only decrease when unstaking/leaving 2024-12-05 08:04:29 +01:00
r4bbit
9374025924 feat(StakeManager): add capabilities to register vaults
This commit introduces changes related to vault registrations in the
stake manager.

The stake manager needs to keep track of the vaults a users creates so
it can aggregate accumulated MP across vaults for any given user.

The `StakeVault` now comes with a `register()` function which needs to
be called to register itself with the stake manager. `StakeManager` has
a new `onlyRegisteredVault` modifier that ensures only registered vaults
can actually `stake` and `unstake`.

Closes #70
2024-12-03 16:55:34 +01:00
Andrea Franz
b1a4e5ad37 fix(RewardsStreamerMP): rename _calculateAccruedRewards to _calculatePendingRewards and fix specs 2024-12-03 13:50:52 +01:00
Andrea Franz
7211b493f7 test(RewardsStreamerMP): fix EmergencyMode spec 2024-12-03 13:50:52 +01:00
Andrea Franz
dffaea2a73 feat(RewardsStreamerMP): stream rewards for a period without checking a real reward token balance 2024-12-03 13:50:52 +01:00
r4bbit
fcfe72d050 feat(RewardsStreamerMP): introduce leave() function
This function allows users to `leave()` the system if they can't or
don't want to trust the stake manager. This is the case when the owner
of the stake manager performs an upgrade.

In case of such an upgrade, the stake manager will be marked as not
trusted which prevents the user from staking, unstaking, locking etc.

The user can then either explicitly trust stake manager (will happen in
future changes) to enable the vault's functionality again, or, `leave()`
the system at which point it will try to perform a benign `leave()`
operation and then move the funds out of the vault.

Closes #66
2024-12-01 08:25:36 +01:00
Ricardo Guilherme Schmidt
8561a68ffd feat(RewardsStreamerMP): make RewardsStreamerMP upgradeable
This commit introduces upgradeability of the `RewardsStreamerMP`
contract by leveraging the UUPS pattern.

This means, for deployment, we have to first deploy an instance of
`RewardsStreamerMP` contract as a "template" logic contract and then
create a ERC1967Proxy that points to it.

The proxy ensures the implementation address is stored in a
deterministic storage slot.

This will later be leveraged by the `StakeVault` contract to implement
the functionality to leave the system in case there was a malicious
upgrade.

Closes #22
2024-12-01 08:06:51 +01:00
r4bbit
1e703e3f71 feat(RewardStreamerMP): add emergency mode so users can exit the system
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.

This also applies when there was a malicious upgrade and a call to
`emergencyModeEnabled()` panics.

To have this in a fully secure manner, we still have to add the counter
part of "leaving" the system. This will allow users that don't agree
with a (malicious) upgrade to get their funds out of the vaults
regardless.

Closes #66
2024-11-28 08:27:58 +01:00
r4bbit
91cd844dd6 chore(certora): formally verify StakeVault account balance vs ERC20
balance

Closes #29
2024-10-30 12:52:21 +01:00
r4bbit
ba26e7cc79 refactor(RewardStreamerMP): rename user vars to account
Closes #59
2024-10-21 13:49:29 +02:00
r4bbit
044301869a chore(certora): dont wait for results 2024-10-18 14:51:36 +02:00
r4bbit
ad2d11d138 chore(certora): add rule that greater lockup means greater MPs
Closes #28
2024-10-18 14:25:14 +02:00
r4bbit
77d77b8017 chore(certora): add rule that MPs are minted at 1-to-1 ratio
Closes #27
2024-10-18 13:56:15 +02:00
r4bbit
b79deb70f5 chore(certora): add accountMPGreaterEqualsAccountBalance invariant
Closes #26
2024-10-16 14:01:51 +02:00
r4bbit
59f2566c78 refactor(RewardStreamerMP): keep track of maxMP instead of
`potentialMP`

This commit changes the mechanics to ensure there are no more MP
generated that what's allowed as per max limiting.

Previously we've kept track of `potentialMP` which would decrease as
more MP are generated.

This made verifying certain rules on certora hard and/or impossible.
So we decided to track `maxMP` instead, which only decreases when users
unstake.

This commit also introduces a rule that ensures any accounts MP never
exceed their max mp.

Closes #44
2024-10-16 12:44:47 +02:00
r4bbit
3eb4aa830e chore(certora): add sumOfBalancesIsTotalStaked invariant
Closes #24
2024-10-14 12:04:52 +02:00
Andrea Franz
478174a356 chore(XPToken): add certora base config 2024-10-11 16:56:03 +02:00
Andrea Franz
4ef75621a3 import foundry template (#1) 2024-09-25 09:39:14 +02:00