mirror of
https://github.com/vacp2p/staking-reward-streamer.git
synced 2026-01-08 23:08:19 -05:00
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
This commit is contained in:
92
.gas-report
92
.gas-report
@@ -10,7 +10,7 @@
|
||||
|-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||
|-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| fallback | 746 | 135370 | 193312 | 193348 | 500 |
|
||||
| fallback | 666 | 112892 | 97112 | 193429 | 693 |
|
||||
╰-------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
|
||||
|
||||
╭-----------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
||||
@@ -18,13 +18,13 @@
|
||||
+===============================================================================================================+
|
||||
| Deployment Cost | Deployment Size | | | | |
|
||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||
| 4746226 | 22993 | | | | |
|
||||
| 5135751 | 24812 | | | | |
|
||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||
| | | | | | |
|
||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||
|-----------------------------------------------------+-----------------+---------+---------+---------+---------|
|
||||
| run | 3966846 | 3966846 | 3966846 | 3966846 | 118 |
|
||||
| run | 4330203 | 4330203 | 4330203 | 4330203 | 152 |
|
||||
╰-----------------------------------------------------+-----------------+---------+---------+---------+---------╯
|
||||
|
||||
╭-----------------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
||||
@@ -66,7 +66,7 @@
|
||||
|---------------------------------------------------------+-----------------+-----+--------+-----+---------|
|
||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||
|---------------------------------------------------------+-----------------+-----+--------+-----+---------|
|
||||
| activeNetworkConfig | 455 | 455 | 455 | 455 | 346 |
|
||||
| activeNetworkConfig | 455 | 455 | 455 | 455 | 414 |
|
||||
╰---------------------------------------------------------+-----------------+-----+--------+-----+---------╯
|
||||
|
||||
╭---------------------------------------------------------------------+-----------------+---------+---------+---------+---------╮
|
||||
@@ -88,41 +88,43 @@
|
||||
+=====================================================================================+
|
||||
| Deployment Cost | Deployment Size | | | | |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| 0 | 9875 | | | | |
|
||||
| 0 | 11694 | | | | |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| | | | | | |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| acceptOwnership | 12020 | 12020 | 12020 | 12020 | 1 |
|
||||
| DEFAULT_ADMIN_ROLE | 306 | 306 | 306 | 306 | 19 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| addRewardDistributor | 2589 | 65756 | 70586 | 70586 | 152 |
|
||||
| OPERATOR_ROLE | 283 | 283 | 283 | 283 | 2 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| allowance | 482 | 482 | 482 | 482 | 3 |
|
||||
| addRewardDistributor | 29894 | 64182 | 70797 | 70797 | 232 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| approve | 419 | 419 | 419 | 419 | 3 |
|
||||
| allowance | 504 | 504 | 504 | 504 | 6 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| balanceOf | 10019 | 13685 | 10019 | 21019 | 9 |
|
||||
| approve | 441 | 441 | 441 | 441 | 6 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| getRewardDistributors | 1140 | 3384 | 3384 | 5628 | 6 |
|
||||
| balanceOf | 10085 | 13751 | 10085 | 21085 | 18 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| initialize | 95872 | 95872 | 95872 | 95872 | 118 |
|
||||
| getRewardDistributors | 1119 | 3523 | 5607 | 5607 | 17 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| mint | 2632 | 37628 | 51197 | 51197 | 14 |
|
||||
| grantRole | 29440 | 29440 | 29440 | 29440 | 5 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| owner | 363 | 1029 | 363 | 2363 | 3 |
|
||||
| hasRole | 685 | 2185 | 2685 | 2685 | 4 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| removeRewardDistributor | 2632 | 12148 | 4824 | 28990 | 9 |
|
||||
| initialize | 94595 | 94595 | 94595 | 94595 | 152 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| setReward | 9233 | 156626 | 166624 | 166624 | 284 |
|
||||
| mint | 4790 | 38817 | 51239 | 51239 | 26 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalSupply | 3545 | 7545 | 9545 | 9545 | 9 |
|
||||
| removeRewardDistributor | 5044 | 22060 | 29223 | 29959 | 21 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| transfer | 417 | 417 | 417 | 417 | 3 |
|
||||
| setReward | 4832 | 147872 | 166705 | 166705 | 307 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| transferFrom | 511 | 511 | 511 | 511 | 3 |
|
||||
| totalSupply | 3567 | 7567 | 9567 | 9567 | 18 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| transferOwnership | 26328 | 26328 | 26328 | 26328 | 1 |
|
||||
| transfer | 439 | 439 | 439 | 439 | 6 |
|
||||
|------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| transferFrom | 511 | 511 | 511 | 511 | 6 |
|
||||
╰------------------------------+-----------------+--------+--------+--------+---------╯
|
||||
|
||||
╭-------------------------------------------------+-----------------+-------+--------+-------+---------╮
|
||||
@@ -184,7 +186,7 @@
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| getAccountVaults | 5230 | 5230 | 5230 | 5230 | 4 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| getVault | 1653 | 5710 | 1653 | 13653 | 4182 |
|
||||
| getVault | 1653 | 5709 | 1653 | 13653 | 4180 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| initialize | 92752 | 92752 | 92752 | 92752 | 95 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
@@ -192,7 +194,7 @@
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| leave | 66348 | 66348 | 66348 | 66348 | 2 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| lock | 7040 | 43178 | 46713 | 87964 | 1034 |
|
||||
| lock | 7040 | 43426 | 46713 | 87964 | 1034 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| migrateToVault | 9294 | 53513 | 17021 | 170715 | 4 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
@@ -210,7 +212,7 @@
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| rewardStartTime | 364 | 1364 | 1364 | 2364 | 2 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| rewardsBalanceOf | 2295 | 3505 | 3908 | 6295 | 268 |
|
||||
| rewardsBalanceOf | 2295 | 3511 | 3908 | 6295 | 268 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| rewardsBalanceOfAccount | 10220 | 10220 | 10220 | 10220 | 1 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
@@ -220,33 +222,33 @@
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| setTrustedCodehash | 24238 | 24238 | 24238 | 24238 | 95 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| stake | 2639 | 131046 | 60725 | 228623 | 2670 |
|
||||
| stake | 2639 | 131085 | 60725 | 228623 | 2670 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| stakedBalanceOf | 2622 | 2622 | 2622 | 2622 | 1 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalMP | 805 | 1257 | 1257 | 1710 | 6 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalMPAccrued | 385 | 1064 | 385 | 2385 | 4162 |
|
||||
| totalMPAccrued | 385 | 1064 | 385 | 2385 | 4160 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalMPStaked | 429 | 1107 | 429 | 2429 | 4165 |
|
||||
| totalMPStaked | 429 | 1107 | 429 | 2429 | 4163 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalMaxMP | 407 | 1086 | 407 | 2407 | 4162 |
|
||||
| totalMaxMP | 407 | 1086 | 407 | 2407 | 4160 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalRewardsAccrued | 407 | 407 | 407 | 407 | 3 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalRewardsSupply | 998 | 1627 | 1792 | 6737 | 290 |
|
||||
| totalRewardsSupply | 998 | 1629 | 1792 | 6737 | 290 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalShares | 597 | 597 | 597 | 597 | 6 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| totalStaked | 408 | 1086 | 408 | 2408 | 4169 |
|
||||
| totalStaked | 408 | 1086 | 408 | 2408 | 4167 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| unstake | 9886 | 41014 | 39781 | 79550 | 271 |
|
||||
| unstake | 9886 | 41548 | 39781 | 79550 | 271 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| updateAccount | 347677 | 347677 | 347677 | 347677 | 1 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| updateGlobalState | 15820 | 25876 | 29230 | 29230 | 8 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| updateVault | 31948 | 34282 | 31948 | 110579 | 1024 |
|
||||
| updateVault | 31948 | 34368 | 31948 | 110579 | 1022 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| upgradeTo | 10279 | 10772 | 10279 | 12745 | 5 |
|
||||
|--------------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
@@ -274,9 +276,9 @@
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| leave | 12223 | 113138 | 84120 | 356510 | 5 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| lock | 12151 | 58671 | 62251 | 103499 | 1035 |
|
||||
| lock | 12151 | 58918 | 62251 | 103499 | 1035 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| lockUntil | 363 | 1743 | 2363 | 2363 | 7758 |
|
||||
| lockUntil | 363 | 1744 | 2363 | 2363 | 7766 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| migrateToVault | 24910 | 77530 | 32637 | 219937 | 4 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
@@ -284,15 +286,15 @@
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| register | 12742 | 78218 | 78761 | 78761 | 374 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| stake | 12131 | 165238 | 76290 | 284275 | 2671 |
|
||||
| stake | 12131 | 165292 | 76290 | 284275 | 2671 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| stakeManager | 393 | 393 | 393 | 393 | 373 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| trustStakeManager | 7650 | 7650 | 7650 | 7650 | 1 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| unstake | 12108 | 57512 | 55296 | 110656 | 272 |
|
||||
| unstake | 12108 | 58273 | 55296 | 110656 | 272 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| updateLockUntil | 4432 | 20765 | 21532 | 21532 | 509 |
|
||||
| updateLockUntil | 4432 | 20761 | 21532 | 21532 | 506 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
| withdraw | 20817 | 20817 | 20817 | 20817 | 1 |
|
||||
|----------------------------------------+-----------------+--------+--------+--------+---------|
|
||||
@@ -310,9 +312,9 @@
|
||||
|----------------------------------------------------+-----------------+------+--------+--------+---------|
|
||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||
|----------------------------------------------------+-----------------+------+--------+--------+---------|
|
||||
| fallback | 708 | 6172 | 2125 | 374054 | 23167 |
|
||||
| fallback | 708 | 6172 | 2125 | 374054 | 23155 |
|
||||
|----------------------------------------------------+-----------------+------+--------+--------+---------|
|
||||
| implementation | 346 | 2136 | 2346 | 2346 | 4871 |
|
||||
| implementation | 346 | 2137 | 2346 | 2346 | 4868 |
|
||||
╰----------------------------------------------------+-----------------+------+--------+--------+---------╯
|
||||
|
||||
╭--------------------------------------------+-----------------+--------+--------+--------+---------╮
|
||||
@@ -336,7 +338,7 @@
|
||||
+===============================================================================================================================================+
|
||||
| Deployment Cost | Deployment Size | | | | |
|
||||
|------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| 1204853 | 6015 | | | | |
|
||||
| 1204853 | 6207 | | | | |
|
||||
|------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| | | | | | |
|
||||
|------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
@@ -382,13 +384,13 @@
|
||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| Function Name | Min | Avg | Median | Max | # Calls |
|
||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| rewardsBalanceOfAccount | 549 | 1882 | 2549 | 2549 | 18 |
|
||||
| rewardsBalanceOfAccount | 549 | 1882 | 2549 | 2549 | 36 |
|
||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| setTotalKarmaShares | 43589 | 43589 | 43589 | 43589 | 18 |
|
||||
| setTotalKarmaShares | 43589 | 43589 | 43589 | 43589 | 36 |
|
||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| setUserKarmaShare | 44194 | 44194 | 44194 | 44194 | 6 |
|
||||
| setUserKarmaShare | 44194 | 44194 | 44194 | 44194 | 12 |
|
||||
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| totalRewardsSupply | 324 | 324 | 324 | 324 | 18 |
|
||||
| totalRewardsSupply | 324 | 324 | 324 | 324 | 36 |
|
||||
╰-------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
|
||||
|
||||
╭---------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
|
||||
@@ -410,7 +412,7 @@
|
||||
+==================================================================================================+
|
||||
| Deployment Cost | Deployment Size | | | | |
|
||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| 770741 | 3987 | | | | |
|
||||
| 770657 | 3987 | | | | |
|
||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| | | | | | |
|
||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
@@ -418,7 +420,7 @@
|
||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| approve | 29075 | 31545 | 29183 | 46259 | 2676 |
|
||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| balanceOf | 561 | 1346 | 561 | 2561 | 4960 |
|
||||
| balanceOf | 561 | 1345 | 561 | 2561 | 4958 |
|
||||
|---------------------------------------------+-----------------+-------+--------+-------+---------|
|
||||
| mint | 33964 | 37190 | 34072 | 68248 | 2685 |
|
||||
╰---------------------------------------------+-----------------+-------+--------+-------+---------╯
|
||||
|
||||
120
.gas-snapshot
120
.gas-snapshot
@@ -1,3 +1,13 @@
|
||||
AddRewardDistributorTest:testAddKarmaDistributorOnlyAdmin() (gas: 423055)
|
||||
AddRewardDistributorTest:testAddRewardDistributorAsOtherAdmin() (gas: 165263)
|
||||
AddRewardDistributorTest:testBalanceOf() (gas: 431293)
|
||||
AddRewardDistributorTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49655)
|
||||
AddRewardDistributorTest:testMintOnlyAdmin() (gas: 378769)
|
||||
AddRewardDistributorTest:testRemoveKarmaDistributorOnlyOwner() (gas: 147308)
|
||||
AddRewardDistributorTest:testRemoveUnknownKarmaDistributor() (gas: 41630)
|
||||
AddRewardDistributorTest:testTotalSupply() (gas: 339166)
|
||||
AddRewardDistributorTest:testTransfersNotAllowed() (gas: 40285)
|
||||
AddRewardDistributorTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 68325)
|
||||
EmergencyExitTest:test_CannotEnableEmergencyModeTwice() (gas: 93554)
|
||||
EmergencyExitTest:test_CannotLeaveBeforeEmergencyMode() (gas: 336067)
|
||||
EmergencyExitTest:test_EmergencyExitBasic() (gas: 427580)
|
||||
@@ -6,15 +16,15 @@ EmergencyExitTest:test_EmergencyExitToAlternateAddress() (gas: 433110)
|
||||
EmergencyExitTest:test_EmergencyExitWithLock() (gas: 433444)
|
||||
EmergencyExitTest:test_EmergencyExitWithRewards() (gas: 419310)
|
||||
EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39176)
|
||||
FuzzTests:testFuzz_AccrueMP(uint128,uint64,uint64) (runs: 1006, μ: 397033, ~: 368037)
|
||||
FuzzTests:testFuzz_AccrueMP_Relock(uint128,uint64,uint64,uint64) (runs: 1006, μ: 502073, ~: 471734)
|
||||
FuzzTests:testFuzz_EmergencyExit(uint256,uint256) (runs: 1001, μ: 497104, ~: 487267)
|
||||
FuzzTests:testFuzz_Lock(uint256,uint64) (runs: 1006, μ: 727730, ~: 726735)
|
||||
FuzzTests:testFuzz_Relock(uint256,uint64,uint64) (runs: 1006, μ: 409301, ~: 388725)
|
||||
FuzzTests:testFuzz_Rewards(uint256,uint256,uint256,uint16,uint16) (runs: 1001, μ: 599762, ~: 601124)
|
||||
FuzzTests:testFuzz_Stake(uint256,uint64) (runs: 1006, μ: 311991, ~: 285086)
|
||||
FuzzTests:testFuzz_Unstake(uint128,uint64,uint16,uint128) (runs: 1006, μ: 498758, ~: 473111)
|
||||
FuzzTests:testFuzz_UpdateVault(uint128,uint64,uint64) (runs: 1006, μ: 397056, ~: 368060)
|
||||
FuzzTests:testFuzz_AccrueMP(uint128,uint64,uint64) (runs: 1006, μ: 400351, ~: 368061)
|
||||
FuzzTests:testFuzz_AccrueMP_Relock(uint128,uint64,uint64,uint64) (runs: 1006, μ: 501707, ~: 471734)
|
||||
FuzzTests:testFuzz_EmergencyExit(uint256,uint256) (runs: 1001, μ: 497146, ~: 487267)
|
||||
FuzzTests:testFuzz_Lock(uint256,uint64) (runs: 1006, μ: 727489, ~: 726735)
|
||||
FuzzTests:testFuzz_Relock(uint256,uint64,uint64) (runs: 1006, μ: 409218, ~: 388725)
|
||||
FuzzTests:testFuzz_Rewards(uint256,uint256,uint256,uint16,uint16) (runs: 1001, μ: 599846, ~: 601205)
|
||||
FuzzTests:testFuzz_Stake(uint256,uint64) (runs: 1006, μ: 311868, ~: 285086)
|
||||
FuzzTests:testFuzz_Unstake(uint128,uint64,uint16,uint128) (runs: 1006, μ: 501292, ~: 473125)
|
||||
FuzzTests:testFuzz_UpdateVault(uint128,uint64,uint64) (runs: 1006, μ: 400374, ~: 368084)
|
||||
IntegrationTest:testStakeFoo() (gas: 1362931)
|
||||
KarmaNFTTest:testApproveNotAllowed() (gas: 10507)
|
||||
KarmaNFTTest:testGetApproved() (gas: 10531)
|
||||
@@ -26,24 +36,24 @@ KarmaNFTTest:testSetMetadataGenerator() (gas: 1010377)
|
||||
KarmaNFTTest:testSetMetadataGeneratorRevert() (gas: 1006937)
|
||||
KarmaNFTTest:testTokenURI() (gas: 1105935)
|
||||
KarmaNFTTest:testTransferNotAllowed() (gas: 10701)
|
||||
KarmaOwnershipTest:testAddKarmaDistributorOnlyOwner() (gas: 364768)
|
||||
KarmaOwnershipTest:testBalanceOf() (gas: 431045)
|
||||
KarmaOwnershipTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49479)
|
||||
KarmaOwnershipTest:testInitialOwner() (gas: 17601)
|
||||
KarmaOwnershipTest:testMintOnlyOwner() (gas: 376410)
|
||||
KarmaOwnershipTest:testOwnershipTransfer() (gas: 98047)
|
||||
KarmaOwnershipTest:testRemoveKarmaDistributorOnlyOwner() (gas: 88820)
|
||||
KarmaOwnershipTest:testRemoveUnknownKarmaDistributor() (gas: 41398)
|
||||
KarmaOwnershipTest:testTotalSupply() (gas: 338940)
|
||||
KarmaOwnershipTest:testTransfersNotAllowed() (gas: 40196)
|
||||
KarmaTest:testAddKarmaDistributorOnlyOwner() (gas: 364768)
|
||||
KarmaTest:testBalanceOf() (gas: 431045)
|
||||
KarmaTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49545)
|
||||
KarmaTest:testMintOnlyOwner() (gas: 376410)
|
||||
KarmaTest:testRemoveKarmaDistributorOnlyOwner() (gas: 88798)
|
||||
KarmaTest:testRemoveUnknownKarmaDistributor() (gas: 41398)
|
||||
KarmaTest:testTotalSupply() (gas: 338940)
|
||||
KarmaTest:testTransfersNotAllowed() (gas: 40241)
|
||||
KarmaOwnershipTest:testAddKarmaDistributorOnlyAdmin() (gas: 423043)
|
||||
KarmaOwnershipTest:testBalanceOf() (gas: 431293)
|
||||
KarmaOwnershipTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49677)
|
||||
KarmaOwnershipTest:testInitialOwner() (gas: 16039)
|
||||
KarmaOwnershipTest:testMintOnlyAdmin() (gas: 378791)
|
||||
KarmaOwnershipTest:testOwnershipTransfer() (gas: 76843)
|
||||
KarmaOwnershipTest:testRemoveKarmaDistributorOnlyOwner() (gas: 147229)
|
||||
KarmaOwnershipTest:testRemoveUnknownKarmaDistributor() (gas: 41618)
|
||||
KarmaOwnershipTest:testTotalSupply() (gas: 339166)
|
||||
KarmaOwnershipTest:testTransfersNotAllowed() (gas: 40285)
|
||||
KarmaTest:testAddKarmaDistributorOnlyAdmin() (gas: 423021)
|
||||
KarmaTest:testBalanceOf() (gas: 431293)
|
||||
KarmaTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49655)
|
||||
KarmaTest:testMintOnlyAdmin() (gas: 378769)
|
||||
KarmaTest:testRemoveKarmaDistributorOnlyOwner() (gas: 147274)
|
||||
KarmaTest:testRemoveUnknownKarmaDistributor() (gas: 41618)
|
||||
KarmaTest:testTotalSupply() (gas: 339166)
|
||||
KarmaTest:testTransfersNotAllowed() (gas: 40263)
|
||||
LeaveTest:test_LeaveShouldKeepFundsLockedInStakeVault() (gas: 9899411)
|
||||
LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 9865059)
|
||||
LeaveTest:test_RevertWhenStakeManagerIsTrusted() (gas: 333238)
|
||||
@@ -69,22 +79,46 @@ NFTMetadataGeneratorSVGTest:testSetImageStringsRevert() (gas: 35891)
|
||||
NFTMetadataGeneratorURLTest:testGenerateMetadata() (gas: 108341)
|
||||
NFTMetadataGeneratorURLTest:testSetBaseURL() (gas: 50631)
|
||||
NFTMetadataGeneratorURLTest:testSetBaseURLRevert() (gas: 36066)
|
||||
OverflowTest:testAddKarmaDistributorOnlyOwner() (gas: 364746)
|
||||
OverflowTest:testBalanceOf() (gas: 431045)
|
||||
OverflowTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49545)
|
||||
OverflowTest:testMintOnlyOwner() (gas: 376410)
|
||||
OverflowTest:testRemoveKarmaDistributorOnlyOwner() (gas: 88798)
|
||||
OverflowTest:testRemoveUnknownKarmaDistributor() (gas: 41410)
|
||||
OverflowTest:testTotalSupply() (gas: 338940)
|
||||
OverflowTest:testTransfersNotAllowed() (gas: 40241)
|
||||
OverflowTest:test_RevertWhen_MintingCausesOverflow() (gas: 129363)
|
||||
OverflowTest:test_RevertWhen_SettingRewardCausesOverflow() (gas: 127641)
|
||||
StakeManager_RewardsTest:testRewardsBalanceOf() (gas: 1281373)
|
||||
StakeManager_RewardsTest:testSetRewards() (gas: 227019)
|
||||
StakeManager_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 63685)
|
||||
StakeManager_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 103443)
|
||||
OverflowTest:testAddKarmaDistributorOnlyAdmin() (gas: 423043)
|
||||
OverflowTest:testBalanceOf() (gas: 431293)
|
||||
OverflowTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49655)
|
||||
OverflowTest:testMintOnlyAdmin() (gas: 378769)
|
||||
OverflowTest:testRemoveKarmaDistributorOnlyOwner() (gas: 147274)
|
||||
OverflowTest:testRemoveUnknownKarmaDistributor() (gas: 41630)
|
||||
OverflowTest:testTotalSupply() (gas: 339166)
|
||||
OverflowTest:testTransfersNotAllowed() (gas: 40263)
|
||||
OverflowTest:test_RevertWhen_MintingCausesOverflow() (gas: 129464)
|
||||
OverflowTest:test_RevertWhen_SettingRewardCausesOverflow() (gas: 127792)
|
||||
RemoveRewardDistributorTest:testAddKarmaDistributorOnlyAdmin() (gas: 423045)
|
||||
RemoveRewardDistributorTest:testBalanceOf() (gas: 431366)
|
||||
RemoveRewardDistributorTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49633)
|
||||
RemoveRewardDistributorTest:testMintOnlyAdmin() (gas: 378759)
|
||||
RemoveRewardDistributorTest:testRemoveKarmaDistributorOnlyOwner() (gas: 147298)
|
||||
RemoveRewardDistributorTest:testRemoveRewardDistributor() (gas: 132118)
|
||||
RemoveRewardDistributorTest:testRemoveRewardDistributorAsOtherAdmin() (gas: 203200)
|
||||
RemoveRewardDistributorTest:testRemoveUnknownKarmaDistributor() (gas: 41636)
|
||||
RemoveRewardDistributorTest:testTotalSupply() (gas: 339239)
|
||||
RemoveRewardDistributorTest:testTransfersNotAllowed() (gas: 40263)
|
||||
RemoveRewardDistributorTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 66507)
|
||||
SetRewardTest:testAddKarmaDistributorOnlyAdmin() (gas: 423077)
|
||||
SetRewardTest:testBalanceOf() (gas: 431293)
|
||||
SetRewardTest:testBalanceOfWithNoSystemTotalKarma() (gas: 49677)
|
||||
SetRewardTest:testMintOnlyAdmin() (gas: 378791)
|
||||
SetRewardTest:testRemoveKarmaDistributorOnlyOwner() (gas: 147241)
|
||||
SetRewardTest:testRemoveUnknownKarmaDistributor() (gas: 41630)
|
||||
SetRewardTest:testSetRewardAsAdmin() (gas: 134934)
|
||||
SetRewardTest:testSetRewardAsOperator() (gas: 126214)
|
||||
SetRewardTest:testSetRewardAsOtherAdmin() (gas: 199420)
|
||||
SetRewardTest:testTotalSupply() (gas: 339211)
|
||||
SetRewardTest:testTransfersNotAllowed() (gas: 40307)
|
||||
SetRewardTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 43559)
|
||||
SetRewardTest:test_RevertWhen_SenderIsNotOperator() (gas: 53332)
|
||||
StakeManager_RewardsTest:testRewardsBalanceOf() (gas: 1281535)
|
||||
StakeManager_RewardsTest:testSetRewards() (gas: 227100)
|
||||
StakeManager_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 63751)
|
||||
StakeManager_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 103509)
|
||||
StakeManager_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39367)
|
||||
StakeManager_RewardsTest:testTotalRewardsSupply() (gas: 746062)
|
||||
StakeManager_RewardsTest:testTotalRewardsSupply() (gas: 746224)
|
||||
StakeTest:test_StakeMultipleAccounts() (gas: 556308)
|
||||
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 564800)
|
||||
StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 942461)
|
||||
@@ -131,7 +165,7 @@ UnstakeTest:test_UnstakeOneAccount() (gas: 545178)
|
||||
UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 544489)
|
||||
UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 468681)
|
||||
UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 570741)
|
||||
UpdateVaultTest:test_UpdateAccount() (gas: 2397297)
|
||||
UpdateVaultTest:test_UpdateAccount() (gas: 2397378)
|
||||
UpgradeTest:test_RevertWhenNotOwner() (gas: 3696209)
|
||||
UpgradeTest:test_UpgradeStakeManager() (gas: 9769347)
|
||||
VaultRegistrationTest:test_VaultRegistration() (gas: 63138)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
{
|
||||
"files": ["src/Karma.sol"],
|
||||
"files": [
|
||||
"src/StakeManager.sol",
|
||||
"src/Karma.sol",
|
||||
],
|
||||
"msg": "Verifying Karma.sol",
|
||||
"rule_sanity": "basic",
|
||||
"verify": "Karma:certora/specs/Karma.spec",
|
||||
"parametric_contracts": ["Karma"],
|
||||
"optimistic_loop": true,
|
||||
"loop_iter": "3",
|
||||
"packages": [
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using Karma as karma;
|
||||
|
||||
methods {
|
||||
function owner() external returns (address) envfree;
|
||||
function totalDistributorAllocation() external returns (uint256) envfree;
|
||||
function totalSupply() external returns (uint256) envfree;
|
||||
function externalSupply() external returns (uint256) envfree;
|
||||
function _.setReward(uint256, uint256) external => HAVOC_ECF;
|
||||
function _.setReward(uint256, uint256) external => DISPATCHER(true);
|
||||
function hasRole(bytes32, address) external returns (bool) envfree;
|
||||
function DEFAULT_ADMIN_ROLE() external returns (bytes32) envfree;
|
||||
function OPERATOR_ROLE() external returns (bytes32) envfree;
|
||||
}
|
||||
|
||||
persistent ghost mathint sumOfDistributorAllocations {
|
||||
@@ -38,14 +40,17 @@ definition isERC20TransferFunction(method f) returns bool = (
|
||||
|| f.selector == sig:karma.approve(address, uint256).selector
|
||||
);
|
||||
|
||||
definition isOwnableFunction(method f) returns bool = (
|
||||
definition isAdminFunction(method f) returns bool = (
|
||||
f.selector == sig:karma.addRewardDistributor(address).selector
|
||||
|| f.selector == sig:karma.removeRewardDistributor(address).selector
|
||||
|| f.selector == sig:karma.setReward(address, uint256, uint256).selector
|
||||
|| f.selector == sig:karma.mint(address, uint256).selector
|
||||
|
||||
);
|
||||
|
||||
definition isOperatorFunction(method f) returns bool = (
|
||||
f.selector == sig:karma.setReward(address, uint256, uint256).selector
|
||||
|| f.selector == sig:karma.mint(address, uint256).selector
|
||||
);
|
||||
|
||||
rule erc20TransferIsDisabled(method f) {
|
||||
env e;
|
||||
calldataarg args;
|
||||
@@ -56,16 +61,29 @@ rule erc20TransferIsDisabled(method f) {
|
||||
assert isERC20TransferFunction(f) => isReverted;
|
||||
}
|
||||
|
||||
rule ownableFuncsOnlyCallableByOwner(method f) {
|
||||
rule adminFuncsOnlyCallableByAdmin(method f) {
|
||||
env e;
|
||||
calldataarg args;
|
||||
|
||||
bool isOwner = owner() == e.msg.sender;
|
||||
bool isOwner = hasRole(DEFAULT_ADMIN_ROLE(), e.msg.sender);
|
||||
|
||||
f@withrevert(e, args);
|
||||
bool isReverted = lastReverted;
|
||||
|
||||
assert isOwnableFunction(f) && !isOwner => isReverted;
|
||||
assert isAdminFunction(f) && !isOwner => isReverted;
|
||||
}
|
||||
|
||||
rule operatorFuncsCallableByAdminAndOperators(method f) {
|
||||
env e;
|
||||
calldataarg args;
|
||||
|
||||
bool isOwner = hasRole(DEFAULT_ADMIN_ROLE(), e.msg.sender);
|
||||
bool isOperator = hasRole(OPERATOR_ROLE(), e.msg.sender);
|
||||
|
||||
f@withrevert(e, args);
|
||||
bool isReverted = lastReverted;
|
||||
|
||||
assert isOperatorFunction(f) && !isOwner && !isOperator => isReverted;
|
||||
}
|
||||
|
||||
rule totalDistributorAllocationCanOnlyIncrease(method f) filtered { f ->
|
||||
|
||||
114
src/Karma.sol
114
src/Karma.sol
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.26;
|
||||
|
||||
import { Ownable2StepUpgradeable } from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
|
||||
import { AccessControlUpgradeable } from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
|
||||
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
||||
@@ -13,12 +13,19 @@ import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableS
|
||||
* @notice This contract allows for setting rewards for reward distributors.
|
||||
* @dev Implementation of the Karma token
|
||||
*/
|
||||
contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPSUpgradeable {
|
||||
contract Karma is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessControlUpgradeable {
|
||||
using EnumerableSet for EnumerableSet.AddressSet;
|
||||
|
||||
/// @notice Emitted when the address is invalid
|
||||
error Karma__InvalidAddress();
|
||||
/// @notice Emitted because transfers are not allowed
|
||||
error Karma__TransfersNotAllowed();
|
||||
/// @notice Emitted when distributor is already added
|
||||
error Karma__DistributorAlreadyAdded();
|
||||
/// @notice Emitted when distributor is not found
|
||||
error Karma__UnknownDistributor();
|
||||
/// @notice Emitted sender does not have the required role
|
||||
error Karma__Unauthorized();
|
||||
|
||||
event RewardDistributorAdded(address distributor);
|
||||
|
||||
@@ -32,12 +39,25 @@ contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPS
|
||||
string public constant SYMBOL = "KARMA";
|
||||
/// @notice The total allocation for all reward distributors
|
||||
uint256 public totalDistributorAllocation;
|
||||
|
||||
/// @notice Set of reward distributors
|
||||
EnumerableSet.AddressSet private rewardDistributors;
|
||||
/// @notice Mapping of reward distributor to allocation
|
||||
mapping(address distributor => uint256 allocation) public rewardDistributorAllocations;
|
||||
|
||||
/// @notice Operator role keccak256("OPERATOR_ROLE")
|
||||
bytes32 public constant OPERATOR_ROLE = 0x97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929;
|
||||
/// @notice Gap for upgrade safety.
|
||||
// solhint-disable-next-line
|
||||
uint256[30] private __gap_Karma;
|
||||
|
||||
/// @notice Modifier to check if sender is admin or operator
|
||||
modifier onlyAdminOrOperator() {
|
||||
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && !hasRole(OPERATOR_ROLE, msg.sender)) {
|
||||
revert Karma__Unauthorized();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
CONSTRUCTOR
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
@@ -51,9 +71,13 @@ contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPS
|
||||
* @param _owner Address of the owner of the contract.
|
||||
*/
|
||||
function initialize(address _owner) public initializer {
|
||||
if (_owner == address(0)) {
|
||||
revert Karma__InvalidAddress();
|
||||
}
|
||||
__ERC20_init(NAME, SYMBOL);
|
||||
_transferOwnership(_owner);
|
||||
__UUPSUpgradeable_init();
|
||||
__AccessControl_init();
|
||||
_setupRole(DEFAULT_ADMIN_ROLE, _owner);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
@@ -66,13 +90,8 @@ contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPS
|
||||
* @dev Emits a `RewardDistributorAdded` event when a distributor is added.
|
||||
* @param distributor The address of the reward distributor.
|
||||
*/
|
||||
function addRewardDistributor(address distributor) external onlyOwner {
|
||||
if (rewardDistributors.contains(distributor)) {
|
||||
revert Karma__DistributorAlreadyAdded();
|
||||
}
|
||||
|
||||
rewardDistributors.add(address(distributor));
|
||||
emit RewardDistributorAdded(distributor);
|
||||
function addRewardDistributor(address distributor) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||
_addRewardDistributor(distributor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,12 +99,8 @@ contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPS
|
||||
* @dev Only the owner can remove a reward distributor.
|
||||
* @param distributor The address of the reward distributor.
|
||||
*/
|
||||
function removeRewardDistributor(address distributor) external onlyOwner {
|
||||
if (!rewardDistributors.contains(distributor)) {
|
||||
revert Karma__UnknownDistributor();
|
||||
}
|
||||
|
||||
rewardDistributors.remove(distributor);
|
||||
function removeRewardDistributor(address distributor) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||
_removeRewardDistributor(distributor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,17 +111,16 @@ contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPS
|
||||
* @param amount The amount of rewards to set.
|
||||
* @param duration The duration of the rewards.
|
||||
*/
|
||||
function setReward(address rewardsDistributor, uint256 amount, uint256 duration) external onlyOwner {
|
||||
if (!rewardDistributors.contains(rewardsDistributor)) {
|
||||
revert Karma__UnknownDistributor();
|
||||
}
|
||||
|
||||
_overflowCheck(amount);
|
||||
|
||||
rewardDistributorAllocations[rewardsDistributor] += amount;
|
||||
totalDistributorAllocation += amount;
|
||||
|
||||
IRewardDistributor(rewardsDistributor).setReward(amount, duration);
|
||||
function setReward(
|
||||
address rewardsDistributor,
|
||||
uint256 amount,
|
||||
uint256 duration
|
||||
)
|
||||
public
|
||||
virtual
|
||||
onlyAdminOrOperator
|
||||
{
|
||||
_setReward(rewardsDistributor, amount, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +130,7 @@ contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPS
|
||||
* @param account The account to mint tokens to.
|
||||
* @param amount The amount of tokens to mint.
|
||||
*/
|
||||
function mint(address account, uint256 amount) external onlyOwner {
|
||||
function mint(address account, uint256 amount) public virtual onlyAdminOrOperator {
|
||||
_overflowCheck(amount);
|
||||
_mint(account, amount);
|
||||
}
|
||||
@@ -167,7 +181,47 @@ contract Karma is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable, UUPS
|
||||
* @dev This function is only callable by the owner.
|
||||
*/
|
||||
function _authorizeUpgrade(address) internal view override {
|
||||
_checkOwner();
|
||||
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
|
||||
revert Karma__Unauthorized();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Adds a reward distributor to the set of reward distributors.
|
||||
* @param distributor The address of the reward distributor.
|
||||
*/
|
||||
function _addRewardDistributor(address distributor) internal virtual {
|
||||
if (rewardDistributors.contains(distributor)) {
|
||||
revert Karma__DistributorAlreadyAdded();
|
||||
}
|
||||
|
||||
rewardDistributors.add(distributor);
|
||||
emit RewardDistributorAdded(distributor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Removes a reward distributor from the set of reward distributors.
|
||||
* @param distributor The address of the reward distributor.
|
||||
*/
|
||||
function _removeRewardDistributor(address distributor) internal virtual {
|
||||
if (!rewardDistributors.contains(distributor)) {
|
||||
revert Karma__UnknownDistributor();
|
||||
}
|
||||
rewardDistributors.remove(distributor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Sets the reward for a reward distributor.
|
||||
*/
|
||||
function _setReward(address rewardsDistributor, uint256 amount, uint256 duration) internal virtual {
|
||||
if (!rewardDistributors.contains(rewardsDistributor)) {
|
||||
revert Karma__UnknownDistributor();
|
||||
}
|
||||
_overflowCheck(amount);
|
||||
|
||||
rewardDistributorAllocations[rewardsDistributor] += amount;
|
||||
totalDistributorAllocation += amount;
|
||||
IRewardDistributor(rewardsDistributor).setReward(amount, duration);
|
||||
}
|
||||
|
||||
function _overflowCheck(uint256 amount) internal view {
|
||||
|
||||
173
test/Karma.t.sol
173
test/Karma.t.sol
@@ -1,6 +1,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
|
||||
|
||||
import { Test } from "forge-std/Test.sol";
|
||||
import { DeployKarmaScript } from "../script/DeployKarma.s.sol";
|
||||
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
|
||||
@@ -17,6 +19,8 @@ contract KarmaTest is Test {
|
||||
KarmaDistributorMock public distributor1;
|
||||
KarmaDistributorMock public distributor2;
|
||||
|
||||
address public operator = makeAddr("operator");
|
||||
|
||||
function setUp() public virtual {
|
||||
DeployKarmaScript karmaDeployment = new DeployKarmaScript();
|
||||
(Karma _karma, DeploymentConfig deploymentConfig) = karmaDeployment.run();
|
||||
@@ -33,11 +37,24 @@ contract KarmaTest is Test {
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
|
||||
function testAddKarmaDistributorOnlyOwner() public {
|
||||
function _accessControlError(address account, bytes32 role) internal pure returns (bytes memory) {
|
||||
string memory expectedError = string(
|
||||
abi.encodePacked(
|
||||
"AccessControl: account ",
|
||||
Strings.toHexString(uint160(account)),
|
||||
" is missing role ",
|
||||
Strings.toHexString(uint256(role), 32)
|
||||
)
|
||||
);
|
||||
return bytes(expectedError);
|
||||
}
|
||||
|
||||
function testAddKarmaDistributorOnlyAdmin() public {
|
||||
KarmaDistributorMock distributor3 = new KarmaDistributorMock();
|
||||
|
||||
bytes memory expectedError = _accessControlError(alice, karma.DEFAULT_ADMIN_ROLE());
|
||||
vm.prank(alice);
|
||||
vm.expectRevert("Ownable: caller is not the owner");
|
||||
vm.expectRevert(expectedError);
|
||||
karma.addRewardDistributor(address(distributor3));
|
||||
|
||||
vm.prank(owner);
|
||||
@@ -51,8 +68,9 @@ contract KarmaTest is Test {
|
||||
}
|
||||
|
||||
function testRemoveKarmaDistributorOnlyOwner() public {
|
||||
bytes memory expectedError = _accessControlError(alice, karma.DEFAULT_ADMIN_ROLE());
|
||||
vm.prank(alice);
|
||||
vm.expectRevert("Ownable: caller is not the owner");
|
||||
vm.expectRevert(expectedError);
|
||||
karma.removeRewardDistributor(address(distributor1));
|
||||
|
||||
vm.prank(owner);
|
||||
@@ -114,7 +132,7 @@ contract KarmaTest is Test {
|
||||
assertEq(balance, expectedBalance);
|
||||
}
|
||||
|
||||
function testMintOnlyOwner() public {
|
||||
function testMintOnlyAdmin() public {
|
||||
vm.startBroadcast(owner);
|
||||
karma.setReward(address(distributor1), 1000 ether, 1000);
|
||||
karma.setReward(address(distributor2), 2000 ether, 2000);
|
||||
@@ -125,7 +143,7 @@ contract KarmaTest is Test {
|
||||
assertEq(karma.totalSupply(), 3000 ether);
|
||||
|
||||
vm.prank(alice);
|
||||
vm.expectRevert("Ownable: caller is not the owner");
|
||||
vm.expectRevert(Karma.Karma__Unauthorized.selector);
|
||||
karma.mint(alice, 1000e18);
|
||||
|
||||
vm.prank(owner);
|
||||
@@ -154,17 +172,148 @@ contract KarmaOwnershipTest is KarmaTest {
|
||||
}
|
||||
|
||||
function testInitialOwner() public view {
|
||||
assertEq(karma.owner(), owner);
|
||||
assert(karma.hasRole(karma.DEFAULT_ADMIN_ROLE(), owner));
|
||||
}
|
||||
|
||||
function testOwnershipTransfer() public {
|
||||
vm.prank(owner);
|
||||
karma.transferOwnership(alice);
|
||||
assertEq(karma.owner(), owner);
|
||||
vm.startPrank(owner);
|
||||
karma.grantRole(karma.DEFAULT_ADMIN_ROLE(), alice);
|
||||
vm.stopPrank();
|
||||
assert(karma.hasRole(karma.DEFAULT_ADMIN_ROLE(), alice));
|
||||
}
|
||||
}
|
||||
|
||||
vm.prank(alice);
|
||||
karma.acceptOwnership();
|
||||
assertEq(karma.owner(), alice);
|
||||
contract AddRewardDistributorTest is KarmaTest {
|
||||
address public distributor;
|
||||
|
||||
function setUp() public virtual override {
|
||||
super.setUp();
|
||||
distributor = address(new KarmaDistributorMock());
|
||||
}
|
||||
|
||||
function test_RevertWhen_SenderIsNotDefaultAdmin() public {
|
||||
vm.prank(makeAddr("someone"));
|
||||
vm.expectRevert();
|
||||
karma.addRewardDistributor(distributor);
|
||||
}
|
||||
|
||||
function testAddRewardDistributorAsOtherAdmin() public {
|
||||
address otherAdmin = makeAddr("otherAdmin");
|
||||
vm.startPrank(owner);
|
||||
karma.grantRole(karma.DEFAULT_ADMIN_ROLE(), otherAdmin);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.startPrank(otherAdmin);
|
||||
karma.addRewardDistributor(distributor);
|
||||
vm.stopPrank();
|
||||
address[] memory distributors = karma.getRewardDistributors();
|
||||
assertEq(distributors.length, 3);
|
||||
assertEq(distributors[2], distributor);
|
||||
}
|
||||
}
|
||||
|
||||
contract RemoveRewardDistributorTest is KarmaTest {
|
||||
address public distributor;
|
||||
|
||||
function setUp() public virtual override {
|
||||
super.setUp();
|
||||
distributor = address(new KarmaDistributorMock());
|
||||
}
|
||||
|
||||
function test_RevertWhen_SenderIsNotDefaultAdmin() public {
|
||||
vm.expectRevert();
|
||||
karma.removeRewardDistributor(distributor);
|
||||
}
|
||||
|
||||
function testRemoveRewardDistributor() public {
|
||||
// add a distributor
|
||||
vm.prank(owner);
|
||||
karma.addRewardDistributor(distributor);
|
||||
address[] memory distributors = karma.getRewardDistributors();
|
||||
assertEq(distributors.length, 3);
|
||||
assertEq(distributors[2], distributor);
|
||||
|
||||
// remove the distributor
|
||||
vm.prank(owner);
|
||||
karma.removeRewardDistributor(distributor);
|
||||
distributors = karma.getRewardDistributors();
|
||||
assertEq(distributors.length, 2);
|
||||
}
|
||||
|
||||
function testRemoveRewardDistributorAsOtherAdmin() public {
|
||||
// add a distributor
|
||||
vm.prank(owner);
|
||||
karma.addRewardDistributor(distributor);
|
||||
address[] memory distributors = karma.getRewardDistributors();
|
||||
assertEq(distributors.length, 3);
|
||||
assertEq(distributors[2], distributor);
|
||||
|
||||
// grant admin role
|
||||
address otherAdmin = makeAddr("otherAdmin");
|
||||
vm.startPrank(owner);
|
||||
karma.grantRole(karma.DEFAULT_ADMIN_ROLE(), otherAdmin);
|
||||
vm.stopPrank();
|
||||
|
||||
// remove the distributor
|
||||
vm.prank(otherAdmin);
|
||||
karma.removeRewardDistributor(address(distributor1));
|
||||
distributors = karma.getRewardDistributors();
|
||||
assertEq(distributors.length, 2);
|
||||
}
|
||||
}
|
||||
|
||||
contract SetRewardTest is KarmaTest {
|
||||
address public distributor;
|
||||
|
||||
function setUp() public virtual override {
|
||||
super.setUp();
|
||||
distributor = address(new KarmaDistributorMock());
|
||||
}
|
||||
|
||||
function test_RevertWhen_SenderIsNotDefaultAdmin() public {
|
||||
vm.prank(makeAddr("someone"));
|
||||
vm.expectRevert();
|
||||
karma.setReward(distributor, 0, 0);
|
||||
}
|
||||
|
||||
function test_RevertWhen_SenderIsNotOperator() public {
|
||||
assert(karma.hasRole(karma.OPERATOR_ROLE(), operator) == false);
|
||||
|
||||
vm.prank(operator);
|
||||
vm.expectRevert();
|
||||
karma.setReward(distributor, 0, 0);
|
||||
}
|
||||
|
||||
function testSetRewardAsAdmin() public {
|
||||
vm.startPrank(owner);
|
||||
karma.addRewardDistributor(distributor);
|
||||
karma.setReward(distributor, 0, 0);
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testSetRewardAsOtherAdmin() public {
|
||||
vm.startPrank(owner);
|
||||
karma.grantRole(karma.DEFAULT_ADMIN_ROLE(), operator);
|
||||
karma.addRewardDistributor(distributor);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.prank(operator);
|
||||
karma.setReward(distributor, 0, 0);
|
||||
}
|
||||
|
||||
function testSetRewardAsOperator() public {
|
||||
// grant operator role
|
||||
assert(karma.hasRole(karma.DEFAULT_ADMIN_ROLE(), owner));
|
||||
|
||||
// actually `vm.prank()` should be used here, but for some reason
|
||||
// foundry seems to mess up the context for what `owner` is
|
||||
vm.startPrank(owner);
|
||||
karma.grantRole(karma.OPERATOR_ROLE(), operator);
|
||||
vm.stopPrank();
|
||||
|
||||
// set reward as operator
|
||||
vm.prank(operator);
|
||||
karma.setReward(address(distributor1), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user