# ParticleExchange.auctionBuyNft and ParticleExchange.withdrawEthWithInterest function calls can be DOS'ed

Malicious borrower contract reverts its receive() to block ETH payouts, DoSing auctionBuyNft and withdrawEthWithInterest so lender can never liquidate the defaulted lien.

- Payout: Contest reward
- Severity: high
- Program: Particle Protocol
- Credited: rbserver
- Disclosed: 2023-08-07
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-05-particle-findings/issues/31
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-particle%3AH-01
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** ParticleExchange.sol auctionBuyNft and withdrawEthWithInterest ETH transfers
**Root cause:** Both functions push ETH to lien.borrower via transfer() when payback>0 or credit>payableInterest; a borrower contract can revert its receive() on demand, reverting the whole call.
**Steps:**
1. Deploy lien.borrower as a contract whose receive() reverts when an owner-controlled boolean is true.
2. Borrow against a lien with this contract as borrower.
3. Lender starts auction; owner flips boolean so receive() reverts.
4. Any auctionBuyNft call with payback>0 reverts at `payable(lien.borrower).transfer(payback)`, blocking all bidders.
5. After auction, withdrawEthWithInterest also reverts at `payable(lien.borrower).transfer(lien.credit - payableInterest)`, so lender cannot settle.
**How found:** Code reading of the ETH push transfers to lien.borrower in auctionBuyNft and withdrawEthWithInterest; recognized that a contract borrower controls its receive() and can force reverts.
**Exploitation:** Borrower waits until default/auction, then toggles the revert flag; every bidder's auctionBuyNft and the lender's withdrawEthWithInterest revert, so the auction never concludes and the lender cannot claim NFT or ETH at zero cost to the borrower.
**Insight:** Any push-payment to a user-controlled address (borrower, bidder, counterparty) in a settlement/liquidation path is a griefing vector: a contract can revert receive() to freeze the counterparty's ability to close the position. Prefer pull-payment accounting (credit balances) for all outgoing transfers in auction/liquidation flows.
