|
| 1 | +# Challenge 28: Verify float to decimal conversion module |
| 2 | + |
| 3 | +- **Status:** *Open* |
| 4 | +- **Solution:** *Option field to point to the PR that solved this challenge.* |
| 5 | +- **Tracking Issue:** *Link to issue* |
| 6 | +- **Start date:** *2026/01/01* |
| 7 | +- **End date:** *2026/08/31* |
| 8 | +- **Reward:** *5,000 USD* |
| 9 | + |
| 10 | +------------------- |
| 11 | + |
| 12 | + |
| 13 | +## Goal |
| 14 | + |
| 15 | +The goal of this challenge is to verify the [flt2dec](https://doc.rust-lang.org/src/core/num/flt2dec/mod.rs.html) module, which provides functions for converting floating point numbers to decimals. To do this, it implements both the Dragon and Grisu families of algorithms. |
| 16 | + |
| 17 | +## Motivation |
| 18 | + |
| 19 | +Given that converting floats to decimals correctly is a relatively costly operation, the standard library’s flt2dec module employs unsafe code to enable performance-enhancing operations that are otherwise not allowed in safe Rust (e.g., lifetime laundering to get around borrow-checker restrictions). Functions from this module are primarily invoked whenever attempting to represent floats in a human-readable format, making this a potentially highly-used module. |
| 20 | + |
| 21 | +## Description |
| 22 | + |
| 23 | +All of the functions targeted in this challenge are safe functions whose bodies contain unsafe code. This challenge is thus centered around proving well-encapsulation, which here mainly means showing that calls to variants of assume_init() are only performed on fully-initialized structures, and that the lifetime laundering does not cause undefined behaviour. |
| 24 | + |
| 25 | +### Success Criteria |
| 26 | + |
| 27 | +The following functions contain unsafe code in their bodies but are not themselves marked unsafe. All of these should be proven unconditionally safe, or safety contracts should be added: |
| 28 | + |
| 29 | +| Function | Defined in | |
| 30 | +|---------|---------| |
| 31 | +| `digits_to_dec_str` | `mod.rs` | |
| 32 | +| `digits_to_exp_str` | `mod.rs` | |
| 33 | +| `to_shortest_str` | `mod.rs` | |
| 34 | +| `to_shortest_exp_str` | `mod.rs` | |
| 35 | +| `to_exact_exp_str` | `mod.rs` | |
| 36 | +| `to_exact_fixed_str` | `mod.rs` | |
| 37 | +| `format_shortest_opt` | `strategy/grisu.rs` | |
| 38 | +| `format_shortest` | `strategy/grisu.rs` | |
| 39 | +| `format_exact_opt` | `strategy/grisu.rs` | |
| 40 | +| `format_exact` | `strategy/grisu.rs` | |
| 41 | +| `format_shortest` | `strategy/dragon.rs` | |
| 42 | +| `format_exact` | `strategy/dragon.rs` | |
| 43 | + |
| 44 | +For functions taking inputs of generic type 'T', the proofs can be limited to primitive types only. |
| 45 | + |
| 46 | +*List of UBs* |
| 47 | + |
| 48 | +In addition to any properties called out as SAFETY comments in the source code, all proofs must automatically ensure the absence of the following [undefined behaviors](https://github.com/rust-lang/reference/blob/142b2ed77d33f37a9973772bd95e6144ed9dce43/src/behavior-considered-undefined.md): |
| 49 | + |
| 50 | +* Accessing (loading from or storing to) a place that is dangling or based on a misaligned pointer. |
| 51 | +* Invoking undefined behavior via compiler intrinsics. |
| 52 | +* Mutating immutable bytes. |
| 53 | +* Producing an invalid value. |
0 commit comments