Reviewed commit: be11bdcb5 (origin/main), from the 2026-07-28 full-repo review.
Severity: HIGH. A USD-named spend cap is enforced against a number that may not be dollars.
Where
pkg/exchange/exchange.go:249-254 (captures CurrencyCode, never used)
pkg/exchange/exchange.go:312-321 (checkInitialQuote), :326-339 (checkReQuote)
pkg/exchange/auto.go:318-325 and :505-535 (compare against MaxPaymentPerExchangeUSD / MaxPaymentDailyUSD)
internal/config/store_postgres.go:2642 (GetRIExchangeDailySpend)
What
getQuoteWithAPI reads out.CurrencyCode into the summary and then every guardrail compares PaymentDue (a bare decimal parsed from out.PaymentDue) against a USD-named cap, with no assertion that the quote is USD-denominated. The ledger likewise SUMs payment_due with no currency column.
Failure scenario
An account whose EC2 exchange quotes come back in a non-USD currency returns PaymentDue="900", CurrencyCode="JPY".
checkInitialQuote compares 900 against MaxPaymentDueUSD = 1000, passes, and AcceptReservedInstancesExchangeQuote fires. The operator's stated $1000/day ceiling is enforced against a number that is not dollars, and the error runs in either direction: silently blocking a legal exchange, or silently authorizing one an order of magnitude over the cap.
Fix direction
Fail closed in checkInitialQuote / checkReQuote when q.CurrencyCode != "USD", and record the currency on the ledger row, rather than comparing across denominations.
Related
Exchange-side sibling of the MaxPurchaseAmount currency rule established in PR LeanerCloud/cloud-commitments-cli#1515. LeanerCloud/cloud-commitments-cli#1087 covers the AWS Savings Plans purchase path being USD-only, a different call site.
Findings from the 2026-09-02 codebase audit
Added by an automated audit of 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd (tip of origin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report: docs/audits/codebase-audit-2026-09-02.md.
A09-031 (medium)
Coverage note for the fix, from reading all six test files in pkg/exchange rather than grepping. Nothing in the package drives checkInitialQuote / checkReQuote with a CurrencyCode other than USD, so the cap comparison this issue is about has no test that could fail. Two sibling guards on the same irreversible path are equally unverified: no case sets PaymentDueRaw to the empty string on a quote destined for those checks, and assertAccount / ExpectedAccount appear in no test file at all. exchange_test.go holds only TestParseDecimalRat, TestPaymentDueUSDStr_InJSON and TestSpendCapComparison, the last exercising big.Rat.Cmp directly rather than the guard; fail_loud_test.go's seqQuoteOut always sets a non-empty PaymentDue (:47-52) and never sets currency or expected account. Three table cases -- an empty PaymentDue, a EUR quote, and an account mismatch, each asserting AcceptReservedInstancesExchangeQuote was never called -- would give this fix teeth. (The EUR/empty OfferingOption.CurrencyCode cases in reshape_crossfamily_test.go exercise passesDollarUnitsCheck, not the cap.) (audit finding A09-031)
Reviewed commit:
be11bdcb5(origin/main), from the 2026-07-28 full-repo review.Severity: HIGH. A USD-named spend cap is enforced against a number that may not be dollars.
Where
pkg/exchange/exchange.go:249-254(capturesCurrencyCode, never used)pkg/exchange/exchange.go:312-321(checkInitialQuote),:326-339(checkReQuote)pkg/exchange/auto.go:318-325and:505-535(compare againstMaxPaymentPerExchangeUSD/MaxPaymentDailyUSD)internal/config/store_postgres.go:2642(GetRIExchangeDailySpend)What
getQuoteWithAPIreadsout.CurrencyCodeinto the summary and then every guardrail comparesPaymentDue(a bare decimal parsed fromout.PaymentDue) against a USD-named cap, with no assertion that the quote is USD-denominated. The ledger likewiseSUMspayment_duewith no currency column.Failure scenario
An account whose EC2 exchange quotes come back in a non-USD currency returns
PaymentDue="900",CurrencyCode="JPY".checkInitialQuotecompares 900 againstMaxPaymentDueUSD = 1000, passes, andAcceptReservedInstancesExchangeQuotefires. The operator's stated $1000/day ceiling is enforced against a number that is not dollars, and the error runs in either direction: silently blocking a legal exchange, or silently authorizing one an order of magnitude over the cap.Fix direction
Fail closed in
checkInitialQuote/checkReQuotewhenq.CurrencyCode != "USD", and record the currency on the ledger row, rather than comparing across denominations.Related
Exchange-side sibling of the
MaxPurchaseAmountcurrency rule established in PR LeanerCloud/cloud-commitments-cli#1515. LeanerCloud/cloud-commitments-cli#1087 covers the AWS Savings Plans purchase path being USD-only, a different call site.Findings from the 2026-09-02 codebase audit
Added by an automated audit of
3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd(tip oforigin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report:docs/audits/codebase-audit-2026-09-02.md.A09-031 (medium)
Coverage note for the fix, from reading all six test files in
pkg/exchangerather than grepping. Nothing in the package drivescheckInitialQuote/checkReQuotewith aCurrencyCodeother than USD, so the cap comparison this issue is about has no test that could fail. Two sibling guards on the same irreversible path are equally unverified: no case setsPaymentDueRawto the empty string on a quote destined for those checks, andassertAccount/ExpectedAccountappear in no test file at all.exchange_test.goholds onlyTestParseDecimalRat,TestPaymentDueUSDStr_InJSONandTestSpendCapComparison, the last exercisingbig.Rat.Cmpdirectly rather than the guard;fail_loud_test.go'sseqQuoteOutalways sets a non-emptyPaymentDue(:47-52) and never sets currency or expected account. Three table cases -- an emptyPaymentDue, a EUR quote, and an account mismatch, each assertingAcceptReservedInstancesExchangeQuotewas never called -- would give this fix teeth. (The EUR/emptyOfferingOption.CurrencyCodecases in reshape_crossfamily_test.go exercisepassesDollarUnitsCheck, not the cap.) (audit finding A09-031)