# scaledQuoteTokenAmount isn't updated to be collateral sell value in the quote token constraint case of _calculateTakeFlowsAndBondChange

In Ajna's Auctions.take, the quote-token-constraint branch fails to update scaledQuoteTokenAmount to collateral*price, underpaying kicker bond rewards by factor (1-BFP).

- Payout: Contest reward
- Severity: high
- Program: Ajna
- Credited: hyh
- Disclosed: 2022-12-21
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-01-ajna-judging/issues/139
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AH-4
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** Auctions.sol _calculateTakeFlowsAndBondChange (liquidation take flow)
**Root cause:** In the quote-token-constraint branch, scaledQuoteTokenAmount is used as the constraint but never recomputed to collateralAmount*auctionPrice, so the subsequent bondChange uses C*p*(1-BFP) instead of C*p.
**Steps:**
1. Call take() where unscaledDeposit is small enough that scaledQuoteTokenAmount <= borrowerDebt and <= borrowerCollateralValue.
2. Branch 1 executes: collateralAmount = roundToScale(scaledQuoteTokenAmount/borrowerPrice), but scaledQuoteTokenAmount stays as the deposit value.
3. bondChange = wmul(scaledQuoteTokenAmount, bpf) uses the stale value, yielding reward proportional to (1-BFP)*BFP instead of BFP.
4. Compare kicker reward against expected C*p*bpf to observe shortfall.
**How found:** Code reading of _calculateTakeFlowsAndBondChange: noticed scaledQuoteTokenAmount has a dual role (constraint then C*p base) and that only branches 2 and 3 reassign it, while branch 1 leaves the constraint value in place.
**Exploitation:** Any lender calling take() with a quote-token-constrained deposit triggers the branch; kicker receives a reduced bond reward proportional to (1-BFP)*BFP rather than BFP, systematically underpaying rewards on every such take.
**Insight:** When a variable serves as both a constraint and a derived value in a multi-branch function, check every branch reassigns it after the constraint check; the branch that skips the reassignment silently propagates the wrong base into downstream reward math.
