tenderly-wizard-v6
Version:
A tool for managing virtual testnets using Tenderly
72 lines (71 loc) • 4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccessControllerWhitelistV2 = void 0;
const safe_master_copy_v2_json_1 = __importDefault(require("../../contracts/safe_master_copy_v2.json"));
const roles_v2_json_1 = __importDefault(require("../../contracts/roles_v2.json"));
const whitelist_class_1 = require("../whitelist-class");
const util_1 = require("../../utils/util");
const constants_1 = require("../../utils/constants");
const roles_chain_config_1 = require("../../utils/roles-chain-config");
const env_config_1 = __importDefault(require("../../env-config"));
const ethers_1 = require("ethers");
// Helper to ensure hex string type
function asHexString(value) {
return value;
}
const ROLES_FUNCTIONS_ALLOWED = [
"revokeTarget",
"scopeTarget",
"allowFunction",
"revokeFunction",
"scopeFunction",
"allowTarget",
];
// Create an ethers Interface from the ABI to get function signatures
const rolesInterface = new ethers_1.Interface(roles_v2_json_1.default);
// this whitelisting class is used in the roles deployment so that security has the ability to scope functions
class AccessControllerWhitelistV2 extends whitelist_class_1.Whitelist {
constructor(acRolesAddr, caller) {
super(acRolesAddr, "v2", caller);
const chainId = env_config_1.default.TENDERLY_FORK_ID;
this.chainConfig = (0, roles_chain_config_1.getChainConfig)(chainId, "v2");
}
// Allow the security team to call all the functions listed in `ROLES_FUNCTIONS_ALLOWED`on the investment roles modifier
async getFullScope(invRolesAddr) {
// Nested roles usage here can be confusing. The invRoles is the target that is scoped on the acRoles
// Must scopeTarget before roles.allowFunction can be called
const roleId = asHexString((0, ethers_1.hexlify)(constants_1.SECURITY_ROLE_ID_V2).padEnd(66, '0'));
const getScopedTargetTxs = await (0, util_1.scopeTargetsV2)([invRolesAddr], roleId, this.roles);
// Get the sighashs that need to be whitelisted
const functionSigs = ROLES_FUNCTIONS_ALLOWED.map(func => {
// Find the function fragment in the ABI
const fragment = rolesInterface.getFunction(func);
if (!fragment) {
throw new Error(`Function ${func} not found in ABI`);
}
return fragment.selector;
});
const getScopedAllowFunctionTxs = await this.scopeAllowFunctionsV2(invRolesAddr, functionSigs, roleId);
const txs = [...getScopedTargetTxs, ...getScopedAllowFunctionTxs];
return (0, util_1.createMultisendTx)(txs, this.chainConfig.MULTISEND_ADDR);
}
async build(invRolesAddr, accessControlSafeAddr) {
const metaTx = await this.getFullScope(invRolesAddr);
// Use any for now since the contract type is complex
const acSafe = new ethers_1.Contract(accessControlSafeAddr, safe_master_copy_v2_json_1.default, this.caller);
const signature = (0, util_1.getPreValidatedSignatures)(await this.caller.getAddress());
return await acSafe.execTransaction.populateTransaction(this.chainConfig.MULTISEND_ADDR, constants_1.tx.zeroValue, metaTx.data, constants_1.SAFE_OPERATION_DELEGATECALL.toString(), constants_1.tx.avatarTxGas, constants_1.tx.baseGas, constants_1.tx.gasPrice, constants_1.tx.gasToken, constants_1.tx.refundReceiver, signature);
}
async execute(invRolesAddr, accessControlSafeAddr) {
const populatedTx = await this.build(invRolesAddr, accessControlSafeAddr);
const tx = await this.caller.sendTransaction({
...populatedTx,
gasLimit: constants_1.GAS_LIMIT,
});
console.log("Successfully executed Security's access control related whitelisting");
}
}
exports.AccessControllerWhitelistV2 = AccessControllerWhitelistV2;