# Gauge set can be front run if bribe and gauge constructors aren't run atomically

Bribe.setGauge is unauthenticated and callable once; front-running it before the Gauge constructor binds a bogus gauge, bricking the Bribe contract.

- Payout: Contest reward
- Severity: medium
- Program: Velodrome Finance
- Credited: hyh
- Disclosed: 2022-08-08
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-05-velodrome-findings/issues/54
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-velodrome%3AM-01
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Bribe/Gauge smart contracts (Solidity)
**Root cause:** Bribe.setGauge is externally callable by anyone and only settable once, while the legitimate call happens inside the Gauge constructor; if Bribe and Gauge deployments aren't atomic, an attacker can occupy the slot first.
**Steps:**
1. Deploy Bribe contract (gauge == address(0)).
2. Before Gauge constructor runs, attacker calls `Bribe.setGauge(attackerAddress)` — passes `require(gauge == address(0))`.
3. Legitimate Gauge constructor calls `IBribe(bribe).setGauge(address(this))`, which reverts since gauge is already set.
4. Bribe is now bound to the wrong gauge and unusable; requires redeployment.
**How found:** Code review of Bribe.setGauge's lack of access control combined with its single-shot semantics and its invocation inside the Gauge constructor; noted the deployment ordering dependency.
**Exploitation:** Attacker monitors deployment and front-runs the non-atomic Bribe->Gauge deployment sequence with a direct setGauge call, permanently binding the Bribe to an arbitrary address and forcing redeployment.
**Insight:** When a setter is one-shot and called from another contract's constructor, check whether the deployment sequence is atomic — any gap lets an attacker claim the slot first.
