Token contracts

Mint, owner, blacklist, and proxy risks

What those four privileges let a key do after you buy, why the same flags on USDT are not the same flags on a new token, and what renouncing ownership leaves in place.

A privilege is a key, not a label

Most token contracts that hurt buyers without a fake website do it with a privilege left in the code. Someone can mint more supply, pause transfers, blacklist a seller, rewrite a balance, or replace the contract through a proxy. The ticker does not tell you which of those exist. The functions do. This page says what each one can do tomorrow, how the checker classifies it, and why a known stablecoin is handled as context instead of a do-not-buy score.

The classification is mechanical. Critical means a source reported a strong scam signal. A warning means a serious lever is present. Context means the address is on a short allowlist of canonical contracts, and the lever is one this site expects from that issuer or wrapper. Context is not applied because the symbol string is USDT. It is applied because the chain and the address match. A copy on another address keeps the warning.

Read this next to the explorer walkthrough. The checker is the summary. The source is the thing being summarized.

Mint

Minting creates tokens. Total supply goes up. If the new tokens are sold into the pool you bought from, the price falls and the minter receives the asset you traded in. That can happen with no failed sell and no removed liquidity. The buyers still hold their tokens. The tokens are worth less because supply and the pool both changed.

A public mint that anyone can call is rare in a traded token and easy to see. The usual shape is onlyOwner, or a minter role, or an 'issue' function on a stablecoin. GoPlus reports is_mintable. On Solana, a mint authority that is still set can create more of the asset. The checker turns both into a warning: mint authority is on. It does not try to decide whether the mint is a collateralized stablecoin or a memecoin. You do that by knowing the address.

Hidden mint is the variant that does not use an obvious name. The owner, or a function the owner can call, increases a balance or total supply in a way a casual read misses. When GoPlus reports that the owner can change balances, the checker treats that as critical, not as a warning. A balance rewrite can also zero a wallet, which is worse than dilution. Do not file that flag under 'they might print a little.'

A fixed total supply with no mint function removes this one lever. It does not remove a blacklist, a tax, or a proxy. People say 'renounced and no mint' as if it were the whole audit. It is one line of the audit.

Owner

Owner is the address allowed to call the gated functions. On an OpenZeppelin-style Ownable contract, onlyOwner checks that the caller is that address, and renounceOwnership sets it to the zero address so those calls fail. That pattern is common. It is not universal. A contract can name the variable anything, can keep several roles, and can implement renounce so that it emits an event and changes nothing.

The checker does not assume the word renounce is honest. It looks at what GoPlus returns. A hidden owner is critical: the contract makes the privilege harder to watch. Ownership that can be taken back after it looks renounced is a warning. A pause function is a warning on an unknown token because the owner can stop transfers. An owner who can change the tax later is a warning. A self-destruct function is critical because it can wipe the contract.

Pause deserves a plain example. Transfers work today. You buy. The owner calls pause. Transfers revert for everyone, or for everyone except the owner, depending on how the function was written. Your sell does not fail because of slippage. It fails because the contract is switched off. Combined with a blacklist, pause is also how a regulated stablecoin halts. On canonical USDT that switch is issuer context. On a token you found in a reply, it is a reason to leave.

If owner() is the zero address, say so, and then look for a second key. Proxy admin, a role in an AccessControl list, a backup 'governance' address, and a function that can reclaim ownership are all second keys. Renouncing the visible owner while keeping the proxy admin renounces the part you screenshotted.

Blacklist and freeze

A blacklist is a mapping from address to a boolean. The transfer function reverts if the sender or the recipient is listed. The owner can add addresses. From the outside this looks like a random sell failure for the listed wallet and a normal sell for everyone else. It is the core of many sell-blocking contracts, described in the honeypot guide.

It is also how USDT and USDC work. Circle’s FiatToken-style USDC and Tether’s USDT can block specified addresses. They publish that control. Freezing a sanctioned address is the point of the function. The checker’s allowlist includes the canonical Ethereum USDT address 0xdAC17F958D2ee523a2206206994597C13D831ec7 and the canonical Ethereum USDC address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, plus a short set of other major contracts on other chains. On those addresses, blacklist, freeze, pause, mint, and proxy are labeled context. The summary does not say do not buy unless a separate critical signal remains, such as an actual honeypot.

That exception is narrow on purpose. WBTC and WETH are on the list as wrappers, not as stablecoins. A wrapper’s mint is the deposit path: lock the underlying, receive the wrapped token. A freeze or blacklist on a wrapper is not given the stablecoin’s excuse. WETH is not supposed to freeze holders. If a source flags a freeze on canonical WETH, read it. Do not assume the allowlist swallowed every warning.

On Solana the analogous switches are mint authority and freeze authority. Freeze authority can stop an account from moving the token. The checker marks that critical, including on a stablecoin, unless the mint address is the canonical one on the allowlist and the signal is in the issuer-context set. A new Solana mint with freeze authority still set is not 'probably a stablecoin.' Stablecoins say who the issuer is, on an address you can compare.

Proxy and the code you did not read

A proxy keeps one address stable and delegatecalls an implementation contract. Users approve and trade the proxy address. The logic they are bound by is whatever implementation the admin currently points at. EIP-1967 is the usual place that address is stored. Etherscan’s Read as proxy view follows it. Reading only the proxy shows a forwarder.

An upgrade replaces the implementation. The new code can add a tax, a blacklist, or a mint that the old code did not have. The pool still points at the same token address, so nothing on the chart announces the change except the contract tab. GoPlus and honeypot.is both surface a proxy flag when they detect one. The checker turns that into a warning: the code you read today may not be the code that runs tomorrow. On an allowlisted stablecoin or wrapper, that warning becomes context, because those contracts are proxies so the issuer can patch them. The power is the same power. The difference is who holds it and whether you already accept that issuer.

Two mistakes follow from that. The first is treating every proxy as a scam. Major stablecoins are proxies. The second is treating 'not a proxy' as safety. A non-upgradeable contract can still mint, blacklist, and tax. Proxy is one lever.

There is a practical check. Write down the implementation address today. If you still hold the token later, compare it. A change means you are in a new contract whether or not the token page looks the same. You will not get a push notification from the chain.

How the rows combine

One warning is a medium score. Three warnings are a high score. Any critical signal is a critical score, and the ordinary summary says not to buy. Context rows are removed from that count. They stay visible so you can see the issuer power. They do not, by themselves, push canonical USDT into the critical band. A honeypot flag on that same address would still be critical. The allowlist does not launder a failed sell.

Empty sources do not fill the band with clears. If GoPlus has no record, the rows it would have covered are not checked. A medium score from a single warning, with everything else unchecked, is a thin report. Read the source list and the checked-at time on the result before you treat the gauge as a survey of the contract.

Holder concentration sits beside these privileges. One unlocked holder with at least half the supply is a warning. At least 80 percent is critical. Burn addresses and holders a source marks as locked are left out of that figure. A mint privilege and a concentrated holder are different facts: one can create supply, the other already has it.

  • You can name the address that can mint, or you can say the mint authority is none.
  • You can name the owner, or you have seen a hidden-owner or reclaim flag and stopped.
  • You know whether a blacklist or pause exists, and whether this address is the canonical issuer contract or a lookalike.
  • You opened the implementation if the contract is a proxy, and you know an admin can change it.
  • You did not treat a renounce event as proof that every role is gone.
  • You ran the address in the checker and read context rows as powers, not as a pass.

Questions

The owner is the zero address. Is the token safe?

The visible Ownable owner is gone, if that function is telling the truth. A proxy admin, a hidden owner, a reclaim function, a mint role, or a liquidity position can all remain. Safety is not a zero in one field.

Why does the checker say context instead of do not buy on USDT?

The canonical addresses for major stablecoins and wrappers are allowlisted. Issuer powers such as blacklist, pause, mint, and proxy are shown as context: the issuer can freeze, which is normal for a regulated stablecoin, or the wrapper can be upgraded. A different address with the same ticker is not on the list. A honeypot or a balance rewrite on an allowlisted address is still critical.

Is a mint function always hostile?

No. A collateralized stablecoin mints when someone deposits reserves, and WETH mints when someone deposits ether. The function is hostile when the caller can mint into a pool without the matching asset. The checker will not make that distinction for you. Knowing the issuer is the distinction.

The report shows three warnings and a high score. Which do I read first?

Read mint, owner, blacklist, and proxy before the gauge. Three of those, with no critical flag, are enough for a high score. Any one of them can be a reason not to buy an unknown token. The gauge is only the count.

Can the project renounce later and make my bags safe?

They can remove some keys later. They can also use the keys first. A promise to renounce is not a state on chain. The state on chain is the owner and the implementation address right now.

Related