sell_to_customer accepts payment from the CustomerEngine even when inventory cannot satisfy the order. Rather than reverting or refunding msg.value, the function simply lowers reputation and exits successfully. The transferred ETH stays in the contract, but the ledger is never updated.
Likelihood: Stockouts are inevitable once demand exceeds production; no attacker coordination is required.
Customers permanently lose their payment despite receiving no goods.
The unaccounted ETH is trapped: company_balance never increases, so withdrawals and net-worth metrics exclude the funds.
Attackers can grief buyers by emptying inventory and letting them burn ETH while reputation merely ticks down.
Set inventory = 0, but leave CustomerEngine active.
Call trigger_demand so it forwards total_cost to sell_to_customer.
The call succeeds; the buyer loses ETH, the company has no inventory change, and company_balance is unchanged.
Shareholders cannot withdraw the stuck ETH because the ledger thinks no cash is available.
Simplified pytest outline:
Revert the sale when inventory is insufficient so CustomerEngine refunds the caller automatically.
Alternatively, explicitly refund msg.value inside sell_to_customer before returning.
If business logic dictates keeping the payment, add it to company_balance so accounting remains accurate.
Patch example (revert approach):
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.