# Adapters logic contracts can be destroyed

Unprotected initializer on AdapterBase logic contracts lets attacker set a malicious strategy whose harvest() selfdestructs, destroying the implementation and bricking all adapter instances.

- Payout: Contest reward
- Severity: medium
- Program: Popcorn
- Credited: eierina
- Disclosed: 2023-09-07
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-01-popcorn-findings/issues/700
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-popcorn%3AM-05
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:dos vuln:misconfiguration

**Target:** Upgradeable adapter logic contracts (BeefyAdapter, YearnAdapter) on AdapterBase
**Root cause:** AdapterBase.__AdapterBase_init is callable directly on the logic contract (no _disableInitializers in constructor), letting anyone set the strategy address; harvest() delegatecalls strategy, so a malicious strategy selfdestructs the implementation.
**Steps:**
1. Call `initialize(adapterInitData, ...)` directly on the BeefyAdapter/YearnAdapter logic contract with `_strategy` set to attacker contract containing `harvest()` or fallback that calls `selfdestruct`.
2. Call `harvest()` on the logic contract; it delegatecalls the malicious strategy, executing selfdestruct in the logic contract's context.
3. Logic contract code is removed; all proxies delegating to it now point to a code-less address and become inoperable.
**How found:** Reasoning about upgradeable contract semantics: direct calls to logic contracts are normally harmless except selfdestruct/delegatecall, then reading __AdapterBase_init (unprotected initializer) and harvest()'s delegatecall to strategy.
**Exploitation:** Attacker directly initializes the implementation contract with a malicious strategy, then triggers harvest() to selfdestruct the implementation, bricking every adapter instance that delegates to it (DoS on the protocol).
**Insight:** On upgradeable/proxy designs, check whether implementation contracts are left initializable; an unprotected initializer that sets a delegatecall target can be turned into selfdestruct of the implementation, bricking all proxies.
