# InfinityExchange computes gas refunds in a way where the first order's buyer pays less than the later ones

InfinityExchange computed per-order gas refunds inside the batch loop, so later buyers in a batch were overcharged relative to earlier ones.

- Payout: Contest reward
- Severity: medium
- Program: Infinity NFT Marketplace
- Credited: Ruhum
- Disclosed: 2022-08-16
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-06-infinity-findings/issues/82
- Library page: https://bugbountylibrary.com/r/c4%3A2022-06-infinity%3AM-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** InfinityExchange.sol batch order fulfillment gas refund logic
**Root cause:** startGasPerOrder is recomputed inside the for-loop using the current gasleft(), so the baseline drifts downward across iterations, inflating the computed gasCost for later orders.
**Steps:**
1. Call batch fulfillment with N orders (e.g. 10) so the loop at InfinityExchange.sol#L202 runs.
2. Observe startGasPerOrder = startGas + ((startGas + 20000 - startGas) / ordersLength) recomputed each iteration with a decreasing startGas.
3. For order 2 with startGas=900000, gasPerOrder=100000, ordersLength=10: startGasPerOrder=912000; gasCost=(912000-800000+50000)*tx.gasprice=162000.
4. For order 9 with startGas=200000: startGasPerOrder=282000; gasCost=(282000-100000+50000)*tx.gasprice=232000.
5. Later buyers pay more gas refund than earlier buyers for equivalent work.
**How found:** Code reading of the batch loop noticed startGasPerOrder initialized inside the for-loop rather than outside, then arithmetic example confirmed the drift.
**Exploitation:** Any user submitting a batch of orders triggers the miscalculation; later orders in the batch are charged a larger gas refund, leaking value from those buyers during normal usage.
**Insight:** When auditing gas-refund or fee accounting in batch loops, check whether the per-item baseline is captured before the loop; recomputing it from live gasleft() inside the loop systematically skews later items.
