# Wrong calculation of erc20Delta and ethDelta

Tally Swap.sol computes erc20Delta/ethDelta against a baseline that already includes the user's input, so ETH refunds are lost and same-token arb swaps lose nearly all input.

- Payout: Audit contest
- Severity: high
- Program: Tally
- Found by: WatchPug
- Disclosed: 2021-11-19
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-10-tally-findings/issues/34
- Library page: https://bugbountylibrary.com/r/c4%3A2021-10-tally%3AH-02
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** Swap.sol fillZrxQuote (Solidity swap contract)
**Root cause:** originalETHBalance/originalERC20Balance are snapshotted after msg.value and input tokens are already in the contract, so the delta subtracts a baseline that includes the input amount.
**Steps:**
1. Contract holds 1 ETH; user calls swap with 10 ETH to USDC.
2. originalETHBalance = 11 ETH (includes msg.value).
3. ZRX call spends ethAmount; 1 ETH refund returns to contract, new balance 2 ETH.
4. ethDelta = subOrZero(2, 11) = 0, so refund path fails / delta reported as 0.
5. For WBTC->WBTC arb of 1 WBTC to 1.1 WBTC, originalERC20Balance includes the 1 WBTC input, so erc20Delta = 0.1 instead of 1.1.
**How found:** Code reading of fillZrxQuote: noticed originalETHBalance is captured after msg.value is credited, and originalERC20Balance after input tokens are transferred in, making the delta baseline wrong; verified with concrete balance examples.
**Exploitation:** No attacker needed; a normal user swapping ETH to ERC20 cannot receive their ETH refund, and a user doing a same-token arb swap loses almost all of their input amount because the computed delta is far below actual received amount.
**Insight:** When auditing swap/fill functions, check whether the pre-balance snapshot is taken before or after the caller's input (msg.value or token transfer) lands in the contract; a baseline that includes input silently zeroes refund deltas and mis-reports received amounts for same-token swaps.
