# Tokens can be burned with no access control

Vault.utilize() lacks a zero-address check on keeper/controller, letting anyone burn available funds to address(0) when both are unset.

- Payout: Audit contest
- Severity: high
- Program: InsureDAO
- Found by: sirhashalot
- Disclosed: 2022-03-15
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-01-insure-findings/issues/158
- Library page: https://bugbountylibrary.com/r/c4%3A2022-01-insure%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Vault.sol smart contract (utilize function)
**Root cause:** keeper and controller default to address(0) and are never validated; utilize()'s only access control compares msg.sender to keeper, so when keeper==0 the check is bypassed and safeTransfer sends tokens to address(0).
**Steps:**
1. Deploy/observe Vault where setKeeper() was never called (keeper==address(0)) and controller left as address(0) per constructor comment.
2. Call `utilize(address token, uint256 amount)` from any address; access control `msg.sender == keeper` passes since keeper is zero.
3. Function executes `safeTransfer(token, address(0), amount)` burning available funds (balance - totalDebt).
**How found:** Code review of Vault.sol access control: noticed keeper/controller default to address(0), that setKeeper is optional, and that utilize()'s only guard is a msg.sender==keeper comparison, making the zero default a bypass.
**Exploitation:** Any external address calls utilize() on a Vault with unset keeper/controller, transferring available underlying tokens to address(0); users with no totalDebt lose their entire balance.
**Insight:** When access control is `msg.sender == someStateVar`, check whether that state var can remain at its default (address(0)) — uninitialized owner/keeper/controller roles turn equality checks into open doors.
