superfuse-wizard
Version:
Interactive smart contract generator based on Superchain 's interoperability standard.
138 lines (117 loc) • 3.86 kB
text/typescript
import type { ContractBuilder, BaseFunction } from './contract';
import { supportsInterface } from './common-functions';
export const accessOptions = [false, 'ownable', 'roles'] as const;
// export const accessOptions = [false, 'ownable', 'roles', 'managed'] as const;
export type Access = typeof accessOptions[number];
function get_authorizeSetRoleFunction() {
const fn = {
name: '_authorizeSetRole',
args: [
{ name: '', type: 'address' },
{ name: '', type: 'uint256' },
{ name: '', type: 'bool' },
],
returns: [ ] ,
kind: 'internal' as const,
};
return fn;
}
/**
* Sets access control for the contract by adding inheritance.
*/
export function setAccessControl(c: ContractBuilder, access: Access) {
switch (access) {
case 'ownable': {
if (c.addParent(parents.Ownable, [])) {
c.addConstructorArgument({
type: 'address',
name: 'owner_'
});
c.addConstructorCode(`_initializeOwner(owner_);`);
}
break;
}
case 'roles': {
if (c.addParent(parents.EnumerableRoles)) {
c.addVariable(`uint256 public constant ADMIN_ROLE = 0;`);
c.addConstructorArgument({
type: 'address',
name: 'defaultAdmin_'
});
c.addConstructorCode(`if (defaultAdmin_ != address(0)) {
_setRole(defaultAdmin_, ADMIN_ROLE, true);
}`);
c.addModifier('override(EnumerableRoles)', get_authorizeSetRoleFunction());
c.addFunctionCode('_checkRole(ADMIN_ROLE);', get_authorizeSetRoleFunction());
}
// c.addOverride(parents.EnumerableRoles, supportsInterface);
break;
}
// case 'managed': {
// if (c.addParent(parents.AccessManaged, [ {lit: 'initialAuthority'} ])) {
// c.addConstructorArgument({
// type: 'address',
// name: 'initialAuthority'
// });
// }
// break;
// }
}
}
/**
* Enables access control for the contract and restricts the given function with access control.
*/
export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, access: Access, roleIdPrefix: string, roleIdValue: string, roleOwner: string | undefined) {
if (access === false) {
access = 'ownable';
}
setAccessControl(c, access);
switch (access) {
case 'ownable': {
c.addModifier('onlyOwner', fn);
break;
}
case 'roles': {
// const roleId = roleIdPrefix + '_ROLE';
// const addedConstant = c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`);
// if (roleOwner && addedConstant) {
// c.addConstructorArgument({type: 'address', name: roleOwner});
// c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
// }
// c.addModifier(`onlyRole(${roleId})`, fn);
// break;
const roleId = roleIdPrefix + '_ROLE';
const addedConstant = c.addVariable(`uint256 public constant ${roleId} = ${roleIdValue};`);
if (roleOwner && addedConstant) {
c.addConstructorArgument({
type: 'address',
name: roleOwner
});
// c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
c.addConstructorCode(`if (${roleOwner} != address(0)) {
_setRole(${roleOwner}, ${roleId}, true);
}`);
}
c.addModifier(`onlyRole(${roleId})`, fn);
break;
}
// case 'managed': {
// c.addModifier('restricted', fn);
// break;
// }
}
}
const parents = {
Ownable: {
name: 'Ownable',
path: '@solady-v0.1.8/auth/Ownable.sol',
},
EnumerableRoles: {
name: 'EnumerableRoles',
path: '@solady-v0.1.8/auth/EnumerableRoles.sol',
},
// AccessManaged: {
// name: 'AccessManaged',
// path: '@openzeppelin/contracts/access/manager/AccessManaged.sol',
// },
};