# The Constructor Caveat leads to bricking of Configurator contract.

Configurator logic contract sets governance and curvePool in its constructor, which never runs behind a proxy, leaving them zero and bricking governance-dependent functions.

- Payout: Contest reward
- Severity: high
- Program: Lybra Finance
- Credited: cthulhu\_cult
- Disclosed: 2023-08-21
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-06-lybra-findings/issues/673
- Library page: https://bugbountylibrary.com/r/c4%3A2023-06-lybra%3AH-04
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:misconfiguration

**Target:** LybraConfigurator upgradeable logic contract behind LybraProxy
**Root cause:** Governance timelock and curvePool addresses are assigned in the constructor of the logic contract; constructor code is not part of runtime bytecode and never executes in the proxy's storage context, so proxy state keeps zero addresses.
**Steps:**
1. Deploy GovernanceTimelock, mockCurve, and Configurator logic with `new Configurator(address(govTimeLock), address(curve))`.
2. Deploy LybraProxy pointing at the Configurator logic with empty init data.
3. Cast proxy to Configurator; read governance/curvePool state — both are address(0).
4. Call `configurator.initToken(address(eusd), address(peUsdMainnet))` — reverts because governance is zero.
**How found:** Manual code review recognizing the Solidity proxy pattern: constructor and inline global-variable initialization are excluded from runtime bytecode, so any state set there is absent in proxy storage; confirmed with a Foundry PoC.
**Insight:** For any upgradeable contract, grep the logic contract for state assignments in the constructor or at declaration; those values silently become zero/default in proxy storage and can brick access-controlled functions.
