Summary
The amount in POST /api/deals comes directly from the request body and is stored in Supabase without validation. It is later passed as-is to the Stellar SDK payment operation in lockFunds and releaseFunds:
// deals.js — no validation
const { buyerSecret, seller, amount, description } = req.body;
await supabase.from('deals').insert({ buyer, seller, amount, ... });
// escrow.js — amount used directly
StellarSdk.Operation.payment({
destination: escrowPublic,
asset: StellarSdk.Asset.native(),
amount: String(amount), // ← unvalidated user input
})
Issues:
- Negative or zero amounts:
amount: -100 will cause lockFunds to throw, but the deal record has already been inserted with a bad amount
- Precision overflow: Stellar supports at most 7 decimal places.
amount: "1.000000001" causes a Stellar SDK error after the deal is written to the DB
- String injection:
amount: "100 XLM" or amount: true bypasses the falsy check and reaches the SDK
Fix
Validate amount before inserting the deal:
const parsed = parseFloat(amount);
if (!Number.isFinite(parsed) || parsed <= 0)
return res.status(400).json({ error: 'amount must be a positive number' });
// Round to Stellar's 7 decimal places
const safeAmount = parsed.toFixed(7);
Affected files
src/routes/deals.js — POST /
src/services/escrow.js — lockFunds, releaseFunds, refund
Summary
The
amountinPOST /api/dealscomes directly from the request body and is stored in Supabase without validation. It is later passed as-is to the Stellar SDK payment operation inlockFundsandreleaseFunds:Issues:
amount: -100will causelockFundsto throw, but the deal record has already been inserted with a bad amountamount: "1.000000001"causes a Stellar SDK error after the deal is written to the DBamount: "100 XLM"oramount: truebypasses the falsy check and reaches the SDKFix
Validate
amountbefore inserting the deal:Affected files
src/routes/deals.js—POST /src/services/escrow.js—lockFunds,releaseFunds,refund