The holder of a role is not always the one who executes it: one measured case

A contract page shows who holds the admin power. We checked whether the holder shown is the one the contract actually lets act, by simulating each privileged call from each holder. On what we measured (46 call forms probed on 14 AccessControl contracts (Ethereum 4, Robinhood Chain 7, Plasma 1, HyperEVM 2), three contracts measured by hand (a beacon and its tokens on Robinhood Chain, Ethena's minting contract, Aave V3's pool configurator) and 26 Ownable owners on Ethereum) the answer was the same every time: the holder shown executes what the role is named for, 0 divergences. One contract still showed a power the three-part score does not carry.

How much was measured

Of 171 EVM targets classified, AccessControl is rare: 14 contracts could be probed, with 46 call forms in all, 0 divergences. Blocks: Ethereum 26,173,603; Robinhood Chain 86,351,252; Plasma 34,834,451; HyperEVM latest, about 48,320,159 (its public RPC ignores the block number); two public nodes that agreed, except Plasma, Monad, Tempo and HyperEVM (one node).

Contracts with no AccessControl121
AccessControl contracts measured14
Tempo precompiles (not measured)10
No code at the address16
Roles held on another contract6
Role holders unreadable4

8 of the 46 forms had no executor among the holders (3 were answered by a business guard; the other 5 are not read either (a plausible argument would be needed to call them). None of the 8 is counted as a divergence). Solana (26 targets) was not part of this pass.

Reserve. The candidates probed are the holders read from each contract. An executor outside the holders (a timelock, another route) is visible only through a measurement by hand, as for the three contracts above.

The case: Ethena's USDe minting contract, Ethereum mainnet

0xe3490297a08d6fC8Da46Edb7B6142E4F461b62D3. Four accounts without code, holding GATEKEEPER_ROLE, can switch off minting and redeeming and remove any minter or redeemer, with no delay. Read at block 26,173,362 on two public nodes (ethereum-rpc.publicnode.com, gateway.tenderly.co/public/mainnet) that agreed. The accounts, shortened: 0x0F56…5BD9, 0x4960…8996, 0xAB91…A7dC, 0xb6EC…CCA3.

Call simulatedExecuted by
disableMintRedeem(), removeMinterRole(address), removeRedeemerRole(address)the four GATEKEEPER_ROLE accounts only
setStablesDeltaLimit(uint128), addCustodianAddress(address), addWhitelistedBenefactor(address), transferAdmin(address), grantRole(bytes32,address)the DEFAULT_ADMIN_ROLE timelock only (24-hour delay, skipped by the simulation, counted separately in the score)
removeSupportedAsset(address), removeCustodianAddress(address), removeWhitelistedBenefactor(address)not read: the answer to a stranger differs because the argument is not in the set, a plausible argument would be needed
any probed actionthe COLLATERAL_MANAGER_ROLE Safe executes none of them

These four accounts are not part of the (admin key, multisig, timelock) score, which is why this page exists: a power worth stating next to the score.

Replay it yourself

RPC=https://gateway.tenderly.co/public/mainnet      # a node that serves a full range of logs
# 1. who holds the role: every RoleGranted and RoleRevoked for the role id, newest event wins
#    topics: 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d (granted), 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b (revoked), role id 0x3c63e605be3290ab6b04cfc46c6e1516e626d43236b034f09d7ede1d017beb0c
curl -s -X POST $RPC -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"address":"0xe3490297a08d6fC8Da46Edb7B6142E4F461b62D3","fromBlock":"0x1100000","toBlock":"0x18f5fb2","topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x3c63e605be3290ab6b04cfc46c6e1516e626d43236b034f09d7ede1d017beb0c"]}]}'
# 2. is the holder a plain account? 0x means no code
curl -s -X POST $RPC -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["HOLDER","0x18f5fb2"]}'
# 3. may it call disableMintRedeem()? ok = the call is allowed; a stranger is refused with an AccessControl error
curl -s -X POST $RPC -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"from":"HOLDER","to":"0xe3490297a08d6fC8Da46Edb7B6142E4F461b62D3","data":"0xc5ff38bd"},"0x18f5fb2"]}'

The log range may need narrowing on some nodes (use several requests of two million blocks). The simulation changes nothing on chain.

What this does not show

Not an audit, not investment advice. Back to the dashboard · Read it yourself.