access-manager.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. const { ethers } = require('hardhat');
  2. const { MAX_UINT64 } = require('./constants');
  3. const time = require('./time');
  4. const { upgradeableSlot } = require('./storage');
  5. function buildBaseRoles() {
  6. const roles = {
  7. ADMIN: {
  8. id: 0n,
  9. },
  10. SOME_ADMIN: {
  11. id: 17n,
  12. },
  13. SOME_GUARDIAN: {
  14. id: 35n,
  15. },
  16. SOME: {
  17. id: 42n,
  18. },
  19. PUBLIC: {
  20. id: MAX_UINT64,
  21. },
  22. };
  23. // Names
  24. Object.entries(roles).forEach(([name, role]) => (role.name = name));
  25. // Defaults
  26. for (const role of Object.keys(roles)) {
  27. roles[role].admin = roles.ADMIN;
  28. roles[role].guardian = roles.ADMIN;
  29. }
  30. // Admins
  31. roles.SOME.admin = roles.SOME_ADMIN;
  32. // Guardians
  33. roles.SOME.guardian = roles.SOME_GUARDIAN;
  34. return roles;
  35. }
  36. const formatAccess = access => [access[0], access[1].toString()];
  37. const MINSETBACK = time.duration.days(5);
  38. const EXPIRATION = time.duration.weeks(1);
  39. const EXECUTION_ID_STORAGE_SLOT = upgradeableSlot('AccessManager', 3n);
  40. const CONSUMING_SCHEDULE_STORAGE_SLOT = upgradeableSlot('AccessManaged', 0n);
  41. /**
  42. * @requires this.{manager, caller, target, calldata}
  43. */
  44. async function prepareOperation(manager, { caller, target, calldata, delay }) {
  45. const scheduledAt = (await time.clock.timestamp()) + 1n;
  46. await time.increaseTo.timestamp(scheduledAt, false); // Fix next block timestamp for predictability
  47. return {
  48. schedule: () => manager.connect(caller).schedule(target, calldata, scheduledAt + delay),
  49. scheduledAt,
  50. operationId: hashOperation(caller, target, calldata),
  51. };
  52. }
  53. const lazyGetAddress = addressable => addressable.address ?? addressable.target ?? addressable;
  54. const hashOperation = (caller, target, data) =>
  55. ethers.keccak256(
  56. ethers.AbiCoder.defaultAbiCoder().encode(
  57. ['address', 'address', 'bytes'],
  58. [lazyGetAddress(caller), lazyGetAddress(target), data],
  59. ),
  60. );
  61. module.exports = {
  62. buildBaseRoles,
  63. formatAccess,
  64. MINSETBACK,
  65. EXPIRATION,
  66. EXECUTION_ID_STORAGE_SLOT,
  67. CONSUMING_SCHEDULE_STORAGE_SLOT,
  68. prepareOperation,
  69. hashOperation,
  70. };