# Missing access modifier for `RFPSimpleStrategy.setPoolActive()` may lead to multiple issues

RFPSimpleStrategy.setPoolActive() lacks onlyPoolManager, letting anyone toggle pool state and re-register with a higher proposalBid to overpay themselves.

- Payout: Contest reward
- Severity: high
- Program: Gitcoin
- Credited: 0x180db
- Disclosed: 2023-09-01
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-09-Gitcoin-judging/issues/458
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-09-Gitcoin%3AH-4
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic

**Target:** RFPSimpleStrategy.sol (Allo v2 strategy contract)
**Root cause:** setPoolActive() is externally callable without the onlyPoolManager(msg.sender) modifier, so any address can flip the pool between active and inactive states that gate _registerRecipient, _allocate, _distribute and withdraw.
**Steps:**
1. Alice calls `_registerRecipient` with `proposalBid = 15e18` and is accepted by the pool manager.
2. Before `_distribute`, Alice calls `setPoolActive()` to reactivate the pool (frontrun or pre-empt).
3. Alice calls `_registerRecipient` again with a higher `proposalBid = 60e18`.
4. Alice calls `setPoolActive()` to deactivate the pool.
5. `_distribute` pays `(60e18 * milestone.amountPercentage) / 1e18` instead of the accepted 15e18 bid.
**How found:** Code reading: the comment on line 217 states msg.sender must be a pool manager, but the onlyPoolManager modifier is absent; tracing which functions are gated by onlyActivePool/onlyInactivePool revealed the re-registration path.
**Exploitation:** Attacker registers as recipient at a low bid, gets accepted, then uses the unguarded setPoolActive to reopen registration and overwrite their proposalBid upward before distribution, extracting more strategy funds than the accepted bid.
**Escalation:** Repeatable across each milestone distribution, draining strategy funds beyond the accepted amount.
**Insight:** When a comment asserts an authorization requirement, verify the modifier is actually applied; then trace every function gated by the state that unguarded setter controls to find a value-changing path (here re-registering a bid) rather than just reporting the missing modifier.
