# Caller of Upkeep may skip step 11 to save gas

Upkeep caller can supply only enough gas for steps 1-10, letting step 11 revert via try/catch while still collecting the 5% incentive.

- Payout: Contest reward
- Severity: medium
- Program: Salty.IO
- Credited: handsomegiraffe
- Disclosed: 2024-04-19
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-01-salty-findings/issues/383
- Library page: https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-17
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic

**Target:** Upkeep.performUpkeep() on-chain function
**Root cause:** performUpkeep wraps each step in try/catch, so a step that runs out of gas reverts internally and is caught, letting the caller complete the call and claim the incentive without executing step 11.
**Steps:**
1. Call `performUpkeep()` with gas sized to cover only steps 1-10.
2. EIP-150 forwards 63/64 of remaining gas to `this.step11()`; it OOGs and reverts.
3. The catch block emits `UpkeepError("Step 11", error)` using the retained 1/64 gas.
4. Function returns normally; caller receives the 5% upkeep incentive while step 11 (SALT transfer from team vesting wallet) never runs.
**How found:** Observed that each upkeep step is individually try/catch-wrapped and reasoned about EIP-150's 63/64 gas forwarding: a step can be starved of gas yet the outer call still succeeds and pays the incentive.
**Exploitation:** Attacker calls performUpkeep with carefully limited gas, saving the cost of step 11 while still earning the incentive; step 11's SALT transfer from the team vesting wallet to the team is skipped each time.
**Insight:** When a function pays a reward for completing N try/catch-wrapped steps, check whether the caller can under-fund gas so later steps OOG-and-get-caught; the 1/64 retained gas is often enough to emit the error and return, so the reward is paid for partial work.
