|
| 1 | +// SPDX-License-Identifier: GPL-3.0 |
| 2 | +pragma solidity >=0.8.0 <0.9.0; |
| 3 | + |
| 4 | +import {Script} from "forge-std/Script.sol"; |
| 5 | +import {stdJson} from "forge-std/StdJson.sol"; |
| 6 | +import {console} from "forge-std/console.sol"; |
| 7 | +import {AccessManager} from "@openzeppelin-contracts/access/manager/AccessManager.sol"; |
| 8 | +import {Multicall} from "@openzeppelin-contracts/utils/Multicall.sol"; |
| 9 | +import {IInstitutionalVault} from "../src/interface/IInstitutionalVault.sol"; |
| 10 | + |
| 11 | +// forge script script/InitialAccessManagerSetup.s.sol:InitialAccessManagerSetup -vvvv |
| 12 | +contract InitialAccessManagerSetup is Script { |
| 13 | + using stdJson for string; |
| 14 | + |
| 15 | + uint64 public constant ADMIN_ROLE_ID = type(uint64).min; // 0 |
| 16 | + uint64 public constant DEPOSITOR_ROLE_ID = 1; |
| 17 | + uint64 public constant WITHDRAWER_ROLE_ID = 2; |
| 18 | + uint64 public constant CUSTOM_EXTERNAL_CALLER_ROLE_ID = 3; |
| 19 | + uint64 public constant WITHDRAWAL_MANAGER_ROLE_ID = 4; |
| 20 | + uint64 public constant ORACLE_ROLE_ID = 5; |
| 21 | + |
| 22 | + struct RolesConfiguration { |
| 23 | + address admin; |
| 24 | + address[] customExternalCallers; |
| 25 | + address pufferOpsMultisig; |
| 26 | + address vault; |
| 27 | + address withdrawalManager; |
| 28 | + } |
| 29 | + |
| 30 | + function run() public view { |
| 31 | + string memory root = vm.projectRoot(); |
| 32 | + string memory path = string.concat(root, "/roles-configuration.json"); |
| 33 | + |
| 34 | + console.log("Path:", path); |
| 35 | + |
| 36 | + string memory fileContent = vm.readFile(path); |
| 37 | + bytes memory rawJson = vm.parseJson(fileContent); |
| 38 | + |
| 39 | + RolesConfiguration memory accessManagerConfiguration = abi.decode(rawJson, (RolesConfiguration)); |
| 40 | + |
| 41 | + console.log("Access manager institution admin:", address(accessManagerConfiguration.admin)); |
| 42 | + |
| 43 | + // Calculate total number of calldatas needed |
| 44 | + uint256 totalCalldatas = 14 + accessManagerConfiguration.customExternalCallers.length + 1; // +1 for revoke role |
| 45 | + bytes[] memory calldatas = new bytes[](totalCalldatas); |
| 46 | + uint256 calldataIndex = 0; |
| 47 | + |
| 48 | + calldatas[calldataIndex++] = abi.encodeCall(AccessManager.labelRole, (DEPOSITOR_ROLE_ID, "Depositor")); |
| 49 | + calldatas[calldataIndex++] = abi.encodeCall(AccessManager.labelRole, (WITHDRAWER_ROLE_ID, "Withdrawer")); |
| 50 | + calldatas[calldataIndex++] = |
| 51 | + abi.encodeCall(AccessManager.labelRole, (CUSTOM_EXTERNAL_CALLER_ROLE_ID, "Custom External Caller")); |
| 52 | + calldatas[calldataIndex++] = |
| 53 | + abi.encodeCall(AccessManager.labelRole, (WITHDRAWAL_MANAGER_ROLE_ID, "Withdrawal Manager")); |
| 54 | + calldatas[calldataIndex++] = abi.encodeCall(AccessManager.labelRole, (ORACLE_ROLE_ID, "Oracle")); |
| 55 | + // Grant the admin role to the institution admin, without any delay |
| 56 | + calldatas[calldataIndex++] = |
| 57 | + abi.encodeCall(AccessManager.grantRole, (ADMIN_ROLE_ID, accessManagerConfiguration.admin, 0)); |
| 58 | + |
| 59 | + bytes4[] memory depositorSelectors = new bytes4[](3); |
| 60 | + depositorSelectors[0] = IInstitutionalVault.depositETH.selector; |
| 61 | + depositorSelectors[1] = IInstitutionalVault.mint.selector; |
| 62 | + depositorSelectors[2] = IInstitutionalVault.deposit.selector; |
| 63 | + |
| 64 | + calldatas[calldataIndex++] = abi.encodeCall( |
| 65 | + AccessManager.setTargetFunctionRole, |
| 66 | + (accessManagerConfiguration.vault, depositorSelectors, DEPOSITOR_ROLE_ID) |
| 67 | + ); |
| 68 | + |
| 69 | + bytes4[] memory withdrawerSelectors = new bytes4[](2); |
| 70 | + withdrawerSelectors[0] = IInstitutionalVault.withdraw.selector; |
| 71 | + withdrawerSelectors[1] = IInstitutionalVault.redeem.selector; |
| 72 | + |
| 73 | + calldatas[calldataIndex++] = abi.encodeCall( |
| 74 | + AccessManager.setTargetFunctionRole, |
| 75 | + (accessManagerConfiguration.vault, withdrawerSelectors, WITHDRAWER_ROLE_ID) |
| 76 | + ); |
| 77 | + |
| 78 | + bytes4[] memory withdrawalManagerSelectors = new bytes4[](2); |
| 79 | + withdrawalManagerSelectors[0] = IInstitutionalVault.queueWithdrawals.selector; |
| 80 | + withdrawalManagerSelectors[1] = IInstitutionalVault.completeQueuedWithdrawals.selector; |
| 81 | + |
| 82 | + calldatas[calldataIndex++] = abi.encodeCall( |
| 83 | + AccessManager.grantRole, (WITHDRAWAL_MANAGER_ROLE_ID, accessManagerConfiguration.withdrawalManager, 0) |
| 84 | + ); |
| 85 | + |
| 86 | + calldatas[calldataIndex++] = |
| 87 | + abi.encodeCall(AccessManager.grantRole, (ORACLE_ROLE_ID, accessManagerConfiguration.admin, 0)); |
| 88 | + |
| 89 | + calldatas[calldataIndex++] = abi.encodeCall( |
| 90 | + AccessManager.setTargetFunctionRole, |
| 91 | + (accessManagerConfiguration.vault, withdrawalManagerSelectors, WITHDRAWAL_MANAGER_ROLE_ID) |
| 92 | + ); |
| 93 | + |
| 94 | + calldatas[calldataIndex++] = |
| 95 | + abi.encodeCall(AccessManager.grantRole, (DEPOSITOR_ROLE_ID, accessManagerConfiguration.admin, 0)); |
| 96 | + |
| 97 | + calldatas[calldataIndex++] = |
| 98 | + abi.encodeCall(AccessManager.grantRole, (WITHDRAWER_ROLE_ID, accessManagerConfiguration.admin, 0)); |
| 99 | + |
| 100 | + bytes4[] memory customExternalCallerSelectors = new bytes4[](1); |
| 101 | + customExternalCallerSelectors[0] = IInstitutionalVault.customExternalCall.selector; |
| 102 | + |
| 103 | + calldatas[calldataIndex++] = abi.encodeCall( |
| 104 | + AccessManager.setTargetFunctionRole, |
| 105 | + (accessManagerConfiguration.vault, customExternalCallerSelectors, CUSTOM_EXTERNAL_CALLER_ROLE_ID) |
| 106 | + ); |
| 107 | + |
| 108 | + // Grant the custom external caller role to the custom external callers |
| 109 | + for (uint256 i = 0; i < accessManagerConfiguration.customExternalCallers.length; i++) { |
| 110 | + calldatas[calldataIndex++] = abi.encodeCall( |
| 111 | + AccessManager.grantRole, |
| 112 | + (CUSTOM_EXTERNAL_CALLER_ROLE_ID, accessManagerConfiguration.customExternalCallers[i], 0) |
| 113 | + ); |
| 114 | + } |
| 115 | + |
| 116 | + // Revoke the admin role from the puffer ops multisig - Clean up |
| 117 | + calldatas[calldataIndex++] = |
| 118 | + abi.encodeCall(AccessManager.revokeRole, (ADMIN_ROLE_ID, accessManagerConfiguration.pufferOpsMultisig)); |
| 119 | + |
| 120 | + bytes memory encodedMulticall = abi.encodeCall(Multicall.multicall, (calldatas)); |
| 121 | + |
| 122 | + console.log("Total calldatas:", totalCalldatas, "calldataIndex:", calldataIndex); |
| 123 | + console.log("Encoded multicall:"); |
| 124 | + console.logBytes(encodedMulticall); |
| 125 | + } |
| 126 | +} |
0 commit comments