mirror of
https://github.com/vacp2p/staking-reward-streamer.git
synced 2026-01-09 15:27:55 -05:00
This commit introduces a new `Karma` extension that adds `AccessControl` capabilities. 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) - Add a `KarmaWithAccessControl` contract that inherits `Karma` and overrides the necessary functions - Introduce `OPERATOR_ROLE` next to the already provided `DEFAULT_ADMIN_ROLE` Due to storage layout conflicts, the extension is implemented by inheriting `Karma` instead of adding the `AccessControl` functionality to the `Karma` contract directly. Closes #207
170 lines
5.6 KiB
Solidity
170 lines
5.6 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.26;
|
|
|
|
import { Test } from "forge-std/Test.sol";
|
|
import { Karma } from "../src/Karma.sol";
|
|
import { KarmaWithAccessControl } from "../src/KarmaWithAccessControl.sol";
|
|
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
|
|
import { DeployKarmaScript } from "../script/DeployKarma.s.sol";
|
|
import { UpgradeToKarmaWithAccessControlScript } from "../script/UpgradeToKarmaWithAccessControl.s.sol";
|
|
import { KarmaDistributorMock } from "./mocks/KarmaDistributorMock.sol";
|
|
|
|
contract KarmaWithAccessControlTest is Test {
|
|
KarmaWithAccessControl public karma;
|
|
|
|
address public deployer;
|
|
|
|
address public operator = makeAddr("operator");
|
|
|
|
address public distributor;
|
|
|
|
function setUp() public virtual {
|
|
// Deploy the original Karma contract
|
|
DeployKarmaScript karmaDeployment = new DeployKarmaScript();
|
|
(Karma _karma, DeploymentConfig config) = karmaDeployment.run();
|
|
(deployer,) = config.activeNetworkConfig();
|
|
|
|
// upgrade to KarmaWithAccessControl
|
|
UpgradeToKarmaWithAccessControlScript upgrade = new UpgradeToKarmaWithAccessControlScript();
|
|
upgrade.runWithAdminAndProxy(deployer, address(_karma));
|
|
karma = KarmaWithAccessControl(address(_karma));
|
|
|
|
distributor = address(new KarmaDistributorMock());
|
|
}
|
|
|
|
function test_InitializeAccessControl() public {
|
|
assert(karma.hasRole(karma.DEFAULT_ADMIN_ROLE(), deployer));
|
|
}
|
|
}
|
|
|
|
contract AddRewardDistributorTest is KarmaWithAccessControlTest {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
}
|
|
|
|
function test_RevertWhen_SenderIsNotDefaultAdmin() public {
|
|
vm.prank(makeAddr("someone"));
|
|
vm.expectRevert();
|
|
karma.addRewardDistributor(distributor);
|
|
}
|
|
|
|
function testAddRewardDistributor() public {
|
|
vm.prank(deployer);
|
|
karma.addRewardDistributor(distributor);
|
|
address[] memory distributors = karma.getRewardDistributors();
|
|
assertEq(distributors.length, 1);
|
|
assertEq(distributors[0], distributor);
|
|
}
|
|
|
|
function testAddRewardDistributorAsOtherAdmin() public {
|
|
address otherAdmin = makeAddr("otherAdmin");
|
|
vm.startPrank(deployer);
|
|
karma.grantRole(karma.DEFAULT_ADMIN_ROLE(), otherAdmin);
|
|
vm.stopPrank();
|
|
|
|
vm.prank(otherAdmin);
|
|
karma.addRewardDistributor(distributor);
|
|
address[] memory distributors = karma.getRewardDistributors();
|
|
assertEq(distributors.length, 1);
|
|
assertEq(distributors[0], distributor);
|
|
}
|
|
}
|
|
|
|
contract RemoveRewardDistributorTest is KarmaWithAccessControlTest {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
}
|
|
|
|
function test_RevertWhen_SenderIsNotDefaultAdmin() public {
|
|
vm.expectRevert();
|
|
karma.removeRewardDistributor(distributor);
|
|
}
|
|
|
|
function testRemoveRewardDistributor() public {
|
|
// add a distributor
|
|
vm.prank(deployer);
|
|
karma.addRewardDistributor(distributor);
|
|
address[] memory distributors = karma.getRewardDistributors();
|
|
assertEq(distributors.length, 1);
|
|
assertEq(distributors[0], distributor);
|
|
|
|
// remove the distributor
|
|
vm.prank(deployer);
|
|
karma.removeRewardDistributor(distributor);
|
|
distributors = karma.getRewardDistributors();
|
|
assertEq(distributors.length, 0);
|
|
}
|
|
|
|
function testRemoveRewardDistributorAsOtherAdmin() public {
|
|
// add a distributor
|
|
vm.prank(deployer);
|
|
karma.addRewardDistributor(distributor);
|
|
address[] memory distributors = karma.getRewardDistributors();
|
|
assertEq(distributors.length, 1);
|
|
assertEq(distributors[0], distributor);
|
|
|
|
// grant admin role
|
|
address otherAdmin = makeAddr("otherAdmin");
|
|
vm.startPrank(deployer);
|
|
karma.grantRole(karma.DEFAULT_ADMIN_ROLE(), otherAdmin);
|
|
vm.stopPrank();
|
|
|
|
// remove the distributor
|
|
vm.prank(otherAdmin);
|
|
karma.removeRewardDistributor(distributor);
|
|
distributors = karma.getRewardDistributors();
|
|
assertEq(distributors.length, 0);
|
|
}
|
|
}
|
|
|
|
contract SetRewardTest is KarmaWithAccessControlTest {
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
vm.prank(deployer);
|
|
karma.addRewardDistributor(distributor);
|
|
}
|
|
|
|
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.prank(deployer);
|
|
karma.setReward(distributor, 0, 0);
|
|
}
|
|
|
|
function testSetRewardAsOtherAdmin() public {
|
|
vm.startPrank(deployer);
|
|
karma.grantRole(karma.DEFAULT_ADMIN_ROLE(), operator);
|
|
vm.stopPrank();
|
|
|
|
vm.prank(operator);
|
|
karma.setReward(distributor, 0, 0);
|
|
}
|
|
|
|
function testSetRewardAsOperator() public {
|
|
// grant operator role
|
|
assert(karma.hasRole(karma.DEFAULT_ADMIN_ROLE(), deployer));
|
|
|
|
// actually `vm.prank()` should be used here, but for some reason
|
|
// foundry seems to mess up the context for what `deployer` is
|
|
vm.startPrank(deployer);
|
|
karma.grantRole(karma.OPERATOR_ROLE(), operator);
|
|
vm.stopPrank();
|
|
|
|
// set reward as operator
|
|
vm.prank(operator);
|
|
karma.setReward(distributor, 0, 0);
|
|
}
|
|
}
|