220 Commits

Author SHA1 Message Date
Filip Pajic
1f9e9f678c docs: minor latex and typo fixes
* MPMaximum Latex syntax fix

* Update T_RATE to reflect block time on SN Sepolia

* Pending Latex syntax fix

* Global Reward Latex syntax fix

* NewIndex Latex syntax fix

* reward example value typo fix

* format MathSpec table

* explicitly state T_RATE is chain dependent value
2025-08-19 12:55:55 +02:00
Ricardo Guilherme Schmidt
04f9c446ee refactor(StakeManager, StakeVault): decouple StakeManager <-> StakeVault (#240)
- BREAKING CHANGE: Updated stake and lock functions in StakeManager to accept an additional parameter for current lock until timestamp.
- BREAKING CHANGE: Modified StakeVault to handle the new locking mechanism and removed the old updateLockUntil function.
- Adjusted related tests to reflect changes in function signatures and expected behaviors.
- Ensured that funds locked checks are properly referenced in tests and contracts.
2025-08-18 08:57:28 -03:00
Ricardo Guilherme Schmidt
48e6903b33 refactor(StakeVault): Remove obsolete trust stake manager logic (#237) 2025-08-06 09:11:22 -03:00
Ricardo Guilherme Schmidt
a2ba7d2045 refactor(StakeVault): replace StakeManager with MockStakeManager and update tests 2025-07-31 11:13:14 +02:00
Ricardo Guilherme Schmidt
f14312e842 chore(StakeVault.test): Improve coverage 2025-07-31 11:13:14 +02:00
Ricardo Guilherme Schmidt
7d2e4a810d refactor: migrate KarmaTiers to contiguous array-based tier management (#228)
* refactor: migrate KarmaTiers to contiguous array-based tier management

- Replaced mapping-based tier storage with a contiguous Tier[] array
- Introduced batch update via updateTiers(), enforcing non-overlapping, gapless ranges
- Removed individual tier operations (add, update, deactivate, activate)
- Simplified tier resolution with linear lookup

test: rewrite test suite for new KarmaTiers structure

- Added tests for ownership, empty input, non-contiguous tiers, invalid names
- Validated proper behavior for unlimited tiers (maxKarma = type(uint256).max)
- Included edge case checks for getTierIdByKarmaBalance
- Added event verification for TiersUpdated

* ci: update python version to fix bug in certora

---------

Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-07-28 10:39:49 -03:00
r4bbit
22ba4ff130 refactor(RLN): remove verifier and exit function 2025-07-16 10:49:03 +02:00
r4bbit
fdc45eac07 fix(RLN): ensure init params are valid 2025-07-16 10:49:03 +02:00
Ricardo Guilherme Schmidt
edd63e75f9 feat(RLN): implement KarmaRLN
Closes #217, #218, #219
2025-07-15 13:39:22 +02:00
r4bbit
382b1c1643 feat: implement KarmaTiers
This commit introduces a new contract `KarmaTiers` that allows for
maintaing tiers for gasless transactions.

The owner of the contract can add tiers, update tiers and deactivate or
activate them.

Tier names can only be 32 bytes long and there's no overlap allowed
between min and max Karma bounds of the tiers.

Closes #216
2025-06-26 15:36:02 +02:00
r4bbit
8bd6687569 test(Karma): adjust fuzz test for slashing to ensure there's balance to
slash

This will otherwise find counter examples where the transaction reverts.
2025-06-23 20:59:47 +02:00
r4bbit
44700264f5 feat(Karma): add ability to slash Karma
This commit introduces the ability for accounts with the necessary
privileges to slash other accounts. The amount to be slashed is
controlled via the `slashPercentage`.

The amount to be slashed will be calculated from the account's current
Karma balance, which is the total Karma across all distributors, minus
the known `slashAmount` for that account.
Under the hood, it calculates the slash amount for each item
(distributor or internal balance). This ensure we reduce the slash
amount correctly, if a reward distributor is removed.

**Example**:

For example, if the account has 100 Karma and hasn't been slashed
before, the account's balances would look like this:

```
rawBalance: 100
slashAmount: 0
balance: 100
```

Therefore, `balanceOf(account)` will return `100`.
If slashing burns 10% of the account's balance, then, after calling
`slash(account)`, the `slashAmount` will be increased accordingly:

```
rawBalance: 100
slashAmount: 10
balance: 90
```

Notice that `rawBalance` isn't actually a new contract property, but
there's a new internal function `_rawBalanceAndSlashAmountOf(account)`, which is used
by `balanceOf(account)` to determine the effective balance of an
account.

**Authorization**

In order to slash accounts, the message sender needs to have the newly
introduced `SLASHER_ROLE`.

Closes #212
2025-06-05 14:26:11 +02:00
Ricardo Guilherme Schmidt
753e379682 chore(forge fmt): change line lenght to 119 to avoid conflicts with solhint 2025-06-05 13:56:52 +02:00
Ricardo Guilherme Schmidt
83d8574867 chore(RLN): use same pragma as other files 2025-06-05 13:56:52 +02:00
Ricardo Guilherme Schmidt
458e07cc70 chore(RLN): import rln-contracts 2025-06-05 13:56:52 +02:00
r4bbit
bfba516b28 chore: use stable foundry on CI 2025-06-04 14:52:31 +02:00
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
8f2adf3c48 refactor(TrustedCodehashAccess): rename storage gap variable
When debugging storage layouts, it's actually hard to follow where all
the `__gap` fields are coming from when multiple upgradeable contracts
are part of the dependency chain.

This commit changes the name of `__gap` toa contract specific name,
allowing for clarity when inspecting storage layouts.
2025-05-13 21:04:35 +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
10b6743d55 fix(Karma): prevent overflow errors when issuing rewards
As described in #206 it's theoretically possible to cause overflows when
either Karma is issued via `mint()` or `setReward()` because both
functions don't take the supply of the other "domain" into account.

This commit fixes this by performing an arithmetic operation on
`super.totalSupply()`, `totalDistributorAllocation` and the newly issued
`amount`.

If there's an overflow, the code will cause an overflow and reverts.
This ensure overflows can't happen *after* rewards have been issued.

Closes #206
2025-05-13 13:36:02 +02:00
r4bbit
ac66c84ef5 chore(release): 0.2.1 v0.2.1 2025-04-04 13:40:25 +02:00
Ricardo Guilherme Schmidt
458fc2873a chore(docs): make it better styling and add deployed contracts 2025-04-03 15:52:29 +02:00
Ricardo Guilherme Schmidt
b108a00c0e chore(docs): update readme.md 2025-04-03 15:52:29 +02:00
r4bbit
07cb570cb3 docs: add deployment steps documentation
This documents the exact steps to deploy the entire staking protocol
including contract verification and configuration of the system.
2025-04-02 18:30:39 +02:00
r4bbit
309d765731 refactor(DeploymentConfig): remove proxy implementation address
This was a bandaid solution to easily allow for upgrade scripts.
We've changed those now to expect environment variables instead.
This allows us to change the dependencies without committing them to
version control.
2025-04-02 16:56:16 +02:00
r4bbit
22feed8dba fix(StakeManager): don't allow migrating to unregistered vaults
This was uncovered when a user tried to migrate a `StakeVault` from one
deployed `StakeManager` to a vault that was registered with a different
`StakeManager` instance.

The result was that the data of the vault has been indeed migrated to
the new vault, however, since the vault queries stake data from the
`StakeManager`, the new vault is unable to properly calculated balances
to withdraw funds, among other things.

It shouldn't be possible to migrate to a vault that isn't registered
with the system a user migrates from, in the first place.

This commit ensures that by reverting when the `migrateTo` address isn't
a registered vault with the `StakeManager`.
2025-04-01 16:10:02 +02:00
r4bbit
e2c327c0c9 chore(release): 0.2.0 v0.2.0 2025-03-28 16:53:53 +01: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
d02daad8ef cleanup: specify exact compiler version
This is to avoid running into bugs in the future, in case the compiler
introduces one in the version range that was specified before.
2025-03-28 12:57:21 +01:00
r4bbit
9a6abd16c3 cleanup(KarmaNFT): remove unused Ownable import 2025-03-28 12:48:33 +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
r4bbit
ce982b9ce5 !refactor(Karma): remove mintAllowance()
This is no longer a necessary requirement.
This commit removes `mintAllowance()`, it's internal counterpart and its
usage.

BREAKING CHANGE:

`mintAllowance()` no longer exists.

Closes #192
2025-03-26 08:33:31 +01:00
r4bbit
695a208804 !refactor: rename getStakedBalance() -> stakedBalanceOf()
This is to align with all the other `mp*Of` and `mp*OfAccount`
functions as discussed in #188

BREAKING CHANGE:

`getStakedBalance(address)` is now `stakedBalanceOf(address)`

Closes #188
2025-03-25 20:25:46 +01:00
r4bbit
8e4aa682c1 !refactor(RewardsStreamerMP): rename internal functions and rewardIndex
This commit does the following changes:

`_getVaultPendingMP()` -> _`vaultPendingMP()`
`_liveTotalMP()` -> `_totalMP()`
`_liveRewardIndex()` -> `_rewardIndex()`
`updateRewardIndex()` -> `_updateRewardIndex()`

BREAKING CHANGE:

The previous public `rewardIndex` field is now called `lastRewardIndex`.

Closes #189
2025-03-25 17:43:41 +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
Ricardo Guilherme Schmidt
0385522821 chore(tests): use UndefinedError in some cases 2025-03-21 18:21:57 +01:00
Ricardo Guilherme Schmidt
400923aed0 # This is a combination of 6 commits.
# This is the 1st commit message:

feat(RewardsStreamerMP.t): improve fuzz tests to test revert cases

fix(StakeMath): prevent uint256 overflow error
fix(StakeMath): prevent unstaking zero

# This is the commit message #2:

fix(StakeMath): prevent unstaking zero

# This is the commit message #3:

refactor(fuzz-tests): enhance readibility + test for unstake

# This is the commit message #4:

chore(tests): add compoud fuzz test

# This is the commit message #5:

chore(tests): Add Compound Fuzz Test

# This is the commit message #6:

chore (tests): fix fuzz test Unstake to always call compound function before unstake.
2025-03-21 18:21:57 +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
dabcf5c990 fix(RewardsStreamerMP): remove double totalMPStaked substraction 2025-03-20 14:03:28 +01:00
Andrea Franz
508885bed5 chore(RewardsStreamerMP): allow users to stake again without increasing the lock period 2025-03-19 15:36:55 +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
2de338c673 chore(release): 0.1.1 v0.1.1 2025-03-18 11:56:59 +01:00
Andrea Franz
47b9fd0ebe chore(KarmaNFT): update deploy scripts with proper svg strings 2025-03-14 16:01:34 +01:00
r4bbit
28cc5d6b2a chore: add deployment script for metadata generator 2025-03-14 16:01:34 +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
r4bbit
619b541d2a fix(RewardsStreamerMP): prevent attack causes accounts to not accrue MP
Closes #176
2025-03-14 13:25:09 +01:00
Andrea Franz
54fd86ddf4 chore(KarmaNFT): use image_data as field when there's a raw inlined image 2025-03-14 13:16:25 +01:00
r4bbit
ccd4bec8c7 docs: adjust docs to latest changes 2025-03-12 11:18:41 +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