Contract Powers Registry / base
USDC (Base)
0x833589fcd6edb6e08f4c7c32d4f71b54bda02913 on base
upgradeable proxy (zeppelinos.implementation); admin key is a plain EOA; retained powers: blacklist, grant_minter, mint, ownership, pause, sweep, upgrade; 2 further owner-only function(s) the engine could not categorise (listed under coverage).
Can this code be replaced?
Yes — this is a proxy. The address you interact with holds no logic of its own; it forwards calls to a second contract. Whoever holds the upgrade right can point it somewhere else, and every behaviour described on this page changes with it.
| Pattern | zeppelinos.implementation |
|---|---|
| Current logic | 0x2ce6311ddae708829bc0784c967b7d77d19fd779 |
| Logic name | FiatTokenV2_2 |
| Logic source verified | Yes |
Raw storage evidence (1)
zeppelinos.implementation→0x2ce6311ddae708829bc0784c967b7d77d19fd779
Who holds the keys?
| Owner / admin | 0x3abd6f64a422225e61e435bae41db12096106df7 |
|---|---|
| Found via | owner() |
| That address is | A plain wallet (EOA) |
owner is a plain externally-owned account — a single private key controls it. In practice: one private key, held by someone, can exercise every power listed below. There is no on-chain delay and no second approver.
What the privileged role can still do
Each card is a capability found in the code. declared = the contract’s published interface exposes it. bytecode-heuristic = the 4-byte selector appears in the compiled code, which often means the contract implements it — but it can equally be a function this contract calls on another contract. Only a verified source settles that.
Addresses can be frozen
declaredA specific address can be blocked from moving its own balance.
Evidence (3)
blacklist(address)implementation-abiunBlacklist(address)implementation-abiblacklist(address)implementation-bytecode
Minting rights can be handed out
declaredThe privileged role does not have to mint itself — it can appoint another address as a minter, sometimes with its own allowance.
Evidence (2)
configureMinter(address,uint256)implementation-abiremoveMinter(address)implementation-abi
New tokens can be created
declaredSupply is not fixed by the code — the privileged role can issue more.
Evidence (2)
mint(address,uint256)implementation-abimint(address,uint256)implementation-bytecode
Control can be transferred
declaredThe privileged role itself can be handed to another address, or renounced.
Evidence (2)
transferOwnership(address)implementation-abitransferOwnership(address)implementation-bytecode
Transfers can be halted
declaredA privileged role can stop activity, including your ability to exit.
Evidence (4)
pause()implementation-abiunpause()implementation-abipause()implementation-bytecodeunpause()implementation-bytecode
Tokens can be pulled out
declaredA rescue/sweep path exists that moves tokens held by the contract.
Evidence (2)
rescueERC20(address,address,uint256)implementation-abiupdateRescuer(address)implementation-abi
Code can be replaced
declaredThe logic behind this address can be swapped for different code. Everything below can change with it.
Evidence (4)
changeAdmin(address)abiupgradeTo(address)abiupgradeToAndCall(address,bytes)abichangeAdmin(address)bytecode-selector
What this page did not categorise
2 more functions here are restricted to a privileged role,
and this engine has no category for them. The list above matches function names against a fixed
set of power categories. These ones are gated in the published source — an only… modifier or a
sender check — but their names match nothing, so no card was written for them. They are named here in full
rather than dropped, because a report that looks complete is worse than one that says where it stops.
| Function | Name shape | Restricted by | Read from |
|---|---|---|---|
burn(uint256) |
— | onlyMinters | implementation source |
updateMasterMinter(address) |
sets a value | onlyOwner | implementation source |
Where to start: 1 of these 2 are a repeating name shape —
1 sets a value — which usually means configuration rather than a new capability. The name shape is read
from the name alone and claims nothing about behaviour; setOracle and setFeeRecipient
share it and differ completely. The other 1 match no shape, and that is where to look first.
What to do with this: open the contract on the explorer and read these functions. The gate shown is the exact text found in the source. This engine does not guess what the function does. Of the 34 state-changing functions in the published interface, 15 matched a known category and 2 are listed here.
Is there a bug bounty on this?
No live bug-bounty program matched this contract’s name in my index (169 Immunefi + 52 Cantina programs, rebuilt daily). Matching is by name, not by address — a program can cover this contract without the names lining up. Browse the full index at Bounty Radar.
Raw facts
| Chain | base (chainId 8453) |
|---|---|
| Contract name | FiatTokenProxy |
| Compiler | v0.6.12+commit.27d51765 |
| License | — |
| Bytecode size | 1,852 bytes (logic: 23,464) |
| DELEGATECALL | present |
| SELFDESTRUCT | absent |
| CREATE2 | absent |
| Explorer | view on block explorer ↗ |
Has any of this changed?
This page is rebuilt from the chain and diffed against the previous day. If the implementation behind this address is replaced, or the privileged key moves, it is listed on what changed with the before and after — also as RSS, so it can reach you without you coming back.
How this was produced, and what it cannot tell you
Storage slots, bytecode and eth_call results were read from public RPC nodes;
where the source is verified, the published interface was read too. Nothing here is copied from another
site’s opinion. Generated in 976 ms on 2026-10-12.
- confidence="declared" means the ABI exposes the function. confidence="bytecode-heuristic" means the 4-byte selector appears in the code — usually its own dispatch table, but it can also be a selector this contract CALLS on another contract. Only a verified ABI settles it.
- admin.controller identifies a Safe-style multisig, an OZ timelock, or an owned admin contract by the functions it answers. A contract that answers none is reported as unknown-contract, not as safe.
- bounty.match="name-heuristic" matches a contract NAME to a program name; it is not proof the address is in scope.
- coverage.unclassifiedOwnerOnly lists functions the source restricts to a privileged role but which match no power category here. It is read from the verified source by matching function name + argument count, so an overloaded or inherited function can be attributed imprecisely. When coverage.checked is false the engine could not read the source at all, and the power list must be treated as a floor.
What would change the answer: an upgrade after the date above; a power reachable only through a contract this one trusts; or role-based access control, whose holders this registry does not enumerate. Re-read the chain before you rely on it.
Machine-readable
Same facts as JSON, free, no key: /c/base/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913.json.
Live lookups for any address (not just this list) are $0.05 per call.
Want a human-grade read?
This page is automated pattern-matching. If you need someone to actually read the code and tell you what breaks, I do fixed-scope micro-audits — you pay after you read the report.