Skip to content

Commit

Permalink
Refactor setup access script
Browse files Browse the repository at this point in the history
  • Loading branch information
bxmmm1 committed Nov 9, 2023
1 parent d099ac4 commit 6bd86c1
Show file tree
Hide file tree
Showing 15 changed files with 211 additions and 109 deletions.
73 changes: 37 additions & 36 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,63 @@ EnclaveVerifierTest:testRaveEvidence3() (gas: 905231)
EnclaveVerifierTest:testRemoveLeafX509() (gas: 200770)
EnclaveVerifierTest:testSetup() (gas: 115154)
EnclaveVerifierTest:testVerifyingStaleEvidence() (gas: 743633)
GuardianModuleTest:testRave() (gas: 45771890)
GuardianModuleTest:testRave() (gas: 47320445)
GuardianModuleTest:testRoateGuardianKeyWithInvalidRaveReverts() (gas: 855872)
GuardianModuleTest:testRoateGuardianToInvalidPubKeyReverts() (gas: 22860)
GuardianModuleTest:testRotateGuardianKeyFromNonGuardianReverts() (gas: 20303)
NoRestakingStartegyTest:testClaimingMultipleProofs() (gas: 188849)
NoRestakingStartegyTest:testCollectRewards() (gas: 183439)
NoRestakingStartegyTest:testClaimingMultipleProofs() (gas: 194011)
NoRestakingStartegyTest:testCollectRewards() (gas: 198074)
NoRestakingStartegyTest:testDonation() (gas: 11852)
NoRestakingStartegyTest:testDoubleClaimInSameTransaction() (gas: 134263)
NoRestakingStartegyTest:testDoubleClaimInSameTransaction() (gas: 139421)
NoRestakingStartegyTest:testPostRewardsRoot(bytes32,uint256) (runs: 256, μ: 72388, ~: 72388)
NoRestakingStartegyTest:testPostRewardsRootReverts(address,bytes32,uint256) (runs: 256, μ: 25698, ~: 25698)
NoRestakingStartegyTest:testPostingRewardsForSameBlockReverts() (gas: 76898)
NoRestakingStartegyTest:testRewardsClaimingForAnotherUser(address) (runs: 256, μ: 163248, ~: 163248)
NoRestakingStartegyTest:testRewardsClaimingForAnotherUser(address) (runs: 256, μ: 168409, ~: 168409)
NoRestakingStartegyTest:testSetup() (gas: 16031)
PufferPoolIntegrationTest:testMulticallStrategyDepositOnGoerli() (gas: 302650)
PufferPoolTest:testBurn(address) (runs: 256, μ: 70123, ~: 70108)
PufferPoolTest:testDeposit(address,uint256) (runs: 256, μ: 101852, ~: 101965)
PufferPoolTest:testDepositAndRedeemRoundingError(address,uint256) (runs: 256, μ: 146005, ~: 146070)
PufferPoolTest:testDepositAndRedeemRoundingErrorForDifferentExchangeRate(address,uint256) (runs: 256, μ: 241309, ~: 241411)
PufferPoolTest:testDepositForOneWei() (gas: 77601)
PufferPoolTest:testMultipleDeposits() (gas: 123056)
PufferPoolTest:testRatioChange() (gas: 188273)
PufferPoolTest:testBurn(address) (runs: 256, μ: 79443, ~: 79429)
PufferPoolTest:testDeposit(address,uint256) (runs: 256, μ: 113487, ~: 113594)
PufferPoolTest:testDepositAndRedeemRoundingError(address,uint256) (runs: 256, μ: 162657, ~: 162721)
PufferPoolTest:testDepositAndRedeemRoundingErrorForDifferentExchangeRate(address,uint256) (runs: 256, μ: 259615, ~: 259725)
PufferPoolTest:testDepositForOneWei() (gas: 89274)
PufferPoolTest:testMultipleDeposits() (gas: 138118)
PufferPoolTest:testRatioChange() (gas: 200300)
PufferPoolTest:testSetup() (gas: 32689)
PufferPoolTest:testStorageS() (gas: 19492)
PufferProtocolInvariants:invariant_callSummary() (runs: 500, calls: 10000, reverts: 921)
PufferProtocolInvariants:invariant_guardiansCanNeverChange() (runs: 500, calls: 10000, reverts: 947)
PufferProtocolInvariants:invariant_pufEthToETHRate() (runs: 500, calls: 10000, reverts: 947)
PufferProtocolInvariants:invariant_pufferPoolETHCanOnlyGoUp() (runs: 500, calls: 10000, reverts: 947)
PufferProtocolInvariants:invariant_callSummary() (runs: 500, calls: 10000, reverts: 920)
PufferProtocolInvariants:invariant_guardiansCanNeverChange() (runs: 500, calls: 10000, reverts: 931)
PufferProtocolInvariants:invariant_pufEthToETHRate() (runs: 500, calls: 10000, reverts: 931)
PufferProtocolInvariants:invariant_pufferPoolETHCanOnlyGoUp() (runs: 500, calls: 10000, reverts: 931)
PufferProtocolTest:testChangeStrategy() (gas: 32124)
PufferProtocolTest:testChangeStrategyToCustom() (gas: 51214)
PufferProtocolTest:testClaimBackBond() (gas: 1367007)
PufferProtocolTest:testChangeStrategyToCustom() (gas: 51236)
PufferProtocolTest:testClaimBackBond() (gas: 1388884)
PufferProtocolTest:testCreateExistingStrategyShouldFail() (gas: 32922)
PufferProtocolTest:testCreatePufferStrategy() (gas: 284661)
PufferProtocolTest:testEmptyQueue() (gas: 32893)
PufferProtocolTest:testFuzzRegisterManyValidators(uint8) (runs: 256, μ: 27742706, ~: 11944202)
PufferProtocolTest:testFuzzRegisterManyValidators(uint8) (runs: 256, μ: 29927623, ~: 19135338)
PufferProtocolTest:testGetPayload() (gas: 170740)
PufferProtocolTest:testProofOfReserve() (gas: 151341)
PufferProtocolTest:testProvisionNode() (gas: 4048449)
PufferProtocolTest:testRegisterInvalidPrivKeyShares() (gas: 73087)
PufferProtocolTest:testRegisterInvalidPubKeyShares() (gas: 76595)
PufferProtocolTest:testRegisterMoreValidatorsThanTheLimit() (gas: 813206)
PufferProtocolTest:testRegisterMultipleValidatorKeysAndDequeue(bytes32,bytes32) (runs: 256, μ: 2144361, ~: 2144361)
PufferProtocolTest:testRegisterToInvalidStrategy() (gas: 59839)
PufferProtocolTest:testRegisterWithInvalidAmountPaid() (gas: 81372)
PufferProtocolTest:testRegisterWithInvalidBLSPubKey() (gas: 32603)
PufferProtocolTest:testRegisterWithoutRAVE() (gas: 341935)
PufferProtocolTest:testPause() (gas: 135006)
PufferProtocolTest:testProofOfReserve() (gas: 151363)
PufferProtocolTest:testProvisionNode() (gas: 4115035)
PufferProtocolTest:testRegisterInvalidPrivKeyShares() (gas: 84873)
PufferProtocolTest:testRegisterInvalidPubKeyShares() (gas: 88360)
PufferProtocolTest:testRegisterMoreValidatorsThanTheLimit() (gas: 836582)
PufferProtocolTest:testRegisterMultipleValidatorKeysAndDequeue(bytes32,bytes32) (runs: 256, μ: 2199243, ~: 2199243)
PufferProtocolTest:testRegisterToInvalidStrategy() (gas: 71603)
PufferProtocolTest:testRegisterWithInvalidAmountPaid() (gas: 93159)
PufferProtocolTest:testRegisterWithInvalidBLSPubKey() (gas: 44367)
PufferProtocolTest:testRegisterWithoutRAVE() (gas: 362535)
PufferProtocolTest:testSetGuardiansFeeRateOverTheLimit() (gas: 28307)
PufferProtocolTest:testSetProtocolFeeRate() (gas: 33494)
PufferProtocolTest:testSetProtocolFeeRateOverTheLimit() (gas: 28319)
PufferProtocolTest:testSetSmoothingCommitment() (gas: 86626)
PufferProtocolTest:testSetSmoothingCommitment(bytes32) (runs: 256, μ: 86576, ~: 86553)
PufferProtocolTest:testSetWithdrawalPoolRateOverTheLimit() (gas: 28373)
PufferProtocolTest:testSetup() (gas: 19658)
PufferProtocolTest:testSkipProvisioning() (gas: 1017569)
PufferProtocolTest:testStopRegistration() (gas: 1113830)
PufferProtocolTest:testStrategyDOS() (gas: 3870211)
PufferProtocolTest:testUpgrade() (gas: 4745160)
PufferProtocolTest:testSetup() (gas: 19591)
PufferProtocolTest:testSkipProvisioning() (gas: 1040452)
PufferProtocolTest:testStopRegistration() (gas: 1140780)
PufferProtocolTest:testStrategyDOS() (gas: 3958921)
PufferProtocolTest:testUpgrade() (gas: 4716483)
PufferStrategyTest:testBeaconUpgrade() (gas: 367461)
WithdrawalPoolTest:testWithdrawETH() (gas: 160389)
WithdrawalPoolTest:testWithdrawETHWithSignature() (gas: 172560)
WithdrawalPoolTest:testWithdrawETH() (gas: 181225)
WithdrawalPoolTest:testWithdrawETHWithSignature() (gas: 193507)
5 changes: 2 additions & 3 deletions docs/PufferPool.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ PufferPool.sol is a **non upgradeable** ERC20Permit token.
<!--
<sub>The ERC-20 permit feature is an extension to the ERC-20 standard that allows token holders to approve transfers without the need for two separate transactions. </sub> -->

It takes the ETH deposits from the Puffers and mints `pufETH` ERC20 token in return. That can be achieved in 2 ways:
- Triggering a payable `receive()` function on this smart contract
It takes the ETH deposits from the Puffers and mints `pufETH` ERC20 token in return by:
- Calling `depositETH()` and sending the ETH along with it

The rewards / donations are going through the `depositETHWithoutMinting()` function. This function will not mint any `pufETH` in return.
The rewards / donations are going through the `receive()` function. This function will not mint any `pufETH` in return.
Depositing ETH through this function will eventually change the exchange rate between ETH and pufETH, making it so that for 1 pufETH you will be able to get more ETH in return. The withdrawals and exchanging of `pufETH` to ETH is happening through our [WithdrawalPool](./WithdrawalPool.md) smart contract or any third party exchange.

The [Guardians](./Guardians.md) are responsible for reporting the values used for calculation of the exchange rate [PufferPoolStorage](../src//struct/PufferPoolStorage.sol). Those values are stored in the storage of our main [PufferProtocol smart contract](../src/PufferProtocolStorage.sol)
Expand Down
1 change: 1 addition & 0 deletions script/1_DeployGuardians.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ contract DeployGuardians is BaseScript {
vm.serializeAddress(obj, "safeProxyFactory", address(safeProxy));
vm.serializeAddress(obj, "safeImplementation", address(safeImplementation));
vm.serializeAddress(obj, "enclaveVerifier", address(verifier));
vm.serializeAddress(obj, "pauser", 0x98BDB87fCF3697F4b356C36Cd621ffF94Ee3Aa19);

string memory finalJson = vm.serializeString(obj, "", "");

Expand Down
2 changes: 1 addition & 1 deletion script/DeployPuffer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ contract DeployPuffer is BaseScript {
// Deploy pool
PufferPool pool = new PufferPool(pufferProtocol, address(accessManager));

WithdrawalPool withdrawalPool = new WithdrawalPool(pool);
WithdrawalPool withdrawalPool = new WithdrawalPool(pool, address(accessManager));

// Read guardians module variable
address payable guardiansModule = payable(stdJson.readAddress(guardiansDeployment, ".guardianModule"));
Expand Down
158 changes: 132 additions & 26 deletions script/SetupAccess.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { stdJson } from "forge-std/StdJson.sol";
import { AccessManager } from "openzeppelin/access/manager/AccessManager.sol";
import { PufferProtocol } from "puffer/PufferProtocol.sol";
import { PufferPool } from "puffer/PufferPool.sol";
import { IWithdrawalPool } from "puffer/interface/IWithdrawalPool.sol";
import { GuardianModule } from "puffer/GuardianModule.sol";
import { IPufferStrategy } from "puffer/interface/IPufferStrategy.sol";
import { UpgradeableBeacon } from "openzeppelin/proxy/beacon/UpgradeableBeacon.sol";
Expand All @@ -15,6 +16,7 @@ import { EnclaveVerifier } from "puffer/EnclaveVerifier.sol";
uint64 constant ROLE_ID_PUFFER_PROTOCOL = 1;
uint64 constant ROLE_ID_DAO = 77;
uint64 constant ROLE_ID_GUARDIANS = 88;
uint64 constant ROLE_ID_PAUSER = 999;

contract SetupAccess is BaseScript {
string internal pufferDeployment = vm.readFile(string.concat("./output/puffer.json"));
Expand All @@ -28,61 +30,145 @@ contract SetupAccess is BaseScript {
address internal guardianModule = stdJson.readAddress(guardiansDeployment, ".guardianModule");
address internal pufferProtocol = stdJson.readAddress(pufferDeployment, ".PufferProtocol");
address internal noRestakingStrategy = stdJson.readAddress(pufferDeployment, ".noRestakingStrategy");
address internal withdrawalPool = stdJson.readAddress(pufferDeployment, ".withdrawalPool");
address internal pufferPool = stdJson.readAddress(pufferDeployment, ".pufferPool");
address internal enclaveVerifier = stdJson.readAddress(guardiansDeployment, ".enclaveVerifier");
address internal pauser = stdJson.readAddress(guardiansDeployment, ".pauser");

function run(address DAO) external broadcast {
_grantRoles(DAO);
_setupPufferProtocolRoles();
_setupGuardianModuleRoles();
_setupPufferPoolRoles();
_setupNoRestakingStrategyRoles();
_setupUpgradeableBeacon();
_setupEnclaveVerifierRoles();
// We do one multicall to setup everything
bytes[] memory rolesCalldatas = _grantRoles(DAO);
bytes[] memory pufferProtocolRoles = _setupPufferProtocolRoles();
bytes[] memory pufferPoolRoles = _setupPufferPoolRoles();
bytes[] memory noRestakingStrategyRoles = _setupNoRestakingStrategyRoles();

bytes[] memory calldatas = new bytes[](16);
calldatas[0] = _setupGuardianModuleRoles();
calldatas[1] = _setupEnclaveVerifierRoles();
calldatas[2] = _setupWithdrawalPoolRoles();
calldatas[3] = _setupUpgradeableBeacon();
calldatas[4] = rolesCalldatas[0];
calldatas[5] = rolesCalldatas[1];
calldatas[6] = rolesCalldatas[2];
calldatas[7] = rolesCalldatas[3];

calldatas[8] = pufferProtocolRoles[0];
calldatas[9] = pufferProtocolRoles[1];
calldatas[10] = pufferProtocolRoles[2];

calldatas[11] = pufferPoolRoles[0];
calldatas[12] = pufferPoolRoles[1];

calldatas[13] = noRestakingStrategyRoles[0];
calldatas[14] = noRestakingStrategyRoles[1];
calldatas[15] = noRestakingStrategyRoles[2];

// calldatas[16] = _setupPauser();

accessManager.multicall(calldatas);
}

function _setupGuardianModuleRoles() internal {
function _setupPauser() internal view returns (bytes memory) {
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = AccessManager.setTargetClosed.selector;

return abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, address(accessManager), selectors, ROLE_ID_PAUSER
);
}

function _setupWithdrawalPoolRoles() internal view returns (bytes memory) {
bytes4[] memory selectors = new bytes4[](2);
selectors[0] = bytes4(hex"4782f779"); // IWithdrawalPool.withdrawETH.selector;
selectors[1] = bytes4(hex"945fca09"); // IWithdrawalPool.withdrawETH Permit version

return abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, withdrawalPool, selectors, accessManager.PUBLIC_ROLE()
);
}

function _setupGuardianModuleRoles() internal view returns (bytes memory) {
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = GuardianModule.setGuardianEnclaveMeasurements.selector;

accessManager.setTargetFunctionRole(guardianModule, selectors, ROLE_ID_DAO);
return
abi.encodeWithSelector(AccessManager.setTargetFunctionRole.selector, guardianModule, selectors, ROLE_ID_DAO);
}

function _setupPufferPoolRoles() internal {
function _setupPufferPoolRoles() internal returns (bytes[] memory) {
bytes[] memory calldatas = new bytes[](2);

bytes4[] memory selectors = new bytes4[](1);
selectors[0] = PufferPool.transferETH.selector;

accessManager.setTargetFunctionRole(pufferPool, selectors, ROLE_ID_PUFFER_PROTOCOL);
calldatas[0] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, pufferPool, selectors, ROLE_ID_PUFFER_PROTOCOL
);

bytes4[] memory publicSelectors = new bytes4[](1);
publicSelectors[0] = PufferPool.depositETH.selector;

calldatas[1] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, pufferPool, publicSelectors, accessManager.PUBLIC_ROLE()
);

return calldatas;
}

function _setupUpgradeableBeacon() internal {
function _setupUpgradeableBeacon() internal view returns (bytes memory) {
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = UpgradeableBeacon.upgradeTo.selector;

accessManager.setTargetFunctionRole(
PufferProtocol(pufferProtocol).PUFFER_STRATEGY_BEACON(), selectors, ROLE_ID_DAO
return abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector,
PufferProtocol(pufferProtocol).PUFFER_STRATEGY_BEACON(),
selectors,
ROLE_ID_DAO
);
}

function _setupNoRestakingStrategyRoles() internal {
function _setupNoRestakingStrategyRoles() internal view returns (bytes[] memory) {
bytes[] memory calldatas = new bytes[](3);

bytes4[] memory selectors = new bytes4[](1);
selectors[0] = IPufferStrategy.callStake.selector;

accessManager.setTargetFunctionRole(noRestakingStrategy, selectors, ROLE_ID_PUFFER_PROTOCOL);
calldatas[0] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, noRestakingStrategy, selectors, ROLE_ID_PUFFER_PROTOCOL
);

bytes4[] memory selectorsForGuardians = new bytes4[](1);
selectorsForGuardians[0] = bytes4(hex"abfaad62"); // signature for `function postRewardsRoot(bytes32 root, uint256 blockNumber)`
accessManager.setTargetFunctionRole(noRestakingStrategy, selectorsForGuardians, ROLE_ID_GUARDIANS);

calldatas[1] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, noRestakingStrategy, selectorsForGuardians, ROLE_ID_GUARDIANS
);

bytes4[] memory publicSelectors = new bytes4[](1);
publicSelectors[0] = bytes4(hex"6f06f422"); // collectRewards

calldatas[2] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector,
noRestakingStrategy,
publicSelectors,
accessManager.PUBLIC_ROLE()
);

return calldatas;
}

function _setupEnclaveVerifierRoles() internal {
function _setupEnclaveVerifierRoles() internal view returns (bytes memory) {
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = EnclaveVerifier.removeLeafX509.selector;

accessManager.setTargetFunctionRole(enclaveVerifier, selectors, ROLE_ID_DAO);
return abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, enclaveVerifier, selectors, ROLE_ID_DAO
);
}

function _setupPufferProtocolRoles() internal {
function _setupPufferProtocolRoles() internal view returns (bytes[] memory) {
bytes[] memory calldatas = new bytes[](3);

bytes4[] memory selectors = new bytes4[](9);
selectors[0] = PufferProtocol.setProtocolFeeRate.selector;
selectors[1] = PufferProtocol.setSmoothingCommitments.selector;
Expand All @@ -94,22 +180,42 @@ contract SetupAccess is BaseScript {
selectors[7] = PufferProtocol.setGuardiansFeeRate.selector;
selectors[8] = PufferProtocol.setWithdrawalPoolRate.selector;

accessManager.setTargetFunctionRole(address(pufferProtocol), selectors, ROLE_ID_DAO);
calldatas[0] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, address(pufferProtocol), selectors, ROLE_ID_DAO
);

bytes4[] memory guardianSelectors = new bytes4[](4);
guardianSelectors[0] = PufferProtocol.skipProvisioning.selector;
guardianSelectors[1] = PufferProtocol.stopValidator.selector;
guardianSelectors[2] = PufferProtocol.proofOfReserve.selector;
guardianSelectors[3] = PufferProtocol.postFullWithdrawalsRoot.selector;

accessManager.setTargetFunctionRole(address(pufferProtocol), guardianSelectors, ROLE_ID_GUARDIANS);
calldatas[1] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector, address(pufferProtocol), guardianSelectors, ROLE_ID_GUARDIANS
);

bytes4[] memory publicSelectors = new bytes4[](1);
publicSelectors[0] = PufferProtocol.registerValidatorKey.selector;

calldatas[2] = abi.encodeWithSelector(
AccessManager.setTargetFunctionRole.selector,
address(pufferProtocol),
publicSelectors,
accessManager.PUBLIC_ROLE()
);

return calldatas;
}

function _grantRoles(address DAO) internal {
accessManager.grantRole(ROLE_ID_DAO, DAO, 0);
function _grantRoles(address DAO) internal view returns (bytes[] memory) {
bytes[] memory calldatas = new bytes[](4);

accessManager.grantRole(ROLE_ID_GUARDIANS, guardians, 0);
calldatas[0] = abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_DAO, DAO, 0);
calldatas[1] = abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_GUARDIANS, guardians, 0);
calldatas[2] =
abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_PUFFER_PROTOCOL, pufferProtocol, 0);
calldatas[3] = abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_PAUSER, pauser, 0);

accessManager.grantRole(ROLE_ID_PUFFER_PROTOCOL, pufferProtocol, 0);
return calldatas;
}
}
Loading

0 comments on commit 6bd86c1

Please sign in to comment.