Skip to content

Integer Overflow in Cumulative Resource Consumption Aggregation #19

Description

@elizabetheonoja-art

Problem Statement / Feature Objective
The cumulative resource consumption aggregation function sums raw meter readings across multiple devices and time windows using i128 arithmetic without explicit overflow checks via checked_add(). While Soroban's i128 does not panic on overflow in release mode (it wraps in Rust's default behavior, though Soroban may panic), the sum of a large number of high-volume readings over a long period could theoretically exceed i128::MAX (~1.7e38). Given that each reading can be up to 1e7 units (with 7-decimal fixed-point) and there can be millions of readings, the cumulative sum may saturate or wrap, producing incorrect billing amounts. The objective is to replace all raw arithmetic operations in the aggregation path with checked_add() and panic with a meaningful error on overflow.

Technical Invariants & Bounds
Maximum single reading value: MAX_READING_VALUE = 1_000_000 * 1e7 (1M tokens) = 1e13 i128. Maximum number of readings per device: limited by storage, but could be up to 1e6 readings. Worst-case sum = 1e6 * 1e13 = 1e19, well within i128 range. However, cross-device aggregation (summing across 1e5 devices) yields 1e24, still safe. The real risk is in the tariff rate multiplier: rate = up to 1e6 * 1e7 (1M rate), and volume = 1e19. product = rate * volume = 1e6 * 1e7 * 1e19 = 1e32, still safe. The invariant: all arithmetic operations must use checked_add(), checked_sub(), checked_mul(), checked_div() and panic with ArithmeticOverflow or ArithmeticUnderflow error. The only exception is division by known-non-zero constants (e.g., / 10000 for basis points conversion) which is safe.

Codebase Navigation Guide
Aggregation logic: contracts/meter-aggregator/src/aggregation.rs — aggregate_volume() at line 45 and sum_readings() at line 78. Tariff rate multiplication: contracts/settlement/src/rate_application.rs — apply_rate() at line 60. Fee calculation: contracts/settlement/src/fees.rs — compute_fee() at line 34. Cumulative storage update: contracts/resource-token/src/balance.rs — update_cumulative_balance() at line 25. These represent ~20 arithmetic operations across the codebase that need auditing.

Implementation Blueprint
Step 1: Search for all occurrences of +, -, , / operators on i128 values across all contract source files: grep -r "i128" --include=".rs" contracts/ | grep -E "[+-*/]" | grep -v "checked_|//|test". Create a list of ~20-30 operations. Step 2: For each operation, determine if overflow is theoretically possible (based on input bounds) or not. For operations where overflow is impossible (e.g., dividing by a constant), add a comment explaining why. Step 3: For all others, replace with checked_add()/.expect("overflow"), checked_sub()/.expect("underflow"), etc. Step 4: Create a custom error type ArithmeticError with variants Overflow, Underflow, DivisionByZero in contracts/common/src/errors.rs. Step 5: Add a property-based test (looping over max-range values) that verifies no overflow occurs during the maximum possible aggregation scenario. Step 6: Run cargo test to ensure no regressions.

Metadata

Metadata

Assignees

Labels

Complexity: HardcoreIssues requiring deep systems-level engineering rigorGrantFox OSSIssue tracked in GrantFox OSSLayer: Core-EngineCore contract engine layerMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignType: Core-ArchitectureCore architecture design issues

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions