# Incorrect implementation of `BPF` leads to kicker losing rewards in a `take` action

Ajna's _bpf returns 0 instead of bondFactor when TP>=NP and auctionPrice==NP, zeroing kicker rewards and inflating borrower penalty.

- Payout: Contest reward
- Severity: medium
- Program: Ajna
- Credited: santipu_
- Disclosed: 2023-09-26
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-09-ajna-judging/issues/18
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-09-ajna%3AM-2
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:liquidation vuln:reward-distribution

**Target:** PoolHelper._bpf bond payment factor in take() liquidation
**Root cause:** In the TP>=NP branch, sign is only set when val<0 or val!=0; when neutralPrice==auctionPrice (val==0) sign stays 0, so BPF=0 instead of bondFactor per spec.
**Steps:**
1. Read _bpf in PoolHelper.sol: TP>=NP branch sets sign=-1e18 if val<0, 1e18 if val!=0, leaves 0 when val==0.
2. Note referencePrice = max(NP, HTP); when NP>HTP, referencePrice==NP.
3. Observe _auctionPrice returns referencePrice/256 at 64800s (18h) elapsed, i.e. auctionPrice==NP at that point.
4. Call take() at the block where elapsed time hits 18h so auctionPrice==NP and TP>=NP.
5. BPF computes to 0 rather than bondFactor, kicker gets no reward and TPF rises.
**How found:** Compared _bpf implementation against whitepaper section 7.3.3 step function; noticed missing else branch for val==0. Later realized referencePrice=max(NP,HTP) and _auctionPrice returns referencePrice/256 at 18h, making NP==auctionPrice reachable ~1/12 of auctions.
**Exploitation:** No profit vector; a taker timing take() near the 18h mark when auctionPrice==NP causes kicker to forfeit bond reward and borrower to be penalized more (TPF inflated), value redirected to reserves.
**Insight:** When auditing step-function/sign logic, check every branch of the piecewise spec including the equality boundary; then check whether 'unlikely' equality is actually forced by a deterministic schedule (e.g. auction price hitting referencePrice/256 at a fixed elapsed time).
