@solvprotocol/upgrade-safe-transpiler
Version:
Solidity preprocessor used to generate OpenZeppelin Contracts Upgrade Safe.
55 lines (46 loc) • 1.64 kB
text/typescript
import { ContractDefinition } from 'solidity-ast';
import { Node } from 'solidity-ast/node';
import { getConstructor } from '../solc/ast-utils';
import { execall } from '../utils/execall';
const errorKinds = [
'state-variable-assignment',
'state-variable-immutable',
'external-library-linking',
'struct-definition',
'enum-definition',
'constructor',
'delegatecall',
'selfdestruct',
'missing-public-upgradeto',
] as const;
type ValidationErrorKind = typeof errorKinds[number];
export function hasOverride(node: Node, override: ValidationErrorKind): boolean {
return getOverrides(node).includes(override);
}
export function getOverrides(node: Node): ValidationErrorKind[] {
if ('documentation' in node) {
const doc =
typeof node.documentation === 'string' ? node.documentation : node.documentation?.text ?? '';
const result: string[] = [];
for (const { groups } of execall(
/^\s*(?:@(?<title>\w+)(?::(?<tag>[a-z][a-z-]*))? )?(?<args>(?:(?!^\s@\w+)[^])*)/m,
doc,
)) {
if (groups && groups.title === 'custom' && groups.tag === 'oz-upgrades-unsafe-allow') {
result.push(...groups.args.split(/\s+/));
}
}
result.forEach(arg => {
if (!(errorKinds as readonly string[]).includes(arg)) {
throw new Error(`NatSpec: oz-upgrades-unsafe-allow argument not recognized: ${arg}`);
}
});
return result as ValidationErrorKind[];
} else {
return [];
}
}
export function hasConstructorOverride(contract: ContractDefinition): boolean {
const ctor = getConstructor(contract);
return ctor ? hasOverride(ctor, 'constructor') : false;
}