FoundrySolidityLayer 2
7.25 ETH
Submission Details
Impact: low
Likelihood: high

`initialize` Does Not Emit Configuration Parameters

Author Revealed upon completion

NOTE

THIS AFFECTS BOTH ConfidencePool.sol, ConfidencePoolFactory.sol

Root + Impact

Description

Both the pool and factory initialize functions set critical configuration parameters without emitting corresponding initialization events. The pool's initialize sets 7 parameters (agreement, stakeToken, safeHarborRegistry, outcomeModerator, expiry, minStake, recoveryAddress) silently — only ScopeUpdated (from _replaceScope) and OwnershipTransferred (from _transferOwnership) are emitted. No single event bundles the full configuration, forcing off-chain indexers to query each parameter individually or infer them from disparate events.

// ConfidencePool.sol — initialize() lines 204-218
@> agreement = agreement_; // no event
@> stakeToken = IERC20(stakeToken_); // no event
@> expiry = uint32(expiry_); // no event
@> minStake = minStake_; // no event
// ... only ScopeUpdated and OwnershipTransferred are emitted

Risk

Likelihood: N/A — one-time initialization per pool. The gap affects all pools equally.

Impact: Low — off-chain friction for indexers and dashboards. No on-chain impact.

Proof of Concept

File: L11-Initialize-NoEvent.poc.t.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {ConfidencePool} from "src/ConfidencePool.sol";
import {BaseConfidencePoolTest} from "test/helpers/BaseConfidencePoolTest.sol";
/// @notice PoC for L-11: initialize doesn't emit configuration parameters
contract L11_Initialize_NoEvent_POC is BaseConfidencePoolTest {
function testPOC_L11_initialize_setsParamsWithoutDedicatedEvent() external {
ConfidencePool freshPool = _deployPool();
// All 7 config values are set but no PoolInitialized event bundles them
assertEq(freshPool.minStake(), ONE);
assertGt(freshPool.expiry(), block.timestamp);
assertEq(freshPool.recoveryAddress(), recovery);
// Off-chain indexers must query each parameter individually.
// No single initialization event provides all config in one log.
}
}

Run: forge test --match-path 'L11-Initialize-NoEvent.poc.t.sol' -vv

Recommended Mitigation

Add a PoolInitialized event emitted at the end of initialize:

+ emit PoolInitialized(agreement_, stakeToken_, safeHarborRegistry_,
+ outcomeModerator_, expiry_, minStake_, recoveryAddress_, owner_);

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!