ABIProbe is a fuzzer for testing the consistency of encoding and decoding of ABI between Rust SDK, Sway and Typescript SDK. Furtheremore, due to the nature of the fuzzer it can also discover sway compiler bugs as it generates sway code that is then compiled and executed to test the encoding and decoding of the ABI.
The implementation was tested with the following:
- cargo: 1.76.0
- node: v20.14.0
- npm: v10.7.0
- fuelup: 0.25.1
- forc: 0.60.0
- fuel-core: 0.26.0
docker build -t abiprobe-docker .
docker run -it --rm -v $(pwd)/test-output:/usr/src/abiprobe/test-output abiprobe-docker
By default config.toml
is used as the config file. This can be modified by using the command line argument --config
followed by the path to the config file to be used.
The config file allows to specify the following parameters:
seed // Seed for the random number generator
rounds // Number of tests to run
samples // Number of samples to generate per test
max_depth // Maximum depth of the generated data structures
output_folder // Folder where the output will be stored
string_min_len // Minimum length of generated strings
string_max_len // Maximum length of generated strings
tuple_min_len // Minimum length of generated tuples
tuple_max_len // Maximum length of generated tuples
array_min_len // Minimum length of generated arrays
array_max_len // Maximum length of generated arrays
vector_min_len // Minimum length of generated vectors
vector_max_len // Maximum length of generated vectors
struct_min_fields // Minimum number of fields in generated structs
struct_max_fields // Maximum number of fields in generated structs
enum_min_variants // Minimum number of variants in generated enums
enum_max_variants // Maximum number of variants in generated enums
slice_min_len // Minimum length of generated slices
slice_max_len // Maximum length of generated slices
bytes_min_len // Minimum length of generated bytes
bytes_max_len // Maximum length of generated bytes
All above config parameters can be overwritten by specifying values as command line arguments.
The output folder has the following structure
.
├── compilation_errors
│ ├── sway
│ └── ts
├── decoding_errors
│ ├── rust
│ ├── sway
│ └── ts
├── encoding_missmatches
└── sway_reverts
compilation_errors
contains the logs of errors that occur during compilation of either the geneated sway smart contract or the generated typescript SDK.
decoding_errors
contains the logs of errors that occur during abi decoding of the encoding.
encoding_missmatches
contains the logs of errors that occur when there is a missmatch of the abi encoding between at least two of the three implementations (RustSDK, Sway, TypescriptSDK).
sway_reverts
contains the logs of reverts that occur during the execution of the sway smart contract.
In this part we give a brief overview of the project structure.
.
├── config.rs // Config file handling
├── error.rs // Errors
├── fuzzer.rs // Fuzzing logic
├── main.rs // Main entry point
├── rustsdk.rs // Rust SDK encoding and decoding
├── sampler.rs // Samples a random type with values to encode and decode
├── sway_converter.rs // Converts type and values to Sway
├── sway.rs // Sway encoding and decoding
├── ts_converter.rs // Converts type and values to Typescript
└── tssdk.rs // Typescript SDK encoding and decoding
Several bugs have been found by the fuzzer. They can be found in the ``issues` folder.
The following bugs have been found:
- RustSDK fails to decode an element that it encoded (see
issues/rustsdk_decoding_errors/
) - Sway compiler can run into a memory flow error (see
issues/sway_memory_overflow/
) or a memory overlap error (seeissues/sway_memory_write_overlap/
) - Sway fails to compile due to a type check error occuring when a tuple of a single element is decoded as the decoding will not produce a tuple but only the single element it contained. (see
issues/sway_tuple_compiler_error/
)
The fuzzer generates random values for the types that are to be encoded and decoded. The values are generated based on the type of the field.
Warning: The current string generation was modified to generate valid strings for sway which does not support characters such as '\n' or '\t'. Therefore, such characters are currently not generated. Please refer to
src/sampler.rs:sample_ascii_string
to modify the string generation to include such characters.