access-controllisted
Install: claude install-skill iktok90-design/ai-smart-contract-auditor
# Access control detection
## When this applies
Any state-mutating function. In particular:
- Functions modifying balances, totalSupply, allowances, prices, fees
- `setOwner`, `transferOwnership`, `grantRole`, `setAdmin`, `setMinter`
- Upgrade pathways: `upgradeTo`, `_authorizeUpgrade`, proxy admins
- Pause/unpause, emergency-withdraw, sweep, recoverERC20
- Initializers (`initialize`, `__Init`, `_init`)
- Functions guarded only by `msg.sender == tx.origin` or address checks against a single static value
- Bridges, governors, vaults, anything with treasury
## Detection patterns
### Missing modifier (CRITICAL)
```solidity
function mint(address to, uint256 amount) external {
_mint(to, amount); // ← anyone can mint
}
```
### Wrong role check (HIGH)
```solidity
function setFee(uint256 fee) external {
require(msg.sender == owner || hasRole(USER, msg.sender)); // ← USER role can set fee
fee_ = fee;
}
```
### Initializer left public (CRITICAL)
```solidity
function initialize(address admin) public { // ← no initializer guard, anyone can re-init
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
```
**See also:** [[initialization]]
### tx.origin auth (HIGH)
```solidity
require(tx.origin == owner); // ← phishable via intermediate contract
```
### Public privileged getter masking setter
Sometimes a setter is internal but a public wrapper exists with weak checks. Search for "alternate paths" to the same state slot.
### Role admin self-grant (HIGH)
`DEFAULT_ADMIN_