# Harvest Finance Uninitialized Proxies Bugfix Review— $200k Bounty

Uninitialized Harvest Finance proxy implementations let anyone become owner and point the hard-worker to a selfdestruct contract, destroying the implementation and bricking proxies holding $6.4M.

- Payout: $200,000
- Severity: critical
- Program: Harvest Finance
- Credited: Dedaub
- Disclosed: 2021-11-12
- Write-up quality: 8/10
- Original: https://immunefi.com/blog/bug-fix-reviews/harvest-finance-uninitialized-proxies-bugfix-review-200k-bounty/
- Library page: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-harvest-finance-uninitialized-proxies-bugfix-review-200k-bounty
- Tags: domain:web3 impact:dos impact:funds-loss kind:bounty platform:blog platform:immunefi sev:critical tech:evm tech:solidity technique:recon technique:reverse-engineering technique:source-review vuln:access-control vuln:misconfiguration

**Target:** Uniswap V3 vault upgradeable proxy implementation contracts (unverified bytecode)
**Root cause:** Implementation contracts were left uninitialized, so any caller could call initialize() and set the hard-worker address; the proxy's upgrade() consults shouldUpgrade() on the implementation, and doHardWork() delegatecalls the attacker-controlled hard-worker, so SELFDESTRUCT executes in the implementation's context.
**Steps:**
1. Identify uninitialized implementation contracts behind Harvest vault proxies (unverified bytecode).
2. Call `initialize()` on the implementation to become owner.
3. Deploy malicious contract whose function executes `selfdestruct`.
4. Set the hard-worker storage field to the malicious contract.
5. Call `doHardWork()` on the implementation; DELEGATECALL runs SELFDESTRUCT in implementation context.
6. Implementation is destroyed; proxy forwards calls to empty address and can no longer upgrade.
**How found:** Dedaub's automated analysis asked how to generalize the UUPS uninitialized-implementation bug to other code. It statically detected contracts that, if uninitialized, let an untrusted caller DELEGATECALL an address of their choosing, checked 250+ initializer signatures, dynamically confirmed the initializer was never called, and required another contract to have DELEGATECALLed it. This flagged three unverified Harvest implementations.
**Exploitation:** Attacker needs only the uninitialized implementation address. They initialize it, register a selfdestructing hard-worker, and trigger doHardWork(); the delegatecall destroys the implementation, permanently bricking the proxy and stranding the $6.4M in Uniswap V3 positions (griefing/DoS, not direct theft).
**Escalation:** Generalized from the OpenZeppelin UUPS uninitialized-proxy bug to a different proxy pattern where upgrade logic consults the implementation via shouldUpgrade().
**Insight:** Any proxy whose upgrade path calls into the implementation (e.g. shouldUpgrade()) inherits UUPS-style selfdestruct risk: hunt unverified implementation bytecode for uninitialized initializers plus a delegatecall to an attacker-settable address, even when the proxy pattern differs from OpenZeppelin.
