UNPKG

superfuse-wizard

Version:

Interactive smart contract generator based on Superchain 's interoperability standard.

269 lines (209 loc) 6.88 kB
import type { Contract, BaseFunction} from './contract'; import { ContractBuilder } from './contract'; import type { Access } from './set-access-control'; import {setAccessControl, requireAccessControl } from './set-access-control'; import { withCommonDefaults, defaults as commonDefaults } from "../shared/option-l2-native-superchain-ERC20"; import type { SharedL2NativeSuperchainERC20Options } from "../shared/option-l2-native-superchain-ERC20"; import { printContract } from "./print"; import { setInfo } from "./set-info"; import type { ClockMode} from './set-clock-mode'; import { clockModeDefault, setClockMode } from './set-clock-mode'; import { supportsInterface } from './common-functions'; import { defineFunctions } from '../utils/define-functions'; export function isAccessControlRequired(opts: Partial<SharedL2NativeSuperchainERC20Options>): boolean { return opts.mintable == true } function withDefaults(opts: SharedL2NativeSuperchainERC20Options): Required<SharedL2NativeSuperchainERC20Options> { return { ...opts, ...withCommonDefaults(opts), ownerAddress: opts.ownerAddress || commonDefaults.ownerAddress, burnable: opts.burnable ?? commonDefaults.burnable, pausable: opts.pausable ?? commonDefaults.pausable, premint: opts.premint || commonDefaults.premint, mintable: opts.mintable ?? commonDefaults.mintable, minterAddress: opts.minterAddress || commonDefaults.minterAddress, permit: opts.permit ?? commonDefaults.permit, votes: opts.votes ?? commonDefaults.votes, flashmint: opts.flashmint ?? commonDefaults.flashmint, }; } export function printL2NativeSuperchainERC20(opts: SharedL2NativeSuperchainERC20Options = commonDefaults): string { return printContract(buildL2NativeSuperchainERC20(opts)); } export function buildL2NativeSuperchainERC20(opts: SharedL2NativeSuperchainERC20Options): Contract { const allOpts = withDefaults(opts); const c = new ContractBuilder(allOpts.contractName); const { access, upgradeable, contractInfo } = allOpts; addBase(c); setERC7802Logic(c); // if (allOpts.burnable) { // addBurnable(c); // } // if (allOpts.pausable) { // addPausableExtension(c, access); // } // if (allOpts.premint) { // addPremint(c, allOpts.premint); // } if (allOpts.mintable) { addMintable(c, access); } // // Note: Votes requires Permit // if (allOpts.permit || allOpts.votes) { // addPermit(c); // } // if (allOpts.votes) { // const clockMode = allOpts.votes === true ? clockModeDefault : allOpts.votes; // addVotes(c, clockMode); // } // if (allOpts.flashmint) { // addFlashMint(c); // } setAccessControl(c, access); // setUpgradeable(c, upgradeable, access); addBaseConstructors(c); setInfo(c, contractInfo); return c; } function addBase(c: ContractBuilder) { //name c.addModifier('virtual override', functions.name); c.addFunctionCode(`return _name;`, functions.name); //symbol c.addModifier('virtual override', functions.symbol); c.addFunctionCode(`return _symbol;`, functions.symbol); //decimals c.addModifier('override', functions.decimals); c.addFunctionCode(`return _decimals;`, functions.decimals); } function addBaseConstructors(c: ContractBuilder) { c.addVariable(`string private _name;`); c.addVariable(`string private _symbol;`); c.addVariable(`uint8 private immutable _decimals;`); c.addConstructorCode(`_name = name_; _symbol = symbol_; _decimals = decimals_;`); c.addConstructorArgument({ type: { name: 'string memory', transpiled: false, }, name: 'name_', }); c.addConstructorArgument({ type: { name: 'string memory', transpiled: false, }, name: 'symbol_', }); c.addConstructorArgument({ type: { name: 'uint8', transpiled: false, }, name: 'decimals_', }); } function setERC7802Logic(c: ContractBuilder) { const SuperchainERC20 = { name: 'SuperchainERC20', path: '@superfuse-core/L2/SuperchainERC20.sol', }; c.addParent( SuperchainERC20, [], ); } // export const premintPattern = /^(\d*)(?:\.(\d+))?(?:e(\d+))?$/; // function addAuthorizable(c: ContractBuilder, access: Access) { // requireAccessControl(c, functions.mintTo, access, 'ADMIN','0', 'initialAdmin'); // c.addFunctionCode('_checkRole(ADMIN_ROLE);', functions._authorizeSetRole); // } function addMintable(c: ContractBuilder, access: Access) { requireAccessControl(c, functions.mintTo, access, 'MINTER','1', 'minter_'); c.addFunctionCode('_mint(to_, amount_);', functions.mintTo); } // function addPermit(c: ContractBuilder) { // // function addPermit(c: ContractBuilder, name: string) { // const ERC20Permit = { // name: 'ERC20Permit', // path: '@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol', // }; // c.addParent(ERC20Permit, [{ lit: '_name' }]); // c.addOverride(ERC20Permit, functions.nonces); // } // function addVotes(c: ContractBuilder, clockMode: ClockMode) { // if (!c.parents.some(p => p.contract.name === 'ERC20Permit')) { // throw new Error('Missing ERC20Permit requirement for ERC20Votes'); // } // const ERC20Votes = { // name: 'ERC20Votes', // path: '@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol', // }; // c.addParent(ERC20Votes); // c.addOverride(ERC20Votes, functions._update); // c.addImportOnly({ // name: 'Nonces', // path: '@openzeppelin/contracts/utils/Nonces.sol', // }); // c.addOverride({ // name: 'Nonces', // }, functions.nonces); // setClockMode(c, ERC20Votes, clockMode); // } const functions = defineFunctions({ name: { kind: 'public' as const, args: [ ], returns: ['string memory'], mutability: 'view' as const, }, symbol: { kind: 'public' as const, args: [ ], returns: ['string memory'], mutability: 'view' as const, }, decimals: { kind: 'public' as const, args: [ ], returns: ['uint8'], mutability: 'view' as const, }, // _authorizeSetRole: { // kind: 'internal' as const, // args: [ // { name: '', type: 'address' }, // { name: '', type: 'uint256' }, // { name: '', type: 'bool' }, // ], // }, mintTo: { kind: 'external' as const, args: [ { name: 'to_', type: 'address' }, { name: 'amount_', type: 'uint256' }, ], }, nonces: { kind: 'public' as const, args: [ { name: 'owner', type: 'address' }, ], returns: ['uint256'], mutability: 'view' as const, }, _update: { kind: 'internal' as const, args: [ { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }, ], }, });