Three Checkboxes and $900 Million — JavaScript Bug Hunt

Modelled on Citibank's Revlon payment (August 2020): to send only an interest payment through the loan system, an operator had to tick three separate…

  • Language: JavaScript
  • Layer: Frontend
  • Difficulty: Medium
  • Concepts: Forms, Defaults
  • Modelled on: Citibank · Revlon 2020
  • Visible tests: no flags means interest only; a partial combination is refused; all three flags means a real payoff
  • Reward: 50 XP for a complete fix

Briefing

Modelled on Citibank's Revlon payment (August 2020): to send only an interest payment through the loan system, an operator had to tick three separate checkboxes. Ticking one left the other two unset, and the system wired the entire $894 million principal instead. Much of it was never recovered.

payment.js decides what to send. Its defaults are dangerously permissive.

Fix buildPayment so an incompletely configured interest-only payment is refused rather than silently escalated to the full principal.

Bug report

BUG-REVLON · Priority: Critical (funds) · Reported by: wire operations

buildPayment(loan, flags) must return:

  • { kind: "interest", amount: loan.interest } when flags.principal, flags.frontFund and flags.escrow are ALL false — the interest-only route
  • { kind: "principal", amount: loan.principal } when all three are true
  • { kind: "refused", amount: 0 } for any partial combination

Observed: a partial combination falls through to the principal branch and wires the whole loan.

Logs

[wire] kind=principal amount=894000000 flags={principal:false,frontFund:true,escrow:false}
[wire] operator intent recorded as: interest only

The code as shipped

src/payments/payment.js (editable)

// Decides which payment to send.
exports.buildPayment = function (loan, flags) {
  if (!flags.principal && !flags.frontFund && !flags.escrow) {
    return { kind: "interest", amount: loan.interest };
  }
  // Anything else is treated as a full principal payoff.
  return { kind: "principal", amount: loan.principal };
};

Read-only context: src/payments/RUNBOOK.js.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.