# broken logic in configureGmxState() of PirexGmx contract because it doesn't properly call safeApprove() for stakedGmx address

configureGmxState() approves new stakedGmx with safeApprove but never zeroes the old allowance, so re-calls revert and stale approvals persist.

- Payout: Contest reward
- Severity: medium
- Program: Redacted Cartel
- Credited: unforgiven
- Disclosed: 2023-01-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-11-redactedcartel-findings/issues/214
- Library page: https://bugbountylibrary.com/r/c4%3A2022-11-redactedcartel%3AM-09
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:incomplete-fix technique:source-review vuln:access-control vuln:business-logic

**Target:** PirexGmx.sol configureGmxState()/setContract() GMX token approvals
**Root cause:** configureGmxState() calls gmx.safeApprove(address(stakedGmx), max) without first resetting the previous stakedGmx allowance to zero, unlike setContract(). OZ safeApprove reverts when current and new allowance are both non-zero.
**Steps:**
1. Owner calls `configureGmxState()` once; stakedGmx gets max GMX allowance.
2. A different GMX contract address changes but stakedGmx stays the same; owner re-calls `configureGmxState()`.
3. `gmx.safeApprove(address(stakedGmx), type(uint256).max)` reverts because allowance is already non-zero.
4. Alternatively stakedGmx changes twice; old address retains max allowance and cannot be re-approved via setContract() either.
**How found:** Code-reading comparison of the approval logic in setContract() (which zeroes old allowance) versus configureGmxState() (which does not), noting OZ safeApprove's non-zero-to-non-zero revert behavior.
**Exploitation:** Not directly weaponized; requires owner misuse or a compromised/upgraded-away stakedGmx contract retaining max GMX allowance to later drain PirexGmx's GMX balance.
**Escalation:** Stale max approval on an abandoned stakedGmx address could let a compromised contract pull all GMX held by PirexGmx.
**Insight:** When a contract has multiple setters for the same address variable, diff their approval-reset logic; OZ safeApprove reverts on non-zero-to-non-zero, so any setter that skips the zeroing step becomes non-idempotent and leaves stale allowances.
