Skip to main content
Glama

OpenZeppelin Contracts MCP Server

Official
by OpenZeppelin
erc20.test.ts7.19 kB
import test from 'ava'; import type { OptionsError } from '.'; import { erc20 } from '.'; import type { ERC20Options } from './erc20'; import { buildERC20 } from './erc20'; import { printContract } from './print'; function testERC20(title: string, opts: Partial<ERC20Options>) { test(title, t => { const c = buildERC20({ name: 'MyToken', symbol: 'MTK', ...opts, }); t.snapshot(printContract(c)); }); } /** * Tests external API for equivalence with internal API */ function testAPIEquivalence(title: string, opts?: ERC20Options) { test(title, t => { t.is( erc20.print(opts), printContract( buildERC20({ name: 'MyToken', symbol: 'MTK', ...opts, }), ), ); }); } testERC20('basic erc20', {}); testERC20('erc20 name is unicodeSafe', { name: 'MyTokeć' }); testERC20('erc20 burnable', { burnable: true, }); testERC20('erc20 pausable', { pausable: true, access: 'ownable', }); testERC20('erc20 pausable with roles', { pausable: true, access: 'roles', }); testERC20('erc20 pausable with managed', { pausable: true, access: 'managed', }); testERC20('erc20 burnable pausable', { burnable: true, pausable: true, }); testERC20('erc20 preminted', { premint: '1000', }); testERC20('erc20 premint of 0', { premint: '0', }); function testPremint(scenario: string, premint: string, expectedError?: string) { test(`erc20 premint - ${scenario} - ${expectedError ? 'invalid' : 'valid'}`, async t => { if (expectedError) { const error = t.throws(() => buildERC20({ name: 'MyToken', symbol: 'MTK', premint, }), ); t.is((error as OptionsError).messages.premint, expectedError); } else { const c = buildERC20({ name: 'MyToken', symbol: 'MTK', premint, }); t.snapshot(printContract(c)); } }); } testPremint('max literal', '115792089237316195423570985008687907853269984665640564039457.584007913129639935'); // 2^256 - 1, shifted by 18 decimals testPremint( 'max literal + 1', '115792089237316195423570985008687907853269984665640564039457.584007913129639936', 'Value is greater than uint256 max value', ); testPremint('no arithmetic overflow', '115792089237316195423570985008687907853269984665640564039457'); // 2^256 - 1, truncated by 18 decimals testPremint( 'arithmetic overflow', '115792089237316195423570985008687907853269984665640564039458', 'Amount would overflow uint256 after applying decimals', ); testPremint('e notation', '1e59'); testPremint('e notation arithmetic overflow', '1e60', 'Amount would overflow uint256 after applying decimals'); testERC20('erc20 mintable', { mintable: true, access: 'ownable', }); testERC20('erc20 mintable with roles', { mintable: true, access: 'roles', }); testERC20('erc20 callback', { callback: true, }); testERC20('erc20 permit', { permit: true, }); testERC20('erc20 votes', { votes: true, }); testERC20('erc20 votes + blocknumber', { votes: 'blocknumber', }); testERC20('erc20 votes + timestamp', { votes: 'timestamp', }); testERC20('erc20 flashmint', { flashmint: true, }); testERC20('erc20 crossChainBridging custom', { crossChainBridging: 'custom', }); testERC20('erc20 crossChainBridging custom ownable', { crossChainBridging: 'custom', access: 'ownable', }); testERC20('erc20 crossChainBridging custom ownable mintable burnable', { crossChainBridging: 'custom', access: 'ownable', mintable: true, burnable: true, }); testERC20('erc20 crossChainBridging custom roles', { crossChainBridging: 'custom', access: 'roles', }); testERC20('erc20 crossChainBridging custom managed', { crossChainBridging: 'custom', access: 'managed', }); testERC20('erc20 crossChainBridging superchain', { crossChainBridging: 'superchain', }); testERC20('erc20 crossChainBridging superchain ownable', { crossChainBridging: 'superchain', access: 'ownable', }); testERC20('erc20 crossChainBridging superchain roles', { crossChainBridging: 'superchain', access: 'roles', }); testERC20('erc20 crossChainBridging superchain managed', { crossChainBridging: 'superchain', access: 'managed', }); testERC20('erc20 crossChainBridging custom upgradeable', { crossChainBridging: 'custom', upgradeable: 'transparent', }); testERC20('erc20 crossChainBridging superchain upgradeable', { crossChainBridging: 'superchain', upgradeable: 'transparent', }); test('erc20 crossChainBridging superchain, premintChainId required', async t => { const error = t.throws(() => buildERC20({ name: 'MyToken', symbol: 'MTK', crossChainBridging: 'superchain', premint: '2000', }), ); t.is( (error as OptionsError).messages.premintChainId, 'Chain ID is required when using Premint with Cross-Chain Bridging', ); }); testERC20('erc20 premint ignores chainId when not crossChainBridging', { premint: '2000', premintChainId: '10', }); testERC20('erc20 premint chainId crossChainBridging custom', { premint: '2000', premintChainId: '10', crossChainBridging: 'custom', }); testERC20('erc20 premint chainId crossChainBridging superchain', { premint: '2000', premintChainId: '10', crossChainBridging: 'superchain', }); testERC20('erc20 full crossChainBridging custom upgradeable uups', { premint: '2000', access: 'roles', burnable: true, mintable: true, pausable: true, callback: true, permit: true, votes: true, flashmint: true, crossChainBridging: 'custom', premintChainId: '10', upgradeable: 'uups', }); testERC20('erc20 full upgradeable transparent', { premint: '2000', access: 'roles', burnable: true, mintable: true, pausable: true, callback: true, permit: true, votes: true, flashmint: true, upgradeable: 'transparent', }); testERC20('erc20 full upgradeable uups', { premint: '2000', access: 'roles', burnable: true, mintable: true, pausable: true, callback: true, permit: true, votes: true, flashmint: true, upgradeable: 'uups', }); testERC20('erc20 full upgradeable uups managed', { premint: '2000', access: 'managed', burnable: true, mintable: true, pausable: true, callback: true, permit: true, votes: true, flashmint: true, upgradeable: 'uups', }); testAPIEquivalence('erc20 API default'); testAPIEquivalence('erc20 API basic', { name: 'CustomToken', symbol: 'CTK' }); testAPIEquivalence('erc20 API full upgradeable', { name: 'CustomToken', symbol: 'CTK', premint: '2000', access: 'roles', burnable: true, mintable: true, pausable: true, callback: true, permit: true, votes: true, flashmint: true, upgradeable: 'uups', }); test('erc20 API assert defaults', async t => { t.is(erc20.print(erc20.defaults), erc20.print()); }); test('erc20 API isAccessControlRequired', async t => { t.is(erc20.isAccessControlRequired({ mintable: true }), true); t.is(erc20.isAccessControlRequired({ pausable: true }), true); t.is(erc20.isAccessControlRequired({ upgradeable: 'uups' }), true); t.is(erc20.isAccessControlRequired({ upgradeable: 'transparent' }), false); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/OpenZeppelin/contracts-wizard'

If you have feedback or need assistance with the MCP directory API, please join our Discord server