# Any public vault without a delegate can be drained

Vaults created without a delegate default delegate to address(0), which ecrecover returns for invalid signatures, letting anyone forge lien approval and drain the vault with a worthless NFT.

- Payout: Contest reward
- Severity: high
- Program: Astaria
- Credited: obront
- Disclosed: 2022-11-07
- Write-up quality: 8/10
- Original: https://github.com/sherlock-audit/2022-10-astaria-judging/issues/69
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-10-astaria%3AH-30
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:auth-bypass vuln:signature-replay

**Target:** AstariaRouter / VaultImplementation public vault lien commitment validation
**Root cause:** init() skips assigning delegate when address(0) is passed, leaving delegate=address(0); ecrecover returns address(0) for invalid signatures (v not 27/28), so signature checks comparing recovered to owner()/delegate pass when strategist is set to address(0).
**Steps:**
1. Create/identify a public vault with no delegate set (delegate == address(0)).
2. Craft lienRequest params with strategy.strategist = address(0) and a worthless NFT as collateral.
3. Set v to an integer other than 27/28 so ecrecover returns address(0).
4. Call commitToLien / validation path; `recovered == strategist` and `recovered == delegate` both pass.
5. Borrow the vault's full funds against the worthless NFT, draining the vault.
**How found:** Code review of init() delegate assignment and the ecrecover-based signature validation; noticed delegate defaults to address(0) and that ecrecover returns address(0) on invalid signatures, then chained the two.
**Exploitation:** Attacker submits a forged lien commitment with strategist=address(0) and invalid v value; ecrecover yields address(0) matching delegate, so the vault accepts the lien and lends out its entire balance against a worthless NFT.
**Insight:** Whenever a signature check compares ecrecover output to a stored role/owner, check whether that role can be address(0) (unset default) and whether invalid v values make ecrecover return address(0) — the two zeros collide and bypass auth.
