Skip to main content
Glama
lordbasilaiassistant-sudo

base-security-scanner-mcp

check_token_permissions

Analyze token contract permissions to verify minting, pausing, blacklisting, fee changes, trading restrictions, and ownership status on Base mainnet.

Instructions

Check owner permissions on a token: can mint? can pause? can blacklist? can change fees? Can disable trading? Ownership renounced?

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
token_addressYesToken contract address on Base mainnet

Implementation Reference

  • Implementation of the check_token_permissions MCP tool. It retrieves the contract bytecode, extracts selectors, checks for specific dangerous function selectors, retrieves ownership information, and summarizes the findings.
    server.tool(
      "check_token_permissions",
      "Check owner permissions on a token: can mint? can pause? can blacklist? can change fees? Can disable trading? Ownership renounced?",
      {
        token_address: z.string().describe("Token contract address on Base mainnet"),
      },
      async ({ token_address }) => {
        try {
          const code = await getContractBytecode(token_address);
          if (code === "0x" || code.length <= 2) {
            return ok({ token: token_address, isContract: false, message: "Not a contract" });
          }
    
          const selectors = extractSelectors(code);
          const ownership = await checkOwnership(token_address);
    
          const permissions: Record<string, { present: boolean; risk: string; detail: string }> = {
            canMint: {
              present: selectors.includes("40c10f19"),
              risk: "critical",
              detail: "mint(address,uint256) -- can create new tokens",
            },
            canPause: {
              present: selectors.includes("8456cb59"),
              risk: "high",
              detail: "pause() -- can freeze all transfers",
            },
            canBlacklist: {
              present: selectors.includes("44337ea1"),
              risk: "high",
              detail: "blacklist(address) -- can block specific addresses",
            },
            canChangeFees: {
              present: selectors.includes("69fe0e2d"),
              risk: "high",
              detail: "setFee(uint256) -- can change transaction fees",
            },
            canDisableTrading: {
              present: selectors.includes("1a8145bb"),
              risk: "critical",
              detail: "setTradingActive(bool) -- can disable all trading",
            },
            canSetMaxTx: {
              present: selectors.includes("e4748b9e"),
              risk: "high",
              detail: "setMaxTxAmount(uint256) -- can restrict transaction sizes",
            },
            canSetMaxWallet: {
              present: selectors.includes("8ee88c53"),
              risk: "high",
              detail: "setMaxWalletSize(uint256) -- can restrict wallet holdings",
            },
            canBurnOthers: {
              present: selectors.includes("79cc6790"),
              risk: "medium",
              detail: "burnFrom(address,uint256) -- can burn tokens from other addresses",
            },
            canUpgrade: {
              present: selectors.includes("3659cfe6") || selectors.includes("4f1ef286"),
              risk: "critical",
              detail: "upgradeTo/upgradeToAndCall -- proxy can be upgraded to new logic",
            },
            canRenounceOwnership: {
              present: selectors.includes("715018a6"),
              risk: "info",
              detail: "renounceOwnership() -- ownership can be given up (positive sign)",
            },
            canTransferOwnership: {
              present: selectors.includes("f2fde38b"),
              risk: "medium",
              detail: "transferOwnership(address) -- ownership can be moved to another address",
            },
          };
    
          const dangerousPermissions = Object.entries(permissions)
            .filter(([, v]) => v.present && (v.risk === "critical" || v.risk === "high"))
            .map(([k]) => k);
    
          return ok({
            token: token_address,
            ownership: serializeBigInts(ownership) as Record<string, unknown>,
            permissions,
            dangerousPermissions,
            riskSummary: dangerousPermissions.length === 0
              ? "No dangerous owner permissions detected"
              : `${dangerousPermissions.length} dangerous permission(s) found: ${dangerousPermissions.join(", ")}`,
          });
        } catch (err) {
          return fail(`check_token_permissions failed: ${err instanceof Error ? err.message : String(err)}`);
        }
      }
    );

Latest Blog Posts

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/lordbasilaiassistant-sudo/base-security-scanner-mcp'

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