Harden fund-invoice amount validation against precision loss
Description
The POST /api/invest/fund-invoice body validator in src/routes/invest.js checks amountStroops with const parsed = Number(amountStroops) and Number.isInteger(parsed). For stroop amounts (1 XLM = 10,000,000 stroops) a large value silently loses precision past Number.MAX_SAFE_INTEGER, and a string like "1e7" or "100.0" can slip through inconsistently. Meanwhile the downstream persistence layer in src/services/investorCommitment.js already validates the same field strictly as a positive-integer string via BigInt (validateAmountStroops). The route should match that strict, precision-safe contract before any Soroban work begins.
Requirements and context
- Repository scope: Liquifact/Liquifact-backend only.
- Replace the
Number(amountStroops) path in src/routes/invest.js with the same digits-only BigInt validation used by validateAmountStroops in src/services/investorCommitment.js (reject signs, decimals, scientific notation, leading zeros, and values over the documented MAX_STROOP_AMOUNT).
- Reuse one shared validator so the route and the service cannot diverge again.
- Preserve the existing
VALIDATION_ERROR response shape and the invoiceId/investorAddress regex checks.
- Never coerce the amount to a JS number anywhere on the funding path.
Suggested execution
- Fork the repo and create a branch
git checkout -b security/invest-02-bigint-amount-validation
- Implement changes
- Test and commit
Test and commit
- Run
npm test and npm run lint.
- Cover edge cases: value above
MAX_SAFE_INTEGER, "1e7", "100.0", leading zeros, zero/negative, valid large integer string.
- Include the full
npm test output and a short security-notes section in the PR description.
Example commit message
fix(invest): validate amountStroops with BigInt to prevent precision loss
Guidelines
- Minimum 95 percent test coverage for impacted modules.
- Clear, reviewer-focused documentation.
- Timeframe: 96 hours.
Community & contribution rewards
- 💬 Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
- ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.
Harden fund-invoice amount validation against precision loss
Description
The
POST /api/invest/fund-invoicebody validator insrc/routes/invest.jschecksamountStroopswithconst parsed = Number(amountStroops)andNumber.isInteger(parsed). For stroop amounts (1 XLM = 10,000,000 stroops) a large value silently loses precision pastNumber.MAX_SAFE_INTEGER, and a string like"1e7"or"100.0"can slip through inconsistently. Meanwhile the downstream persistence layer insrc/services/investorCommitment.jsalready validates the same field strictly as a positive-integer string viaBigInt(validateAmountStroops). The route should match that strict, precision-safe contract before any Soroban work begins.Requirements and context
Number(amountStroops)path insrc/routes/invest.jswith the same digits-onlyBigIntvalidation used byvalidateAmountStroopsinsrc/services/investorCommitment.js(reject signs, decimals, scientific notation, leading zeros, and values over the documentedMAX_STROOP_AMOUNT).VALIDATION_ERRORresponse shape and the invoiceId/investorAddress regex checks.Suggested execution
git checkout -b security/invest-02-bigint-amount-validationsrc/routes/invest.jsandsrc/services/investorCommitment.js(export the shared validator).tests/invest.fund.test.js.README.mdand the route@swaggerblock.Test and commit
npm testandnpm run lint.MAX_SAFE_INTEGER,"1e7","100.0", leading zeros, zero/negative, valid large integer string.npm testoutput and a short security-notes section in the PR description.Example commit message
fix(invest): validate amountStroops with BigInt to prevent precision lossGuidelines
Community & contribution rewards