mirror of
https://github.com/vacp2p/staking-reward-streamer.git
synced 2026-01-09 13:08:03 -05:00
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
This commit is contained in:
116
.gas-report
116
.gas-report
@@ -1,30 +1,30 @@
|
|||||||
|
|
||||||
╭-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
|
╭-------------------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------╮
|
||||||
| lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol:ERC1967Proxy Contract | | | | | |
|
| lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol:ERC1967Proxy Contract | | | | | |
|
||||||
+==================================================================================================================================================+
|
+=================================================================================================================================================+
|
||||||
| Deployment Cost | Deployment Size | | | | |
|
| Deployment Cost | Deployment Size | | | | |
|
||||||
|-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
|
|-------------------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
|
||||||
| 0 | 1374 | | | | |
|
| 0 | 1374 | | | | |
|
||||||
|-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
|
|-------------------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
|
||||||
| | | | | | |
|
| | | | | | |
|
||||||
|-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
|
|-------------------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
|
||||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||||
|-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
|
|-------------------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
|
||||||
| fallback | 5166 | 113929 | 97112 | 193429 | 693 |
|
| fallback | 5145 | 65850 | 33119 | 193478 | 3440 |
|
||||||
╰-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
|
╰-------------------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------╯
|
||||||
|
|
||||||
╭-----------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
╭-----------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
||||||
| script/DeployKarma.s.sol:DeployKarmaScript Contract | | | | | |
|
| script/DeployKarma.s.sol:DeployKarmaScript Contract | | | | | |
|
||||||
+===============================================================================================================+
|
+===============================================================================================================+
|
||||||
| Deployment Cost | Deployment Size | | | | |
|
| Deployment Cost | Deployment Size | | | | |
|
||||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||||
| 5135751 | 24812 | | | | |
|
| 5471828 | 26377 | | | | |
|
||||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||||
| | | | | | |
|
| | | | | | |
|
||||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||||
| run | 4330203 | 4330203 | 4330203 | 4330203 | 152 |
|
| run | 4666141 | 4666141 | 4666141 | 4666141 | 176 |
|
||||||
╰-----------------------------------------------------+-----------------+---------+---------+---------+---------╯
|
╰-----------------------------------------------------+-----------------+---------+---------+---------+---------╯
|
||||||
|
|
||||||
╭-----------------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
╭-----------------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
|---------------------------------------------------------+-----------------+------+--------+------+---------|
|
|---------------------------------------------------------+-----------------+------+--------+------+---------|
|
||||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||||
|---------------------------------------------------------+-----------------+------+--------+------+---------|
|
|---------------------------------------------------------+-----------------+------+--------+------+---------|
|
||||||
| activeNetworkConfig | 455 | 1971 | 455 | 4455 | 414 |
|
| activeNetworkConfig | 455 | 2022 | 455 | 4455 | 462 |
|
||||||
╰---------------------------------------------------------+-----------------+------+--------+------+---------╯
|
╰---------------------------------------------------------+-----------------+------+--------+------+---------╯
|
||||||
|
|
||||||
╭---------------------------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
╭---------------------------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
||||||
@@ -88,43 +88,57 @@
|
|||||||
+=====================================================================================+
|
+=====================================================================================+
|
||||||
| Deployment Cost | Deployment Size | | | | |
|
| Deployment Cost | Deployment Size | | | | |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| 0 | 11694 | | | | |
|
| 0 | 13259 | | | | |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| | | | | | |
|
| | | | | | |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| DEFAULT_ADMIN_ROLE | 306 | 306 | 306 | 306 | 19 |
|
| DEFAULT_ADMIN_ROLE | 285 | 285 | 285 | 285 | 23 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| OPERATOR_ROLE | 283 | 283 | 283 | 283 | 2 |
|
| MIN_SLASH_AMOUNT | 264 | 264 | 264 | 264 | 1 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| addRewardDistributor | 29894 | 64182 | 70797 | 70797 | 232 |
|
| OPERATOR_ROLE | 262 | 262 | 262 | 262 | 2 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| allowance | 504 | 504 | 504 | 504 | 6 |
|
| SLASHER_ROLE | 262 | 262 | 262 | 262 | 24 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| approve | 441 | 441 | 441 | 441 | 6 |
|
| accountSlashAmount | 2611 | 2611 | 2611 | 2611 | 2 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| balanceOf | 21085 | 21085 | 21085 | 21085 | 18 |
|
| addRewardDistributor | 29975 | 63645 | 70903 | 70903 | 284 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| getRewardDistributors | 5119 | 7759 | 9607 | 9607 | 17 |
|
| allowance | 573 | 573 | 573 | 573 | 8 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| grantRole | 29440 | 29440 | 29440 | 29440 | 5 |
|
| approve | 453 | 453 | 453 | 453 | 8 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| hasRole | 2685 | 2685 | 2685 | 2685 | 4 |
|
| balanceOf | 17795 | 28157 | 28160 | 28233 | 287 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| initialize | 94595 | 94595 | 94595 | 94595 | 152 |
|
| calculateSlashAmount | 2763 | 2801 | 2804 | 2804 | 774 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| mint | 4790 | 38817 | 51239 | 51239 | 26 |
|
| getRewardDistributors | 5132 | 7710 | 9644 | 9644 | 21 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| removeRewardDistributor | 5044 | 22060 | 29223 | 29959 | 21 |
|
| grantRole | 29490 | 29490 | 29490 | 29490 | 29 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| setReward | 4832 | 147872 | 166705 | 166705 | 307 |
|
| hasRole | 2754 | 2754 | 2754 | 2754 | 4 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| totalSupply | 22567 | 22567 | 22567 | 22567 | 18 |
|
| initialize | 116796 | 116796 | 116796 | 116796 | 176 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| transfer | 439 | 439 | 439 | 439 | 6 |
|
| mint | 4869 | 50368 | 51342 | 51342 | 550 |
|
||||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| transferFrom | 511 | 511 | 511 | 511 | 6 |
|
| removeRewardDistributor | 5080 | 22644 | 29995 | 30358 | 28 |
|
||||||
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
|
| rewardDistributorSlashAmount | 2781 | 2781 | 2781 | 2781 | 1 |
|
||||||
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
|
| setReward | 4845 | 144102 | 166754 | 166754 | 319 |
|
||||||
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
|
| slash | 4803 | 103614 | 85757 | 123125 | 519 |
|
||||||
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
|
| slashedAmountOf | 17682 | 28099 | 28120 | 28120 | 516 |
|
||||||
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
|
| totalSupply | 22591 | 22591 | 22591 | 22591 | 24 |
|
||||||
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
|
| transfer | 451 | 451 | 451 | 451 | 8 |
|
||||||
|
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
|
| transferFrom | 580 | 580 | 580 | 580 | 8 |
|
||||||
╰------------------------------+-----------------+--------+--------+--------+---------╯
|
╰------------------------------+-----------------+--------+--------+--------+---------╯
|
||||||
|
|
||||||
╭-------------------------------------------------+-----------------+-------+--------+-------+---------╮
|
╭-------------------------------------------------+-----------------+-------+--------+-------+---------╮
|
||||||
@@ -194,7 +208,7 @@
|
|||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| leave | 66348 | 66348 | 66348 | 66348 | 2 |
|
| leave | 66348 | 66348 | 66348 | 66348 | 2 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| lock | 7040 | 43591 | 46713 | 87964 | 1034 |
|
| lock | 7040 | 43452 | 46713 | 87964 | 1034 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| migrateToVault | 9294 | 53513 | 17021 | 170715 | 4 |
|
| migrateToVault | 9294 | 53513 | 17021 | 170715 | 4 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
@@ -222,7 +236,7 @@
|
|||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| setTrustedCodehash | 24238 | 24238 | 24238 | 24238 | 95 |
|
| setTrustedCodehash | 24238 | 24238 | 24238 | 24238 | 95 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| stake | 2639 | 131862 | 60725 | 228623 | 2670 |
|
| stake | 2639 | 131319 | 60725 | 228623 | 2670 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| stakedBalanceOf | 2622 | 2622 | 2622 | 2622 | 1 |
|
| stakedBalanceOf | 2622 | 2622 | 2622 | 2622 | 1 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
@@ -242,13 +256,13 @@
|
|||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| totalStaked | 2408 | 2408 | 2408 | 2408 | 4169 |
|
| totalStaked | 2408 | 2408 | 2408 | 2408 | 4169 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| unstake | 9886 | 41391 | 39781 | 79550 | 271 |
|
| unstake | 9886 | 41365 | 39781 | 79550 | 271 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| updateAccount | 347677 | 347677 | 347677 | 347677 | 1 |
|
| updateAccount | 347677 | 347677 | 347677 | 347677 | 1 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| updateGlobalState | 15820 | 25876 | 29230 | 29230 | 8 |
|
| updateGlobalState | 15820 | 25876 | 29230 | 29230 | 8 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| updateVault | 31948 | 34543 | 31948 | 110579 | 1024 |
|
| updateVault | 31948 | 34373 | 31948 | 110579 | 1024 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| upgradeTo | 10279 | 10772 | 10279 | 12745 | 5 |
|
| upgradeTo | 10279 | 10772 | 10279 | 12745 | 5 |
|
||||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
@@ -276,9 +290,9 @@
|
|||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| leave | 12223 | 113137 | 84120 | 356508 | 5 |
|
| leave | 12223 | 113137 | 84120 | 356508 | 5 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| lock | 12151 | 59083 | 62251 | 103499 | 1035 |
|
| lock | 12151 | 58945 | 62251 | 103499 | 1035 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| lockUntil | 2363 | 2363 | 2363 | 2363 | 7769 |
|
| lockUntil | 2363 | 2363 | 2363 | 2363 | 7768 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| migrateToVault | 24910 | 77530 | 32637 | 219937 | 4 |
|
| migrateToVault | 24910 | 77530 | 32637 | 219937 | 4 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
@@ -286,15 +300,15 @@
|
|||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| register | 12742 | 78218 | 78761 | 78761 | 374 |
|
| register | 12742 | 78218 | 78761 | 78761 | 374 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| stake | 12131 | 166249 | 76290 | 284275 | 2671 |
|
| stake | 12131 | 165586 | 76290 | 284275 | 2671 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| stakeManager | 393 | 393 | 393 | 393 | 373 |
|
| stakeManager | 393 | 393 | 393 | 393 | 373 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| trustStakeManager | 7650 | 7650 | 7650 | 7650 | 1 |
|
| trustStakeManager | 7650 | 7650 | 7650 | 7650 | 1 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| unstake | 12108 | 58059 | 55296 | 110656 | 272 |
|
| unstake | 12108 | 58033 | 55296 | 110656 | 272 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| updateLockUntil | 4432 | 20722 | 21532 | 21532 | 524 |
|
| updateLockUntil | 4432 | 20797 | 21532 | 21532 | 508 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
| withdraw | 20817 | 20817 | 20817 | 20817 | 1 |
|
| withdraw | 20817 | 20817 | 20817 | 20817 | 1 |
|
||||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||||
@@ -312,9 +326,9 @@
|
|||||||
|----------------------------------------------------+-----------------+-------+--------+--------+---------|
|
|----------------------------------------------------+-----------------+-------+--------+--------+---------|
|
||||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||||
|----------------------------------------------------+-----------------+-------+--------+--------+---------|
|
|----------------------------------------------------+-----------------+-------+--------+--------+---------|
|
||||||
| fallback | 5208 | 12842 | 7353 | 374054 | 23167 |
|
| fallback | 5208 | 12834 | 7353 | 374054 | 23167 |
|
||||||
|----------------------------------------------------+-----------------+-------+--------+--------+---------|
|
|----------------------------------------------------+-----------------+-------+--------+--------+---------|
|
||||||
| implementation | 346 | 2131 | 2346 | 2346 | 4886 |
|
| implementation | 346 | 2137 | 2346 | 2346 | 4870 |
|
||||||
╰----------------------------------------------------+-----------------+-------+--------+--------+---------╯
|
╰----------------------------------------------------+-----------------+-------+--------+--------+---------╯
|
||||||
|
|
||||||
╭--------------------------------------------+-----------------+--------+--------+--------+---------╮
|
╭--------------------------------------------+-----------------+--------+--------+--------+---------╮
|
||||||
@@ -460,13 +474,13 @@
|
|||||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| rewardsBalanceOfAccount | 2549 | 2549 | 2549 | 2549 | 36 |
|
| rewardsBalanceOfAccount | 549 | 1986 | 2549 | 2549 | 3675 |
|
||||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| setTotalKarmaShares | 43589 | 43589 | 43589 | 43589 | 36 |
|
| setTotalKarmaShares | 43589 | 43589 | 43589 | 43589 | 48 |
|
||||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| setUserKarmaShare | 44194 | 44194 | 44194 | 44194 | 12 |
|
| setUserKarmaShare | 24210 | 44068 | 44134 | 44266 | 530 |
|
||||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| totalRewardsSupply | 2324 | 2324 | 2324 | 2324 | 36 |
|
| totalRewardsSupply | 2324 | 2324 | 2324 | 2324 | 48 |
|
||||||
╰-------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
|
╰-------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
|
||||||
|
|
||||||
╭---------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
|
╭---------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
|
||||||
@@ -488,17 +502,17 @@
|
|||||||
+==================================================================================================+
|
+==================================================================================================+
|
||||||
| Deployment Cost | Deployment Size | | | | |
|
| Deployment Cost | Deployment Size | | | | |
|
||||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| 770741 | 3987 | | | | |
|
| 770657 | 3987 | | | | |
|
||||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| | | | | | |
|
| | | | | | |
|
||||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| approve | 29075 | 31544 | 29183 | 46259 | 2676 |
|
| approve | 29075 | 31545 | 29183 | 46259 | 2676 |
|
||||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| balanceOf | 2561 | 2561 | 2561 | 2561 | 4960 |
|
| balanceOf | 2561 | 2561 | 2561 | 2561 | 4960 |
|
||||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||||
| mint | 33964 | 37189 | 34072 | 68248 | 2685 |
|
| mint | 33964 | 37190 | 34072 | 68248 | 2685 |
|
||||||
╰---------------------------------------------+-----------------+-------+--------+-------+---------╯
|
╰---------------------------------------------+-----------------+-------+--------+-------+---------╯
|
||||||
|
|
||||||
╭-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
|
╭-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
|
||||||
|
|||||||
180
.gas-snapshot
180
.gas-snapshot
@@ -1,13 +1,13 @@
|
|||||||
AddRewardDistributorTest:testAddKarmaDistributorOnlyAdmin() (gas: 438055)
|
AddRewardDistributorTest:testAddKarmaDistributorOnlyAdmin() (gas: 438258)
|
||||||
AddRewardDistributorTest:testAddRewardDistributorAsOtherAdmin() (gas: 182763)
|
AddRewardDistributorTest:testAddRewardDistributorAsOtherAdmin() (gas: 182935)
|
||||||
AddRewardDistributorTest:testBalanceOf() (gas: 449293)
|
AddRewardDistributorTest:testBalanceOf() (gas: 456642)
|
||||||
AddRewardDistributorTest:testBalanceOfWithNoSystemTotalKarma() (gas: 69655)
|
AddRewardDistributorTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83805)
|
||||||
AddRewardDistributorTest:testMintOnlyAdmin() (gas: 428769)
|
AddRewardDistributorTest:testMintOnlyAdmin() (gas: 429097)
|
||||||
AddRewardDistributorTest:testRemoveKarmaDistributorOnlyOwner() (gas: 162308)
|
AddRewardDistributorTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163471)
|
||||||
AddRewardDistributorTest:testRemoveUnknownKarmaDistributor() (gas: 41630)
|
AddRewardDistributorTest:testRemoveUnknownKarmaDistributor() (gas: 41666)
|
||||||
AddRewardDistributorTest:testTotalSupply() (gas: 359166)
|
AddRewardDistributorTest:testTotalSupply() (gas: 359391)
|
||||||
AddRewardDistributorTest:testTransfersNotAllowed() (gas: 61785)
|
AddRewardDistributorTest:testTransfersNotAllowed() (gas: 61947)
|
||||||
AddRewardDistributorTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 68325)
|
AddRewardDistributorTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 68406)
|
||||||
EmergencyExitTest:test_CannotEnableEmergencyModeTwice() (gas: 93554)
|
EmergencyExitTest:test_CannotEnableEmergencyModeTwice() (gas: 93554)
|
||||||
EmergencyExitTest:test_CannotLeaveBeforeEmergencyMode() (gas: 336067)
|
EmergencyExitTest:test_CannotLeaveBeforeEmergencyMode() (gas: 336067)
|
||||||
EmergencyExitTest:test_EmergencyExitBasic() (gas: 524580)
|
EmergencyExitTest:test_EmergencyExitBasic() (gas: 524580)
|
||||||
@@ -16,15 +16,15 @@ EmergencyExitTest:test_EmergencyExitToAlternateAddress() (gas: 479110)
|
|||||||
EmergencyExitTest:test_EmergencyExitWithLock() (gas: 452444)
|
EmergencyExitTest:test_EmergencyExitWithLock() (gas: 452444)
|
||||||
EmergencyExitTest:test_EmergencyExitWithRewards() (gas: 484810)
|
EmergencyExitTest:test_EmergencyExitWithRewards() (gas: 484810)
|
||||||
EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39176)
|
EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39176)
|
||||||
FuzzTests:testFuzz_AccrueMP(uint128,uint64,uint64) (runs: 1009, μ: 586777, ~: 549070)
|
FuzzTests:testFuzz_AccrueMP(uint128,uint64,uint64) (runs: 1009, μ: 583242, ~: 549046)
|
||||||
FuzzTests:testFuzz_AccrueMP_Relock(uint128,uint64,uint64,uint64) (runs: 1009, μ: 811994, ~: 777237)
|
FuzzTests:testFuzz_AccrueMP_Relock(uint128,uint64,uint64,uint64) (runs: 1009, μ: 808244, ~: 777237)
|
||||||
FuzzTests:testFuzz_EmergencyExit(uint256,uint256) (runs: 1001, μ: 588323, ~: 578267)
|
FuzzTests:testFuzz_EmergencyExit(uint256,uint256) (runs: 1001, μ: 588167, ~: 578267)
|
||||||
FuzzTests:testFuzz_Lock(uint256,uint64) (runs: 1008, μ: 961825, ~: 961235)
|
FuzzTests:testFuzz_Lock(uint256,uint64) (runs: 1008, μ: 961506, ~: 961235)
|
||||||
FuzzTests:testFuzz_Relock(uint256,uint64,uint64) (runs: 1008, μ: 598425, ~: 574225)
|
FuzzTests:testFuzz_Relock(uint256,uint64,uint64) (runs: 1008, μ: 600126, ~: 574225)
|
||||||
FuzzTests:testFuzz_Rewards(uint256,uint256,uint256,uint16,uint16) (runs: 1001, μ: 650378, ~: 653205)
|
FuzzTests:testFuzz_Rewards(uint256,uint256,uint256,uint16,uint16) (runs: 1001, μ: 650444, ~: 653254)
|
||||||
FuzzTests:testFuzz_Stake(uint256,uint64) (runs: 1008, μ: 375317, ~: 346086)
|
FuzzTests:testFuzz_Stake(uint256,uint64) (runs: 1008, μ: 377931, ~: 346087)
|
||||||
FuzzTests:testFuzz_Unstake(uint128,uint64,uint16,uint128) (runs: 1009, μ: 806735, ~: 780622)
|
FuzzTests:testFuzz_Unstake(uint128,uint64,uint16,uint128) (runs: 1009, μ: 803049, ~: 780598)
|
||||||
FuzzTests:testFuzz_UpdateVault(uint128,uint64,uint64) (runs: 1009, μ: 586800, ~: 549093)
|
FuzzTests:testFuzz_UpdateVault(uint128,uint64,uint64) (runs: 1009, μ: 583265, ~: 549069)
|
||||||
IntegrationTest:testStakeFoo() (gas: 2348931)
|
IntegrationTest:testStakeFoo() (gas: 2348931)
|
||||||
KarmaNFTTest:testApproveNotAllowed() (gas: 10507)
|
KarmaNFTTest:testApproveNotAllowed() (gas: 10507)
|
||||||
KarmaNFTTest:testGetApproved() (gas: 10531)
|
KarmaNFTTest:testGetApproved() (gas: 10531)
|
||||||
@@ -36,29 +36,29 @@ KarmaNFTTest:testSetMetadataGenerator() (gas: 1012377)
|
|||||||
KarmaNFTTest:testSetMetadataGeneratorRevert() (gas: 1006937)
|
KarmaNFTTest:testSetMetadataGeneratorRevert() (gas: 1006937)
|
||||||
KarmaNFTTest:testTokenURI() (gas: 1112435)
|
KarmaNFTTest:testTokenURI() (gas: 1112435)
|
||||||
KarmaNFTTest:testTransferNotAllowed() (gas: 10701)
|
KarmaNFTTest:testTransferNotAllowed() (gas: 10701)
|
||||||
KarmaOwnershipTest:testAddKarmaDistributorOnlyAdmin() (gas: 438043)
|
KarmaOwnershipTest:testAddKarmaDistributorOnlyAdmin() (gas: 438246)
|
||||||
KarmaOwnershipTest:testBalanceOf() (gas: 449293)
|
KarmaOwnershipTest:testBalanceOf() (gas: 456642)
|
||||||
KarmaOwnershipTest:testBalanceOfWithNoSystemTotalKarma() (gas: 69677)
|
KarmaOwnershipTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83827)
|
||||||
KarmaOwnershipTest:testInitialOwner() (gas: 20539)
|
KarmaOwnershipTest:testInitialOwner() (gas: 20587)
|
||||||
KarmaOwnershipTest:testMintOnlyAdmin() (gas: 428791)
|
KarmaOwnershipTest:testMintOnlyAdmin() (gas: 429119)
|
||||||
KarmaOwnershipTest:testOwnershipTransfer() (gas: 94343)
|
KarmaOwnershipTest:testOwnershipTransfer() (gas: 94420)
|
||||||
KarmaOwnershipTest:testRemoveKarmaDistributorOnlyOwner() (gas: 162229)
|
KarmaOwnershipTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163392)
|
||||||
KarmaOwnershipTest:testRemoveUnknownKarmaDistributor() (gas: 41618)
|
KarmaOwnershipTest:testRemoveUnknownKarmaDistributor() (gas: 41654)
|
||||||
KarmaOwnershipTest:testTotalSupply() (gas: 359166)
|
KarmaOwnershipTest:testTotalSupply() (gas: 359391)
|
||||||
KarmaOwnershipTest:testTransfersNotAllowed() (gas: 61785)
|
KarmaOwnershipTest:testTransfersNotAllowed() (gas: 61947)
|
||||||
KarmaTest:testAddKarmaDistributorOnlyAdmin() (gas: 438021)
|
KarmaTest:testAddKarmaDistributorOnlyAdmin() (gas: 438224)
|
||||||
KarmaTest:testBalanceOf() (gas: 449293)
|
KarmaTest:testBalanceOf() (gas: 456642)
|
||||||
KarmaTest:testBalanceOfWithNoSystemTotalKarma() (gas: 69655)
|
KarmaTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83805)
|
||||||
KarmaTest:testMintOnlyAdmin() (gas: 428769)
|
KarmaTest:testMintOnlyAdmin() (gas: 429097)
|
||||||
KarmaTest:testRemoveKarmaDistributorOnlyOwner() (gas: 162274)
|
KarmaTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163437)
|
||||||
KarmaTest:testRemoveUnknownKarmaDistributor() (gas: 41618)
|
KarmaTest:testRemoveUnknownKarmaDistributor() (gas: 41654)
|
||||||
KarmaTest:testTotalSupply() (gas: 359166)
|
KarmaTest:testTotalSupply() (gas: 359391)
|
||||||
KarmaTest:testTransfersNotAllowed() (gas: 61763)
|
KarmaTest:testTransfersNotAllowed() (gas: 61925)
|
||||||
LeaveTest:test_LeaveShouldKeepFundsLockedInStakeVault() (gas: 9938411)
|
LeaveTest:test_LeaveShouldKeepFundsLockedInStakeVault() (gas: 9938411)
|
||||||
LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 10011059)
|
LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 10011059)
|
||||||
LeaveTest:test_RevertWhenStakeManagerIsTrusted() (gas: 333238)
|
LeaveTest:test_RevertWhenStakeManagerIsTrusted() (gas: 333238)
|
||||||
LeaveTest:test_TrustNewStakeManager() (gas: 9944491)
|
LeaveTest:test_TrustNewStakeManager() (gas: 9944491)
|
||||||
LockTest:test_LockFailsWithInvalidPeriod(uint256) (runs: 1008, μ: 384561, ~: 384588)
|
LockTest:test_LockFailsWithInvalidPeriod(uint256) (runs: 1008, μ: 384560, ~: 384588)
|
||||||
LockTest:test_LockFailsWithNoStake() (gas: 89700)
|
LockTest:test_LockFailsWithNoStake() (gas: 89700)
|
||||||
LockTest:test_LockFailsWithZero() (gas: 343310)
|
LockTest:test_LockFailsWithZero() (gas: 343310)
|
||||||
LockTest:test_LockMultipleTimesExceedMaxLock() (gas: 746921)
|
LockTest:test_LockMultipleTimesExceedMaxLock() (gas: 746921)
|
||||||
@@ -79,16 +79,16 @@ NFTMetadataGeneratorSVGTest:testSetImageStringsRevert() (gas: 35891)
|
|||||||
NFTMetadataGeneratorURLTest:testGenerateMetadata() (gas: 108341)
|
NFTMetadataGeneratorURLTest:testGenerateMetadata() (gas: 108341)
|
||||||
NFTMetadataGeneratorURLTest:testSetBaseURL() (gas: 59131)
|
NFTMetadataGeneratorURLTest:testSetBaseURL() (gas: 59131)
|
||||||
NFTMetadataGeneratorURLTest:testSetBaseURLRevert() (gas: 36066)
|
NFTMetadataGeneratorURLTest:testSetBaseURLRevert() (gas: 36066)
|
||||||
OverflowTest:testAddKarmaDistributorOnlyAdmin() (gas: 438043)
|
OverflowTest:testAddKarmaDistributorOnlyAdmin() (gas: 438246)
|
||||||
OverflowTest:testBalanceOf() (gas: 449293)
|
OverflowTest:testBalanceOf() (gas: 456642)
|
||||||
OverflowTest:testBalanceOfWithNoSystemTotalKarma() (gas: 69655)
|
OverflowTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83805)
|
||||||
OverflowTest:testMintOnlyAdmin() (gas: 428769)
|
OverflowTest:testMintOnlyAdmin() (gas: 429097)
|
||||||
OverflowTest:testRemoveKarmaDistributorOnlyOwner() (gas: 162274)
|
OverflowTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163437)
|
||||||
OverflowTest:testRemoveUnknownKarmaDistributor() (gas: 41630)
|
OverflowTest:testRemoveUnknownKarmaDistributor() (gas: 41666)
|
||||||
OverflowTest:testTotalSupply() (gas: 359166)
|
OverflowTest:testTotalSupply() (gas: 359391)
|
||||||
OverflowTest:testTransfersNotAllowed() (gas: 61763)
|
OverflowTest:testTransfersNotAllowed() (gas: 61925)
|
||||||
OverflowTest:test_RevertWhen_MintingCausesOverflow() (gas: 129464)
|
OverflowTest:test_RevertWhen_MintingCausesOverflow() (gas: 129592)
|
||||||
OverflowTest:test_RevertWhen_SettingRewardCausesOverflow() (gas: 127792)
|
OverflowTest:test_RevertWhen_SettingRewardCausesOverflow() (gas: 127920)
|
||||||
RLNTest:test_initial_state() (gas: 65400)
|
RLNTest:test_initial_state() (gas: 65400)
|
||||||
RLNTest:test_register_fails_when_amount_lt_minimal_deposit() (gas: 161453)
|
RLNTest:test_register_fails_when_amount_lt_minimal_deposit() (gas: 161453)
|
||||||
RLNTest:test_register_fails_when_duplicate_identity_commitments() (gas: 444949)
|
RLNTest:test_register_fails_when_duplicate_identity_commitments() (gas: 444949)
|
||||||
@@ -106,36 +106,60 @@ RLNTest:test_withdraw_fails_when_already_underways() (gas: 468594)
|
|||||||
RLNTest:test_withdraw_fails_when_invalid_proof() (gas: 399356)
|
RLNTest:test_withdraw_fails_when_invalid_proof() (gas: 399356)
|
||||||
RLNTest:test_withdraw_fails_when_not_registered() (gas: 57129)
|
RLNTest:test_withdraw_fails_when_not_registered() (gas: 57129)
|
||||||
RLNTest:test_withdraw_succeeds() (gas: 480413)
|
RLNTest:test_withdraw_succeeds() (gas: 480413)
|
||||||
RemoveRewardDistributorTest:testAddKarmaDistributorOnlyAdmin() (gas: 438045)
|
RemoveRewardDistributorTest:testAddKarmaDistributorOnlyAdmin() (gas: 438248)
|
||||||
RemoveRewardDistributorTest:testBalanceOf() (gas: 449366)
|
RemoveRewardDistributorTest:testBalanceOf() (gas: 456715)
|
||||||
RemoveRewardDistributorTest:testBalanceOfWithNoSystemTotalKarma() (gas: 69633)
|
RemoveRewardDistributorTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83783)
|
||||||
RemoveRewardDistributorTest:testMintOnlyAdmin() (gas: 428759)
|
RemoveRewardDistributorTest:testMintOnlyAdmin() (gas: 429087)
|
||||||
RemoveRewardDistributorTest:testRemoveKarmaDistributorOnlyOwner() (gas: 162298)
|
RemoveRewardDistributorTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163461)
|
||||||
RemoveRewardDistributorTest:testRemoveRewardDistributor() (gas: 162118)
|
RemoveRewardDistributorTest:testRemoveRewardDistributor() (gas: 162967)
|
||||||
RemoveRewardDistributorTest:testRemoveRewardDistributorAsOtherAdmin() (gas: 242200)
|
RemoveRewardDistributorTest:testRemoveRewardDistributorAsOtherAdmin() (gas: 243532)
|
||||||
RemoveRewardDistributorTest:testRemoveUnknownKarmaDistributor() (gas: 41636)
|
RemoveRewardDistributorTest:testRemoveUnknownKarmaDistributor() (gas: 41672)
|
||||||
RemoveRewardDistributorTest:testTotalSupply() (gas: 359239)
|
RemoveRewardDistributorTest:testTotalSupply() (gas: 359464)
|
||||||
RemoveRewardDistributorTest:testTransfersNotAllowed() (gas: 61763)
|
RemoveRewardDistributorTest:testTransfersNotAllowed() (gas: 61925)
|
||||||
RemoveRewardDistributorTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 66507)
|
RemoveRewardDistributorTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 66543)
|
||||||
SetRewardTest:testAddKarmaDistributorOnlyAdmin() (gas: 438077)
|
SetRewardTest:testAddKarmaDistributorOnlyAdmin() (gas: 438280)
|
||||||
SetRewardTest:testBalanceOf() (gas: 449293)
|
SetRewardTest:testBalanceOf() (gas: 456642)
|
||||||
SetRewardTest:testBalanceOfWithNoSystemTotalKarma() (gas: 69677)
|
SetRewardTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83827)
|
||||||
SetRewardTest:testMintOnlyAdmin() (gas: 428791)
|
SetRewardTest:testMintOnlyAdmin() (gas: 429119)
|
||||||
SetRewardTest:testRemoveKarmaDistributorOnlyOwner() (gas: 162241)
|
SetRewardTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163404)
|
||||||
SetRewardTest:testRemoveUnknownKarmaDistributor() (gas: 41630)
|
SetRewardTest:testRemoveUnknownKarmaDistributor() (gas: 41666)
|
||||||
SetRewardTest:testSetRewardAsAdmin() (gas: 134934)
|
SetRewardTest:testSetRewardAsAdmin() (gas: 135089)
|
||||||
SetRewardTest:testSetRewardAsOperator() (gas: 143714)
|
SetRewardTest:testSetRewardAsOperator() (gas: 143840)
|
||||||
SetRewardTest:testSetRewardAsOtherAdmin() (gas: 203920)
|
SetRewardTest:testSetRewardAsOtherAdmin() (gas: 204104)
|
||||||
SetRewardTest:testTotalSupply() (gas: 359211)
|
SetRewardTest:testTotalSupply() (gas: 359436)
|
||||||
SetRewardTest:testTransfersNotAllowed() (gas: 61807)
|
SetRewardTest:testTransfersNotAllowed() (gas: 61969)
|
||||||
SetRewardTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 43559)
|
SetRewardTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 43572)
|
||||||
SetRewardTest:test_RevertWhen_SenderIsNotOperator() (gas: 61832)
|
SetRewardTest:test_RevertWhen_SenderIsNotOperator() (gas: 61893)
|
||||||
StakeManager_RewardsTest:testRewardsBalanceOf() (gas: 2712035)
|
SlashAmountOfTest:testAddKarmaDistributorOnlyAdmin() (gas: 438224)
|
||||||
StakeManager_RewardsTest:testSetRewards() (gas: 278100)
|
SlashAmountOfTest:testBalanceOf() (gas: 456642)
|
||||||
StakeManager_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 63751)
|
SlashAmountOfTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83783)
|
||||||
StakeManager_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 103509)
|
SlashAmountOfTest:testFuzz_SlashAmountOf(uint256,uint256,uint256) (runs: 1002, μ: 407788, ~: 408571)
|
||||||
|
SlashAmountOfTest:testMintOnlyAdmin() (gas: 429075)
|
||||||
|
SlashAmountOfTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163437)
|
||||||
|
SlashAmountOfTest:testRemoveUnknownKarmaDistributor() (gas: 41654)
|
||||||
|
SlashAmountOfTest:testTotalSupply() (gas: 359391)
|
||||||
|
SlashAmountOfTest:testTransfersNotAllowed() (gas: 61990)
|
||||||
|
SlashAmountOfTest:test_SlashAmountOf() (gas: 327608)
|
||||||
|
SlashTest:testAddKarmaDistributorOnlyAdmin() (gas: 438270)
|
||||||
|
SlashTest:testBalanceOf() (gas: 456648)
|
||||||
|
SlashTest:testBalanceOfWithNoSystemTotalKarma() (gas: 83827)
|
||||||
|
SlashTest:testFuzz_Slash(uint256) (runs: 1009, μ: 280204, ~: 280146)
|
||||||
|
SlashTest:testMintOnlyAdmin() (gas: 429131)
|
||||||
|
SlashTest:testRemoveKarmaDistributorOnlyOwner() (gas: 163461)
|
||||||
|
SlashTest:testRemoveRewardDistributorShouldReduceSlashAmount() (gas: 610762)
|
||||||
|
SlashTest:testRemoveUnknownKarmaDistributor() (gas: 41683)
|
||||||
|
SlashTest:testTotalSupply() (gas: 359420)
|
||||||
|
SlashTest:testTransfersNotAllowed() (gas: 61969)
|
||||||
|
SlashTest:test_RevertWhen_KarmaBalanceIsInvalid() (gas: 71550)
|
||||||
|
SlashTest:test_RevertWhen_SenderIsNotDefaultAdminOrSlasher() (gas: 43232)
|
||||||
|
SlashTest:test_Slash() (gas: 428385)
|
||||||
|
SlashTest:test_SlashRemainingBalanceIfBalanceIsLow() (gas: 251800)
|
||||||
|
StakeManager_RewardsTest:testRewardsBalanceOf() (gas: 2712133)
|
||||||
|
StakeManager_RewardsTest:testSetRewards() (gas: 278149)
|
||||||
|
StakeManager_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 63800)
|
||||||
|
StakeManager_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 103558)
|
||||||
StakeManager_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39367)
|
StakeManager_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39367)
|
||||||
StakeManager_RewardsTest:testTotalRewardsSupply() (gas: 1280724)
|
StakeManager_RewardsTest:testTotalRewardsSupply() (gas: 1280822)
|
||||||
StakeTest:test_StakeMultipleAccounts() (gas: 666808)
|
StakeTest:test_StakeMultipleAccounts() (gas: 666808)
|
||||||
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 721800)
|
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 721800)
|
||||||
StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 1324461)
|
StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 1324461)
|
||||||
@@ -182,7 +206,7 @@ UnstakeTest:test_UnstakeOneAccount() (gas: 759178)
|
|||||||
UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 719489)
|
UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 719489)
|
||||||
UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 673681)
|
UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 673681)
|
||||||
UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 722241)
|
UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 722241)
|
||||||
UpdateVaultTest:test_UpdateAccount() (gas: 2587378)
|
UpdateVaultTest:test_UpdateAccount() (gas: 2587427)
|
||||||
UpgradeTest:test_RevertWhenNotOwner() (gas: 3696209)
|
UpgradeTest:test_RevertWhenNotOwner() (gas: 3696209)
|
||||||
UpgradeTest:test_UpgradeStakeManager() (gas: 9855347)
|
UpgradeTest:test_UpgradeStakeManager() (gas: 9855347)
|
||||||
VaultRegistrationTest:test_VaultRegistration() (gas: 90138)
|
VaultRegistrationTest:test_VaultRegistration() (gas: 90138)
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"src/StakeManager.sol",
|
"src/StakeManager.sol",
|
||||||
"src/Karma.sol",
|
"src/Karma.sol",
|
||||||
|
"certora/harness/KarmaHarness.sol",
|
||||||
],
|
],
|
||||||
"msg": "Verifying Karma.sol",
|
"msg": "Verifying Karma.sol",
|
||||||
"rule_sanity": "basic",
|
"rule_sanity": "basic",
|
||||||
"verify": "Karma:certora/specs/Karma.spec",
|
"verify": "KarmaHarness:certora/specs/Karma.spec",
|
||||||
"parametric_contracts": ["Karma"],
|
"parametric_contracts": ["KarmaHarness"],
|
||||||
"optimistic_loop": true,
|
"optimistic_loop": true,
|
||||||
"loop_iter": "3",
|
"loop_iter": "3",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
|||||||
14
certora/harness/KarmaHarness.sol
Normal file
14
certora/harness/KarmaHarness.sol
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity 0.8.26;
|
||||||
|
|
||||||
|
import { Karma } from "../../src/Karma.sol";
|
||||||
|
|
||||||
|
contract KarmaHarness is Karma {
|
||||||
|
function rawBalanceOf(address account) public view returns (uint256) {
|
||||||
|
(uint256 rawBalance,) = _rawBalanceAndSlashAmountOf(account);
|
||||||
|
return rawBalance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,13 +1,23 @@
|
|||||||
using Karma as karma;
|
using KarmaHarness as karma;
|
||||||
|
|
||||||
methods {
|
methods {
|
||||||
|
function balanceOf(address) external returns (uint256) envfree;
|
||||||
|
function rawBalanceOf(address) external returns (uint256) envfree;
|
||||||
function totalDistributorAllocation() external returns (uint256) envfree;
|
function totalDistributorAllocation() external returns (uint256) envfree;
|
||||||
function totalSupply() external returns (uint256) envfree;
|
function totalSupply() external returns (uint256) envfree;
|
||||||
function externalSupply() external returns (uint256) envfree;
|
function externalSupply() external returns (uint256) envfree;
|
||||||
|
function accountSlashAmount(address) external returns (uint256) envfree;
|
||||||
function _.setReward(uint256, uint256) external => DISPATCHER(true);
|
function _.setReward(uint256, uint256) external => DISPATCHER(true);
|
||||||
|
function _.rewardsBalanceOfAccount(address) external => DISPATCHER(true);
|
||||||
function hasRole(bytes32, address) external returns (bool) envfree;
|
function hasRole(bytes32, address) external returns (bool) envfree;
|
||||||
function DEFAULT_ADMIN_ROLE() external returns (bytes32) envfree;
|
function DEFAULT_ADMIN_ROLE() external returns (bytes32) envfree;
|
||||||
function OPERATOR_ROLE() external returns (bytes32) envfree;
|
function OPERATOR_ROLE() external returns (bytes32) envfree;
|
||||||
|
function Math.mulDiv(uint256 a, uint256 b, uint256 c) internal returns uint256 => mulDivSummary(a,b,c);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mulDivSummary(uint256 a, uint256 b, uint256 c) returns uint256 {
|
||||||
|
require c != 0;
|
||||||
|
return require_uint256(a*b/c);
|
||||||
}
|
}
|
||||||
|
|
||||||
persistent ghost mathint sumOfDistributorAllocations {
|
persistent ghost mathint sumOfDistributorAllocations {
|
||||||
@@ -18,17 +28,6 @@ hook Sstore rewardDistributorAllocations[KEY address addr] uint256 newValue (uin
|
|||||||
sumOfDistributorAllocations = sumOfDistributorAllocations - oldValue + newValue;
|
sumOfDistributorAllocations = sumOfDistributorAllocations - oldValue + newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
invariant totalDistributorAllocationIsSumOfDistributorAllocations()
|
|
||||||
to_mathint(totalDistributorAllocation()) == sumOfDistributorAllocations
|
|
||||||
filtered {
|
|
||||||
f -> !isUpgradeFunction(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
rule externalSupplyIsLessOrEqThanTotalDistributorAllocation() {
|
|
||||||
assert externalSupply() <= totalDistributorAllocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
definition isUpgradeFunction(method f) returns bool = (
|
definition isUpgradeFunction(method f) returns bool = (
|
||||||
f.selector == sig:karma.upgradeToAndCall(address, bytes).selector ||
|
f.selector == sig:karma.upgradeToAndCall(address, bytes).selector ||
|
||||||
f.selector == sig:karma.upgradeTo(address).selector
|
f.selector == sig:karma.upgradeTo(address).selector
|
||||||
@@ -51,6 +50,22 @@ definition isOperatorFunction(method f) returns bool = (
|
|||||||
|| f.selector == sig:karma.mint(address, uint256).selector
|
|| f.selector == sig:karma.mint(address, uint256).selector
|
||||||
);
|
);
|
||||||
|
|
||||||
|
invariant totalDistributorAllocationIsSumOfDistributorAllocations()
|
||||||
|
to_mathint(totalDistributorAllocation()) == sumOfDistributorAllocations
|
||||||
|
filtered {
|
||||||
|
f -> !isUpgradeFunction(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// invariant slashAmountIsLessEqualToKarmaBalance(address account)
|
||||||
|
// rawBalanceOf(account) >= getSlashAmountForAccount(account)
|
||||||
|
// filtered {
|
||||||
|
// f -> !isUpgradeFunction(f) && !isERC20TransferFunction(f)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// rule externalSupplyIsLessOrEqThanTotalDistributorAllocation() {
|
||||||
|
// assert externalSupply() <= totalDistributorAllocation();
|
||||||
|
// }
|
||||||
|
|
||||||
rule erc20TransferIsDisabled(method f) {
|
rule erc20TransferIsDisabled(method f) {
|
||||||
env e;
|
env e;
|
||||||
calldataarg args;
|
calldataarg args;
|
||||||
|
|||||||
184
src/Karma.sol
184
src/Karma.sol
@@ -7,6 +7,7 @@ import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils
|
|||||||
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
||||||
import { IRewardDistributor } from "./interfaces/IRewardDistributor.sol";
|
import { IRewardDistributor } from "./interfaces/IRewardDistributor.sol";
|
||||||
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
||||||
|
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title Karma
|
* @title Karma
|
||||||
@@ -26,8 +27,28 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
error Karma__UnknownDistributor();
|
error Karma__UnknownDistributor();
|
||||||
/// @notice Emitted sender does not have the required role
|
/// @notice Emitted sender does not have the required role
|
||||||
error Karma__Unauthorized();
|
error Karma__Unauthorized();
|
||||||
|
/// @notice Emitted when slash percentage to set is invalid
|
||||||
|
error Karma__InvalidSlashPercentage();
|
||||||
|
/// @notice Emitted when balance to slash is invalid
|
||||||
|
error Karma__CannotSlashZeroBalance();
|
||||||
|
|
||||||
|
/// @notice Emitted when a reward distributor is added
|
||||||
event RewardDistributorAdded(address distributor);
|
event RewardDistributorAdded(address distributor);
|
||||||
|
/// @notice Emitted when a reward distributor is removed
|
||||||
|
event RewardDistributorRemoved(address distributor);
|
||||||
|
/// @notice Emitted when an account is slashed
|
||||||
|
event AccountSlashed(address indexed account, uint256 amount);
|
||||||
|
/// @notice Emitted when the slash percentage is updated
|
||||||
|
event SlashPercentageUpdated(uint256 oldPercentage, uint256 newPercentage);
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
CONSTATNS
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
/// @notice Maximum slash percentage (in basis points: 100% = 10000)
|
||||||
|
uint256 public constant MAX_SLASH_PERCENTAGE = 10_000;
|
||||||
|
/// @notice Minimum slash amount
|
||||||
|
uint256 public constant MIN_SLASH_AMOUNT = 1 ether;
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
STATE VARIABLES
|
STATE VARIABLES
|
||||||
@@ -39,13 +60,23 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
string public constant SYMBOL = "KARMA";
|
string public constant SYMBOL = "KARMA";
|
||||||
/// @notice The total allocation for all reward distributors
|
/// @notice The total allocation for all reward distributors
|
||||||
uint256 public totalDistributorAllocation;
|
uint256 public totalDistributorAllocation;
|
||||||
|
uint256 public totalSlashAmount;
|
||||||
/// @notice Set of reward distributors
|
/// @notice Set of reward distributors
|
||||||
EnumerableSet.AddressSet private rewardDistributors;
|
EnumerableSet.AddressSet private rewardDistributors;
|
||||||
/// @notice Mapping of reward distributor to allocation
|
/// @notice Mapping of reward distributor allocations
|
||||||
mapping(address distributor => uint256 allocation) public rewardDistributorAllocations;
|
mapping(address distributor => uint256 allocation) public rewardDistributorAllocations;
|
||||||
|
/// @notice Mapping of reward distributor slash amounts for individual accounts
|
||||||
|
mapping(address distributor => mapping(address account => uint256 slashAmount)) public rewardDistributorSlashAmount;
|
||||||
|
/// @notice Mapping of accounts to their slashed amount for internal balance
|
||||||
|
mapping(address account => uint256 slashAmount) public accountSlashAmount;
|
||||||
|
/// @notice Percentage of Karma to slash (in basis points: 1% = 100, 10% = 1000, 100% = 10000)
|
||||||
|
uint256 public slashPercentage;
|
||||||
|
|
||||||
/// @notice Operator role keccak256("OPERATOR_ROLE")
|
/// @notice Operator role keccak256("OPERATOR_ROLE")
|
||||||
bytes32 public constant OPERATOR_ROLE = 0x97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929;
|
bytes32 public constant OPERATOR_ROLE = 0x97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929;
|
||||||
|
/// @notice Slasher role keccak256("SLASHER_ROLE")
|
||||||
|
bytes32 public constant SLASHER_ROLE = 0x12b42e8a160f6064dc959c6f251e3af0750ad213dbecf573b4710d67d6c28e39;
|
||||||
|
|
||||||
/// @notice Gap for upgrade safety.
|
/// @notice Gap for upgrade safety.
|
||||||
// solhint-disable-next-line
|
// solhint-disable-next-line
|
||||||
uint256[30] private __gap_Karma;
|
uint256[30] private __gap_Karma;
|
||||||
@@ -58,6 +89,14 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @notice Modifier to check if sender has slasher role
|
||||||
|
modifier onlySlasher() {
|
||||||
|
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && !hasRole(SLASHER_ROLE, msg.sender)) {
|
||||||
|
revert Karma__Unauthorized();
|
||||||
|
}
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
CONSTRUCTOR
|
CONSTRUCTOR
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
@@ -77,7 +116,9 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
__ERC20_init(NAME, SYMBOL);
|
__ERC20_init(NAME, SYMBOL);
|
||||||
__UUPSUpgradeable_init();
|
__UUPSUpgradeable_init();
|
||||||
__AccessControl_init();
|
__AccessControl_init();
|
||||||
|
|
||||||
_setupRole(DEFAULT_ADMIN_ROLE, _owner);
|
_setupRole(DEFAULT_ADMIN_ROLE, _owner);
|
||||||
|
slashPercentage = 5000; // 50%
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -103,6 +144,20 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
_removeRewardDistributor(distributor);
|
_removeRewardDistributor(distributor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Sets the slash percentage for the contract.
|
||||||
|
* @dev Only the admin configure the slash percentage
|
||||||
|
* @param percentage The percentage to set (in basis points: 1% = 100, 10% = 1000, 100% = 10000)
|
||||||
|
*/
|
||||||
|
function setSlashPercentage(uint256 percentage) public onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||||
|
if (percentage > 10_000) {
|
||||||
|
revert Karma__InvalidSlashPercentage();
|
||||||
|
}
|
||||||
|
uint256 oldPercentage = slashPercentage;
|
||||||
|
slashPercentage = percentage;
|
||||||
|
emit SlashPercentageUpdated(oldPercentage, percentage);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notice Sets the reward for a reward distributor.
|
* @notice Sets the reward for a reward distributor.
|
||||||
* @dev Only the owner can set the reward for a reward distributor.
|
* @dev Only the owner can set the reward for a reward distributor.
|
||||||
@@ -135,6 +190,20 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
_mint(account, amount);
|
_mint(account, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Slashes karma from an account based on the current slashing percentage
|
||||||
|
* @dev Only accounts with the SLASHER_ROLE can call this function
|
||||||
|
* @param account Account to slash
|
||||||
|
* @return slashedAmount The amount of karma that was slashed
|
||||||
|
*/
|
||||||
|
function slash(address account) public virtual onlySlasher returns (uint256) {
|
||||||
|
return _slash(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateSlashAmount(uint256 value) public view returns (uint256) {
|
||||||
|
return _calculateSlashAmount(value);
|
||||||
|
}
|
||||||
|
|
||||||
function transfer(address, uint256) public pure override returns (bool) {
|
function transfer(address, uint256) public pure override returns (bool) {
|
||||||
revert Karma__TransfersNotAllowed();
|
revert Karma__TransfersNotAllowed();
|
||||||
}
|
}
|
||||||
@@ -155,6 +224,15 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
return super.totalSupply() + _externalSupply();
|
return super.totalSupply() + _externalSupply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Returns the internal total supply of the token.
|
||||||
|
* @dev The internal total supply is the total supply of the token without the external supply.
|
||||||
|
* @return The internal total supply of the token.
|
||||||
|
*/
|
||||||
|
function _internalTotalSupply() internal view returns (uint256) {
|
||||||
|
return super.totalSupply();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notice Returns the external supply of the token.
|
* @notice Returns the external supply of the token.
|
||||||
* @dev The external supply is the sum of the rewards from all reward distributors.
|
* @dev The external supply is the sum of the rewards from all reward distributors.
|
||||||
@@ -176,6 +254,16 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
return externalSupply;
|
return externalSupply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Returns the internal balance of an account.
|
||||||
|
* @dev This function is used to get the internal balance of an account.
|
||||||
|
* @param account The address of the account to get the internal balance of.
|
||||||
|
* @return The internal balance of the account.
|
||||||
|
*/
|
||||||
|
function _internalBalanceOf(address account) internal view returns (uint256) {
|
||||||
|
return super.balanceOf(account);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notice Authorizes contract upgrades via UUPS.
|
* @notice Authorizes contract upgrades via UUPS.
|
||||||
* @dev This function is only callable by the owner.
|
* @dev This function is only callable by the owner.
|
||||||
@@ -194,7 +282,6 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
if (rewardDistributors.contains(distributor)) {
|
if (rewardDistributors.contains(distributor)) {
|
||||||
revert Karma__DistributorAlreadyAdded();
|
revert Karma__DistributorAlreadyAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
rewardDistributors.add(distributor);
|
rewardDistributors.add(distributor);
|
||||||
emit RewardDistributorAdded(distributor);
|
emit RewardDistributorAdded(distributor);
|
||||||
}
|
}
|
||||||
@@ -208,6 +295,7 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
revert Karma__UnknownDistributor();
|
revert Karma__UnknownDistributor();
|
||||||
}
|
}
|
||||||
rewardDistributors.remove(distributor);
|
rewardDistributors.remove(distributor);
|
||||||
|
emit RewardDistributorRemoved(distributor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,6 +312,78 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
IRewardDistributor(rewardsDistributor).setReward(amount, duration);
|
IRewardDistributor(rewardsDistributor).setReward(amount, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Slashes karma from an account based on the current slashing percentage
|
||||||
|
* @param account Account to slash
|
||||||
|
* @return slashedAmount The amount of karma that was slashed
|
||||||
|
*/
|
||||||
|
function _slash(address account) internal virtual returns (uint256) {
|
||||||
|
uint256 currentBalance = balanceOf(account);
|
||||||
|
if (currentBalance == 0) {
|
||||||
|
revert Karma__CannotSlashZeroBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 totalAmountToSlash;
|
||||||
|
|
||||||
|
// first, slash all reward distributors
|
||||||
|
for (uint256 i = 0; i < rewardDistributors.length(); i++) {
|
||||||
|
address distributor = rewardDistributors.at(i);
|
||||||
|
uint256 currentDistributorAccountBalance = IRewardDistributor(distributor).rewardsBalanceOfAccount(account);
|
||||||
|
uint256 currentDistributorSlashAmount = rewardDistributorSlashAmount[distributor][account];
|
||||||
|
|
||||||
|
uint256 distributorAmountToSlash =
|
||||||
|
_calculateSlashAmount(currentDistributorAccountBalance - currentDistributorSlashAmount);
|
||||||
|
|
||||||
|
rewardDistributorSlashAmount[distributor][account] += distributorAmountToSlash;
|
||||||
|
totalAmountToSlash += distributorAmountToSlash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// then, slash internal balance
|
||||||
|
uint256 amountToSlash = _calculateSlashAmount(super.balanceOf(account) - accountSlashAmount[account]);
|
||||||
|
accountSlashAmount[account] += amountToSlash;
|
||||||
|
totalAmountToSlash += amountToSlash;
|
||||||
|
totalSlashAmount += totalAmountToSlash;
|
||||||
|
|
||||||
|
emit AccountSlashed(account, totalAmountToSlash);
|
||||||
|
return totalAmountToSlash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Calculates the amount to slash from a given balance, falling back to the minimum slash amount if
|
||||||
|
* necessary.
|
||||||
|
*/
|
||||||
|
function _calculateSlashAmount(uint256 balance) internal view returns (uint256) {
|
||||||
|
uint256 amountToSlash = Math.mulDiv(balance, slashPercentage, MAX_SLASH_PERCENTAGE);
|
||||||
|
if (amountToSlash < MIN_SLASH_AMOUNT) {
|
||||||
|
if (balance < MIN_SLASH_AMOUNT) {
|
||||||
|
// Not enough balance for minimum slash, slash entire balance
|
||||||
|
amountToSlash = balance;
|
||||||
|
} else {
|
||||||
|
amountToSlash = MIN_SLASH_AMOUNT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return amountToSlash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Returns the raw balance of an account.
|
||||||
|
*/
|
||||||
|
function _rawBalanceAndSlashAmountOf(address account) internal view returns (uint256, uint256) {
|
||||||
|
uint256 externalBalance;
|
||||||
|
uint256 slashedAmount;
|
||||||
|
|
||||||
|
// first, aggregate all slashed amounts from reward distributors
|
||||||
|
for (uint256 i = 0; i < rewardDistributors.length(); i++) {
|
||||||
|
address distributor = rewardDistributors.at(i);
|
||||||
|
externalBalance += IRewardDistributor(distributor).rewardsBalanceOfAccount(account);
|
||||||
|
slashedAmount += rewardDistributorSlashAmount[distributor][account];
|
||||||
|
}
|
||||||
|
// then, add the slashed amount from the internal balance
|
||||||
|
slashedAmount += accountSlashAmount[account];
|
||||||
|
|
||||||
|
return (super.balanceOf(account) + externalBalance, slashedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
function _overflowCheck(uint256 amount) internal view {
|
function _overflowCheck(uint256 amount) internal view {
|
||||||
// This will revert if `amount` overflows the total supply
|
// This will revert if `amount` overflows the total supply
|
||||||
super.totalSupply() + totalDistributorAllocation + amount;
|
super.totalSupply() + totalDistributorAllocation + amount;
|
||||||
@@ -257,14 +417,22 @@ contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessContro
|
|||||||
* @return The balance of the account.
|
* @return The balance of the account.
|
||||||
*/
|
*/
|
||||||
function balanceOf(address account) public view override returns (uint256) {
|
function balanceOf(address account) public view override returns (uint256) {
|
||||||
uint256 externalBalance;
|
(uint256 rawBalance, uint256 slashedAmount) = _rawBalanceAndSlashAmountOf(account);
|
||||||
|
// Subtract slashed amount
|
||||||
for (uint256 i = 0; i < rewardDistributors.length(); i++) {
|
if (slashedAmount >= rawBalance) {
|
||||||
address distributor = rewardDistributors.at(i);
|
return 0;
|
||||||
externalBalance += IRewardDistributor(distributor).rewardsBalanceOfAccount(account);
|
|
||||||
}
|
}
|
||||||
|
return rawBalance - slashedAmount;
|
||||||
|
}
|
||||||
|
|
||||||
return super.balanceOf(account) + externalBalance;
|
/**
|
||||||
|
* @notice Returns the total slash amount of an account
|
||||||
|
* @param account The account to get the slash amount of.
|
||||||
|
* @return The slash amount of the account.
|
||||||
|
*/
|
||||||
|
function slashedAmountOf(address account) public view returns (uint256) {
|
||||||
|
(, uint256 slashAmount) = _rawBalanceAndSlashAmountOf(account);
|
||||||
|
return slashAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowance(address, address) public pure override returns (uint256) {
|
function allowance(address, address) public pure override returns (uint256) {
|
||||||
|
|||||||
165
test/Karma.t.sol
165
test/Karma.t.sol
@@ -341,3 +341,168 @@ contract OverflowTest is KarmaTest {
|
|||||||
karma.setReward(address(distributor1), 1e18, 1000);
|
karma.setReward(address(distributor1), 1e18, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contract SlashAmountOfTest is KarmaTest {
|
||||||
|
address public slasher = makeAddr("slasher");
|
||||||
|
|
||||||
|
function _mintKarmaToAccount(address account, uint256 amount) internal {
|
||||||
|
vm.startPrank(owner);
|
||||||
|
karma.mint(account, amount);
|
||||||
|
vm.stopPrank();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUp() public override {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
vm.startPrank(owner);
|
||||||
|
karma.grantRole(karma.SLASHER_ROLE(), slasher);
|
||||||
|
vm.stopPrank();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_SlashAmountOf() public {
|
||||||
|
uint256 accountBalance = 100 ether;
|
||||||
|
uint256 distributorBalance = 50 ether;
|
||||||
|
_mintKarmaToAccount(alice, accountBalance);
|
||||||
|
vm.prank(owner);
|
||||||
|
distributor1.setUserKarmaShare(alice, distributorBalance);
|
||||||
|
|
||||||
|
vm.prank(owner);
|
||||||
|
karma.slash(alice);
|
||||||
|
|
||||||
|
uint256 slashedAmount = karma.slashedAmountOf(alice);
|
||||||
|
assertEq(
|
||||||
|
slashedAmount, karma.calculateSlashAmount(accountBalance) + karma.calculateSlashAmount(distributorBalance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFuzz_SlashAmountOf(
|
||||||
|
uint256 accountBalance,
|
||||||
|
uint256 distributor1Balance,
|
||||||
|
uint256 distributor2Balance
|
||||||
|
)
|
||||||
|
public
|
||||||
|
{
|
||||||
|
// adding some bounds here to ensure we don't overflow
|
||||||
|
vm.assume(accountBalance < 1e30);
|
||||||
|
vm.assume(distributor1Balance < 1e30);
|
||||||
|
vm.assume(distributor2Balance < 1e30);
|
||||||
|
|
||||||
|
_mintKarmaToAccount(alice, accountBalance);
|
||||||
|
vm.startPrank(owner);
|
||||||
|
distributor1.setUserKarmaShare(alice, distributor1Balance);
|
||||||
|
distributor2.setUserKarmaShare(alice, distributor2Balance);
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
vm.prank(owner);
|
||||||
|
karma.slash(alice);
|
||||||
|
|
||||||
|
uint256 slashedAmount = karma.slashedAmountOf(alice);
|
||||||
|
uint256 expectedSlashAmount = karma.calculateSlashAmount(accountBalance)
|
||||||
|
+ karma.calculateSlashAmount(distributor1Balance) + karma.calculateSlashAmount(distributor2Balance);
|
||||||
|
assertEq(slashedAmount, expectedSlashAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract SlashTest is KarmaTest {
|
||||||
|
address public slasher = makeAddr("slasher");
|
||||||
|
|
||||||
|
function _mintKarmaToAccount(address account, uint256 amount) internal {
|
||||||
|
vm.startPrank(owner);
|
||||||
|
karma.mint(account, amount);
|
||||||
|
vm.stopPrank();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUp() public override {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
vm.startPrank(owner);
|
||||||
|
karma.grantRole(karma.SLASHER_ROLE(), slasher);
|
||||||
|
vm.stopPrank();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_RevertWhen_SenderIsNotDefaultAdminOrSlasher() public {
|
||||||
|
vm.prank(makeAddr("someone"));
|
||||||
|
vm.expectRevert(Karma.Karma__Unauthorized.selector);
|
||||||
|
karma.slash(alice);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_RevertWhen_KarmaBalanceIsInvalid() public {
|
||||||
|
vm.prank(slasher);
|
||||||
|
vm.expectRevert(Karma.Karma__CannotSlashZeroBalance.selector);
|
||||||
|
karma.slash(alice);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_SlashRemainingBalanceIfBalanceIsLow() public {
|
||||||
|
_mintKarmaToAccount(alice, karma.MIN_SLASH_AMOUNT() - 1);
|
||||||
|
|
||||||
|
vm.prank(slasher);
|
||||||
|
karma.slash(alice);
|
||||||
|
|
||||||
|
assertEq(karma.balanceOf(alice), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_Slash() public {
|
||||||
|
// ensure rewards
|
||||||
|
uint256 currentBalance = 100 ether;
|
||||||
|
_mintKarmaToAccount(alice, currentBalance);
|
||||||
|
uint256 slashedAmount = karma.calculateSlashAmount(currentBalance);
|
||||||
|
|
||||||
|
// slash the account
|
||||||
|
vm.prank(slasher);
|
||||||
|
karma.slash(alice);
|
||||||
|
assertEq(karma.balanceOf(alice), currentBalance - slashedAmount);
|
||||||
|
|
||||||
|
currentBalance = karma.balanceOf(alice);
|
||||||
|
slashedAmount = karma.calculateSlashAmount(currentBalance);
|
||||||
|
|
||||||
|
// slash again
|
||||||
|
vm.prank(slasher);
|
||||||
|
karma.slash(alice);
|
||||||
|
|
||||||
|
assertEq(karma.balanceOf(alice), currentBalance - slashedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFuzz_Slash(uint256 rewardsAmount) public {
|
||||||
|
vm.assume(rewardsAmount > 0);
|
||||||
|
_mintKarmaToAccount(alice, rewardsAmount);
|
||||||
|
|
||||||
|
vm.prank(slasher);
|
||||||
|
karma.slash(alice);
|
||||||
|
uint256 slashedAmount = karma.slashedAmountOf(alice);
|
||||||
|
|
||||||
|
assertEq(karma.balanceOf(alice), rewardsAmount - slashedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRemoveRewardDistributorShouldReduceSlashAmount() public {
|
||||||
|
uint256 distributorRewards = 1000 ether;
|
||||||
|
uint256 mintedRewards = 1000 ether;
|
||||||
|
uint256 totalRewards = distributorRewards + mintedRewards;
|
||||||
|
|
||||||
|
// set up rewards for alice
|
||||||
|
vm.prank(owner);
|
||||||
|
distributor1.setUserKarmaShare(alice, distributorRewards);
|
||||||
|
_mintKarmaToAccount(alice, mintedRewards);
|
||||||
|
assertEq(distributor1.rewardsBalanceOfAccount(alice), distributorRewards);
|
||||||
|
assertEq(karma.balanceOf(alice), totalRewards);
|
||||||
|
|
||||||
|
// slash alice
|
||||||
|
uint256 accountSlashAmount = karma.calculateSlashAmount(mintedRewards);
|
||||||
|
uint256 distributorSlashAmount = karma.calculateSlashAmount(distributorRewards);
|
||||||
|
vm.prank(owner);
|
||||||
|
karma.slash(alice);
|
||||||
|
|
||||||
|
uint256 totalSlashAmount = karma.slashedAmountOf(alice);
|
||||||
|
|
||||||
|
assertEq(karma.accountSlashAmount(alice), accountSlashAmount);
|
||||||
|
assertEq(karma.rewardDistributorSlashAmount(address(distributor1), alice), distributorSlashAmount);
|
||||||
|
assertEq(karma.slashedAmountOf(alice), totalSlashAmount);
|
||||||
|
assertEq(karma.balanceOf(alice), totalRewards - totalSlashAmount);
|
||||||
|
|
||||||
|
// remove the distributor
|
||||||
|
vm.prank(owner);
|
||||||
|
karma.removeRewardDistributor(address(distributor1));
|
||||||
|
totalSlashAmount = karma.slashedAmountOf(alice);
|
||||||
|
assertEq(karma.accountSlashAmount(alice), accountSlashAmount);
|
||||||
|
assertEq(karma.balanceOf(alice), totalRewards - distributorRewards - totalSlashAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user