#
tokens: 42774/50000 4/1140 files (page 96/103)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 96 of 103. Use http://codebase.md/cyfrin/aderyn?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .cargo
│   └── config.toml
├── .git-blame-ignore-revs
├── .gitattributes
├── .github
│   ├── images
│   │   ├── aderyn_logo.png
│   │   ├── poweredbycyfrinblack.png
│   │   └── poweredbycyfrinblue.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   ├── false_positive_issue.md
│   │   └── feature_request.md
│   └── workflows
│       ├── cargo.yml
│       ├── dependencies.yml
│       ├── release.yml
│       ├── reports.yml
│       └── toml.yml
├── .gitignore
├── .gitmodules
├── .vscode
│   └── settings.json
├── aderyn
│   ├── Cargo.toml
│   ├── oranda.json
│   ├── README.md
│   ├── src
│   │   ├── birdsong.rs
│   │   ├── completions.rs
│   │   ├── lib.rs
│   │   ├── lsp.rs
│   │   ├── main.rs
│   │   ├── mcp.rs
│   │   └── panic.rs
│   └── templates
│       └── aderyn.toml
├── aderyn_core
│   ├── .gitignore
│   ├── Cargo.toml
│   ├── README.md
│   ├── src
│   │   ├── ast
│   │   │   ├── ast_nodes.rs
│   │   │   ├── ast.rs
│   │   │   ├── impls
│   │   │   │   ├── ctx
│   │   │   │   │   ├── utils.rs
│   │   │   │   │   └── workspace.rs
│   │   │   │   ├── ctx.rs
│   │   │   │   ├── disp
│   │   │   │   │   ├── blocks.rs
│   │   │   │   │   ├── contracts.rs
│   │   │   │   │   ├── enumerations.rs
│   │   │   │   │   ├── errors.rs
│   │   │   │   │   ├── events.rs
│   │   │   │   │   ├── expressions.rs
│   │   │   │   │   ├── functions.rs
│   │   │   │   │   ├── identifiers.rs
│   │   │   │   │   ├── literals.rs
│   │   │   │   │   ├── modifiers.rs
│   │   │   │   │   ├── statements.rs
│   │   │   │   │   ├── structures.rs
│   │   │   │   │   ├── types.rs
│   │   │   │   │   ├── user_defined_value_types.rs
│   │   │   │   │   ├── using_for_directives.rs
│   │   │   │   │   └── variables.rs
│   │   │   │   ├── disp.rs
│   │   │   │   ├── node
│   │   │   │   │   ├── blocks.rs
│   │   │   │   │   ├── contracts.rs
│   │   │   │   │   ├── documentation.rs
│   │   │   │   │   ├── enumerations.rs
│   │   │   │   │   ├── errors.rs
│   │   │   │   │   ├── events.rs
│   │   │   │   │   ├── expressions.rs
│   │   │   │   │   ├── functions.rs
│   │   │   │   │   ├── identifiers.rs
│   │   │   │   │   ├── import_directives.rs
│   │   │   │   │   ├── literals.rs
│   │   │   │   │   ├── modifiers.rs
│   │   │   │   │   ├── pragma_directives.rs
│   │   │   │   │   ├── source_units.rs
│   │   │   │   │   ├── statements.rs
│   │   │   │   │   ├── structures.rs
│   │   │   │   │   ├── types.rs
│   │   │   │   │   ├── user_defined_value_types.rs
│   │   │   │   │   ├── using_for_directives.rs
│   │   │   │   │   └── variables.rs
│   │   │   │   ├── node.rs
│   │   │   │   ├── own
│   │   │   │   │   ├── hashing.rs
│   │   │   │   │   ├── node_id.rs
│   │   │   │   │   ├── source_units.rs
│   │   │   │   │   └── utils.rs
│   │   │   │   └── own.rs
│   │   │   ├── impls.rs
│   │   │   ├── macros.rs
│   │   │   ├── magic.rs
│   │   │   ├── node_type.rs
│   │   │   └── yul.rs
│   │   ├── ast.rs
│   │   ├── audit
│   │   │   ├── attack_surface.rs
│   │   │   ├── auditor.rs
│   │   │   ├── entrypoint.rs
│   │   │   └── public_functions_no_sender.rs
│   │   ├── audit.rs
│   │   ├── context
│   │   │   ├── browser
│   │   │   │   ├── ancestral_line.rs
│   │   │   │   ├── closest_ancestor.rs
│   │   │   │   ├── external_calls.rs
│   │   │   │   ├── extractor.rs
│   │   │   │   ├── immediate_children.rs
│   │   │   │   ├── location.rs
│   │   │   │   ├── macros.rs
│   │   │   │   ├── parent.rs
│   │   │   │   ├── peek_over.rs
│   │   │   │   ├── peek_under.rs
│   │   │   │   ├── peek.rs
│   │   │   │   ├── siblings.rs
│   │   │   │   ├── sort_nodes.rs
│   │   │   │   └── storage_vars.rs
│   │   │   ├── browser.rs
│   │   │   ├── capturable.rs
│   │   │   ├── flow
│   │   │   │   ├── display.rs
│   │   │   │   ├── error.rs
│   │   │   │   ├── kind.rs
│   │   │   │   ├── primitives.rs
│   │   │   │   ├── reducibles.rs
│   │   │   │   ├── tests.rs
│   │   │   │   ├── utils.rs
│   │   │   │   ├── visualizer.rs
│   │   │   │   └── voids.rs
│   │   │   ├── flow.rs
│   │   │   ├── graph
│   │   │   │   ├── callgraph
│   │   │   │   │   ├── legacy.rs
│   │   │   │   │   ├── new.rs
│   │   │   │   │   ├── tests.rs
│   │   │   │   │   ├── utils.rs
│   │   │   │   │   └── visit.rs
│   │   │   │   ├── callgraph.rs
│   │   │   │   ├── preprocess
│   │   │   │   │   ├── legacy.rs
│   │   │   │   │   └── new.rs
│   │   │   │   ├── preprocess.rs
│   │   │   │   ├── traits.rs
│   │   │   │   └── utils.rs
│   │   │   ├── graph.rs
│   │   │   ├── macros.rs
│   │   │   ├── mcp
│   │   │   │   ├── callgraph
│   │   │   │   │   ├── render.rs
│   │   │   │   │   ├── tool.rs
│   │   │   │   │   └── utils.rs
│   │   │   │   ├── callgraph.rs
│   │   │   │   ├── contract_surface
│   │   │   │   │   ├── render.rs
│   │   │   │   │   ├── tool.rs
│   │   │   │   │   └── util.rs
│   │   │   │   ├── contract_surface.rs
│   │   │   │   ├── list_contracts
│   │   │   │   │   ├── render.rs
│   │   │   │   │   └── tool.rs
│   │   │   │   ├── list_contracts.rs
│   │   │   │   ├── node_finder
│   │   │   │   │   ├── render.rs
│   │   │   │   │   ├── tool.rs
│   │   │   │   │   └── utils.rs
│   │   │   │   ├── node_finder.rs
│   │   │   │   ├── node_summarizer
│   │   │   │   │   ├── render.rs
│   │   │   │   │   ├── tool.rs
│   │   │   │   │   └── utils.rs
│   │   │   │   ├── node_summarizer.rs
│   │   │   │   ├── project_overview
│   │   │   │   │   ├── render.rs
│   │   │   │   │   └── tool.rs
│   │   │   │   ├── project_overview.rs
│   │   │   │   ├── tool_guide
│   │   │   │   │   └── tool.rs
│   │   │   │   └── tool_guide.rs
│   │   │   ├── mcp.rs
│   │   │   ├── router
│   │   │   │   ├── external_calls.rs
│   │   │   │   ├── internal_calls.rs
│   │   │   │   ├── modifier_calls.rs
│   │   │   │   └── tests.rs
│   │   │   ├── router.rs
│   │   │   └── workspace.rs
│   │   ├── context.rs
│   │   ├── detect
│   │   │   ├── detector.rs
│   │   │   ├── entrypoint.rs
│   │   │   ├── helpers.rs
│   │   │   ├── high
│   │   │   │   ├── _template.rs
│   │   │   │   ├── abi_encode_packed_hash_collision.rs
│   │   │   │   ├── arbitrary_transfer_from.rs
│   │   │   │   ├── const_func_changes_state.rs
│   │   │   │   ├── contract_locks_ether.rs
│   │   │   │   ├── dangerous_unary_operator.rs
│   │   │   │   ├── delegate_call_unchecked_address.rs
│   │   │   │   ├── delete_nested_mapping.rs
│   │   │   │   ├── dynamic_array_length_assignment.rs
│   │   │   │   ├── enumerable_loop_removal.rs
│   │   │   │   ├── eth_send_unchecked_address.rs
│   │   │   │   ├── experimental_encoder.rs
│   │   │   │   ├── function_selector_collision.rs
│   │   │   │   ├── incorrect_caret_operator.rs
│   │   │   │   ├── incorrect_erc20_interface.rs
│   │   │   │   ├── incorrect_erc721_interface.rs
│   │   │   │   ├── incorrect_shift_order.rs
│   │   │   │   ├── misused_boolean.rs
│   │   │   │   ├── msg_value_in_loops.rs
│   │   │   │   ├── multiple_constructors.rs
│   │   │   │   ├── nested_struct_in_mapping.rs
│   │   │   │   ├── out_of_order_retryable.rs
│   │   │   │   ├── pre_declared_variable_usage.rs
│   │   │   │   ├── reentrancy_state_change.rs
│   │   │   │   ├── reused_contract_name.rs
│   │   │   │   ├── rtlo.rs
│   │   │   │   ├── selfdestruct.rs
│   │   │   │   ├── signed_integer_storage_array.rs
│   │   │   │   ├── state_variable_shadowing.rs
│   │   │   │   ├── storage_array_memory_edit.rs
│   │   │   │   ├── strict_equality_contract_balance.rs
│   │   │   │   ├── tautological_compare.rs
│   │   │   │   ├── tautology_or_contradiction.rs
│   │   │   │   ├── tx_origin_used_for_auth.rs
│   │   │   │   ├── unchecked_low_level_call.rs
│   │   │   │   ├── unchecked_send.rs
│   │   │   │   ├── unprotected_initializer.rs
│   │   │   │   ├── unsafe_casting.rs
│   │   │   │   ├── weak_randomness.rs
│   │   │   │   └── yul_return.rs
│   │   │   ├── high.rs
│   │   │   ├── low
│   │   │   │   ├── _template.rs
│   │   │   │   ├── assert_state_change.rs
│   │   │   │   ├── block_timestamp_deadline.rs
│   │   │   │   ├── boolean_equality.rs
│   │   │   │   ├── builtin_symbol_shadowing.rs
│   │   │   │   ├── centralization_risk.rs
│   │   │   │   ├── constant_function_contains_assembly.rs
│   │   │   │   ├── costly_loop.rs
│   │   │   │   ├── dead_code.rs
│   │   │   │   ├── delegatecall_in_loop.rs
│   │   │   │   ├── deprecated_oz_function.rs
│   │   │   │   ├── division_before_multiplication.rs
│   │   │   │   ├── ecrecover.rs
│   │   │   │   ├── empty_block.rs
│   │   │   │   ├── empty_require_revert.rs
│   │   │   │   ├── function_initializing_state.rs
│   │   │   │   ├── function_pointer_in_constructor.rs
│   │   │   │   ├── inconsistent_type_names.rs
│   │   │   │   ├── incorrect_modifier.rs
│   │   │   │   ├── internal_function_used_once.rs
│   │   │   │   ├── large_numeric_literal.rs
│   │   │   │   ├── literal_instead_of_constant.rs
│   │   │   │   ├── local_variable_shadowing.rs
│   │   │   │   ├── missing_inheritance.rs
│   │   │   │   ├── modifier_used_only_once.rs
│   │   │   │   ├── multiple_placeholders.rs
│   │   │   │   ├── non_reentrant_not_first.rs
│   │   │   │   ├── push_0_opcode.rs
│   │   │   │   ├── redundant_statement.rs
│   │   │   │   ├── require_revert_in_loop.rs
│   │   │   │   ├── return_bomb.rs
│   │   │   │   ├── solmate_safe_transfer_lib.rs
│   │   │   │   ├── state_change_without_event.rs
│   │   │   │   ├── state_no_address_check.rs
│   │   │   │   ├── state_variable_could_be_constant.rs
│   │   │   │   ├── state_variable_could_be_immutable.rs
│   │   │   │   ├── state_variable_read_external.rs
│   │   │   │   ├── storage_array_length_not_cached.rs
│   │   │   │   ├── todo.rs
│   │   │   │   ├── unchecked_return.rs
│   │   │   │   ├── uninitialized_local_variable.rs
│   │   │   │   ├── unsafe_erc20_operation.rs
│   │   │   │   ├── unsafe_oz_erc721_mint.rs
│   │   │   │   ├── unspecific_solidity_pragma.rs
│   │   │   │   ├── unused_error.rs
│   │   │   │   ├── unused_import.rs
│   │   │   │   ├── unused_public_function.rs
│   │   │   │   ├── unused_state_variable.rs
│   │   │   │   └── void_constructor.rs
│   │   │   ├── low.rs
│   │   │   └── test_utils.rs
│   │   ├── detect.rs
│   │   ├── lib.rs
│   │   ├── stats
│   │   │   ├── cloc.rs
│   │   │   ├── dbg_tips.txt
│   │   │   ├── ignore.rs
│   │   │   ├── token.rs
│   │   │   └── util.rs
│   │   ├── stats.rs
│   │   ├── test_utils
│   │   │   └── load_source_unit.rs
│   │   ├── test_utils.rs
│   │   ├── visitor
│   │   │   ├── ast_visitor.rs
│   │   │   ├── macros.rs
│   │   │   └── workspace_visitor.rs
│   │   └── visitor.rs
│   ├── templates
│   │   └── mcp-tool-response
│   │       ├── callgraph.md
│   │       ├── contract_surface.md
│   │       ├── list_contracts.md
│   │       ├── node_finder_get_all.md
│   │       ├── node_finder_grep.md
│   │       ├── node_finder_search.md
│   │       ├── node_summarizer.md
│   │       ├── project_overview.md
│   │       └── tool_guide.md
│   └── tests
│       ├── common
│       │   ├── ancestral_line.rs
│       │   ├── closest_ancestor.rs
│       │   ├── immediate_children.rs
│       │   ├── immediate_parent.rs
│       │   ├── mod.rs
│       │   ├── new_ast_nodes.rs
│       │   ├── peek_over.rs
│       │   └── sibling.rs
│       └── traversal.rs
├── aderyn_driver
│   ├── .gitignore
│   ├── benches
│   │   └── detectors.rs
│   ├── Cargo.toml
│   ├── README.md
│   ├── src
│   │   ├── compile.rs
│   │   ├── config.rs
│   │   ├── display.rs
│   │   ├── driver.rs
│   │   ├── interface
│   │   │   ├── json.rs
│   │   │   ├── lsp.rs
│   │   │   ├── markdown.rs
│   │   │   ├── mod.rs
│   │   │   ├── sarif.rs
│   │   │   ├── tables.rs
│   │   │   └── util.rs
│   │   ├── lib.rs
│   │   ├── mcp.rs
│   │   ├── process.rs
│   │   └── runner.rs
│   └── tests
│       └── astgen.rs
├── bacon.toml
├── benchmarks
│   ├── aderyn
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── iteration_times.svg
│   │       │   └── pdf.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── iteration_times_small.svg
│   │       ├── iteration_times.svg
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── relative_iteration_times_small.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── SD.svg
│   │       └── typical.svg
│   ├── arbitrary-transfer-from
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── avoid-abi-encode-packed
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── block-timestamp-deadline
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── centralization-risk
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── constants-instead-of-literals
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── delegate-call-in-loop
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── deprecated-oz-functions
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── ecrecover
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── empty-block
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── hello_world
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── inconsistent-type-names
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── large-numeric-literal
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── non-reentrant-before-others
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── push-zero-opcode
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── report
│   │   └── index.html
│   ├── require-with-string
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── solmate-safe-transfer-lib
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── unindexed-events
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── unprotected-initializer
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── unsafe-erc20-functions
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── unsafe-oz-erc721-mint
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── unspecific-solidity-pragma
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── useless-internal-function
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── useless-modifier
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   ├── useless-public-function
│   │   ├── base
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   ├── change
│   │   │   └── estimates.json
│   │   ├── new
│   │   │   ├── benchmark.json
│   │   │   ├── estimates.json
│   │   │   ├── sample.json
│   │   │   └── tukey.json
│   │   └── report
│   │       ├── both
│   │       │   ├── pdf.svg
│   │       │   └── regression.svg
│   │       ├── change
│   │       │   ├── mean.svg
│   │       │   ├── median.svg
│   │       │   └── t-test.svg
│   │       ├── index.html
│   │       ├── MAD.svg
│   │       ├── mean.svg
│   │       ├── median.svg
│   │       ├── pdf_small.svg
│   │       ├── pdf.svg
│   │       ├── regression_small.svg
│   │       ├── regression.svg
│   │       ├── relative_pdf_small.svg
│   │       ├── relative_regression_small.svg
│   │       ├── SD.svg
│   │       ├── slope.svg
│   │       └── typical.svg
│   └── zero-address-check
│       ├── base
│       │   ├── benchmark.json
│       │   ├── estimates.json
│       │   ├── sample.json
│       │   └── tukey.json
│       ├── change
│       │   └── estimates.json
│       ├── new
│       │   ├── benchmark.json
│       │   ├── estimates.json
│       │   ├── sample.json
│       │   └── tukey.json
│       └── report
│           ├── both
│           │   ├── pdf.svg
│           │   └── regression.svg
│           ├── change
│           │   ├── mean.svg
│           │   ├── median.svg
│           │   └── t-test.svg
│           ├── index.html
│           ├── MAD.svg
│           ├── mean.svg
│           ├── median.svg
│           ├── pdf_small.svg
│           ├── pdf.svg
│           ├── regression_small.svg
│           ├── regression.svg
│           ├── relative_pdf_small.svg
│           ├── relative_regression_small.svg
│           ├── SD.svg
│           ├── slope.svg
│           └── typical.svg
├── Cargo.lock
├── Cargo.toml
├── cli
│   ├── benchmarks.sh
│   └── reportgen.sh
├── CODEOWNERS
├── CONTRIBUTING.md
├── cyfrinup
│   ├── dynamic_script
│   └── why.md
├── deny.toml
├── dist-workspace.toml
├── funding.json
├── LICENSE
├── Makefile
├── package-lock.json
├── package.json
├── README.md
├── RELEASE_CHECKLIST.md
├── reports
│   ├── adhoc-sol-files-highs-only-report.json
│   ├── adhoc-sol-files-report.md
│   ├── ccip-functions-report.md
│   ├── empty_report.md
│   ├── hardhat-playground-report.md
│   ├── nft-report-icm.md
│   ├── nft-report.md
│   ├── prb-math-report.md
│   ├── report.json
│   ├── report.md
│   ├── report.sarif
│   ├── sablier-aderyn-toml-nested-root.md
│   ├── templegold-report.md
│   └── uniswap_profile.md
├── rust-toolchain.toml
├── rustfmt.toml
├── tests
│   ├── adhoc-sol-files
│   │   ├── aderyn.toml
│   │   ├── Counter.sol
│   │   ├── DemoASTNodes.sol
│   │   ├── Helper.sol
│   │   ├── InconsistentUints.sol
│   │   ├── inheritance
│   │   │   ├── ExtendedInheritance.sol
│   │   │   ├── IContractInheritance.sol
│   │   │   └── InheritanceBase.sol
│   │   ├── InternalFunctions.sol
│   │   ├── lib
│   │   │   └── ThisShouldBeExcluded.sol
│   │   ├── multiple-versions
│   │   │   ├── 0.4
│   │   │   │   ├── A.sol
│   │   │   │   └── B.sol
│   │   │   ├── 0.5
│   │   │   │   ├── A.sol
│   │   │   │   └── B.sol
│   │   │   ├── 0.6
│   │   │   │   ├── A.sol
│   │   │   │   └── B.sol
│   │   │   ├── 0.7
│   │   │   │   ├── A.sol
│   │   │   │   └── B.sol
│   │   │   └── 0.8
│   │   │       ├── A.sol
│   │   │       └── B.sol
│   │   ├── OnceModifierExample.sol
│   │   └── StateVariables.sol
│   ├── ast
│   │   ├── abstract_contract.json
│   │   ├── address_payable.json
│   │   ├── array_type_name.json
│   │   ├── ast-erc4626.json
│   │   ├── base_constructor_call.json
│   │   ├── bit_not.json
│   │   ├── call.json
│   │   ├── constructor.json
│   │   ├── contract_dep_order.json
│   │   ├── do_while.json
│   │   ├── documentation_1.json
│   │   ├── documentation_2.json
│   │   ├── documentation_3.json
│   │   ├── documentation_local_variable.json
│   │   ├── documentation_on_statements.json
│   │   ├── documentation_triple.json
│   │   ├── empty_block.json
│   │   ├── enum_value_declaration.json
│   │   ├── enum_value.json
│   │   ├── event_definition.json
│   │   ├── experimental_encoder_pragma.json
│   │   ├── fallback_and_reveice_ether.json
│   │   ├── fallback_payable.json
│   │   ├── fallback.json
│   │   ├── function_type.json
│   │   ├── function.json
│   │   ├── global_enum.json
│   │   ├── global_struct.json
│   │   ├── inheritance_specifier.json
│   │   ├── leave.json
│   │   ├── license.json
│   │   ├── long_type_name_binary_operation.json
│   │   ├── long_type_name_identifier.json
│   │   ├── loop.json
│   │   ├── mappings.json
│   │   ├── modifier_definition.json
│   │   ├── modifier_invocation.json
│   │   ├── mutability.json
│   │   ├── nested_functions.json
│   │   ├── non_utf8.json
│   │   ├── override.json
│   │   ├── placeholder_statement.json
│   │   ├── receive_ether.json
│   │   ├── short_type_name_ref.json
│   │   ├── short_type_name.json
│   │   ├── slot_offset.json
│   │   ├── smoke.json
│   │   ├── source_location.json
│   │   ├── string.json
│   │   ├── stringlit.json
│   │   ├── switch_default.json
│   │   ├── switch.json
│   │   ├── try_catch.json
│   │   ├── two_base_functions.json
│   │   ├── unicode.json
│   │   ├── used_errors.json
│   │   ├── userDefinedValueType.json
│   │   ├── using_for_directive.json
│   │   ├── var_access.json
│   │   └── yul_hex_literal.json
│   ├── contract-playground
│   │   ├── .github
│   │   │   └── workflows
│   │   │       └── test.yml
│   │   ├── .gitignore
│   │   ├── dot
│   │   │   └── .gitkeep
│   │   ├── foundry.toml
│   │   ├── README.md
│   │   ├── script
│   │   │   └── Counter.s.sol
│   │   ├── src
│   │   │   ├── AbstractContract.sol
│   │   │   ├── AderynIgnoreCustomDetectors.sol
│   │   │   ├── AdminContract.sol
│   │   │   ├── ArbitraryTransferFrom.sol
│   │   │   ├── AssemblyExample.sol
│   │   │   ├── AssertStateChange.sol
│   │   │   ├── auditor_mode
│   │   │   │   ├── ExternalCalls.sol
│   │   │   │   └── PublicFunctionsWithoutSenderCheck.sol
│   │   │   ├── BooleanEquality.sol
│   │   │   ├── BuiltinSymbolShadow.sol
│   │   │   ├── CacheArrayLength.sol
│   │   │   ├── CallGraphTests.sol
│   │   │   ├── Casting.sol
│   │   │   ├── cloc
│   │   │   │   ├── AnotherHeavilyCommentedContract.sol
│   │   │   │   ├── EmptyContractFile.sol
│   │   │   │   └── HeavilyCommentedContract.sol
│   │   │   ├── CompilerBugStorageSignedIntegerArray.sol
│   │   │   ├── ConstantFuncsAssembly.sol
│   │   │   ├── ConstantsLiterals.sol
│   │   │   ├── ConstFuncChangeState.sol
│   │   │   ├── ContractLocksEther.sol
│   │   │   ├── ContractWithTodo.sol
│   │   │   ├── control_flow
│   │   │   │   └── SimpleProgram.sol
│   │   │   ├── CostlyOperationsInsideLoops.sol
│   │   │   ├── Counter.sol
│   │   │   ├── CrazyPragma.sol
│   │   │   ├── DangerousStrictEquality1.sol
│   │   │   ├── DangerousStrictEquality2.sol
│   │   │   ├── DangerousUnaryOperator.sol
│   │   │   ├── DeadCode.sol
│   │   │   ├── DelegateCallWithoutAddressCheck.sol
│   │   │   ├── DeletionNestedMappingStructureContract.sol
│   │   │   ├── DeprecatedOZFunctions.sol
│   │   │   ├── DivisionBeforeMultiplication.sol
│   │   │   ├── DynamicArrayLengthAssignment.sol
│   │   │   ├── EmitAfterExternalCall.sol
│   │   │   ├── EmptyBlocks.sol
│   │   │   ├── EnumerableSetIteration.sol
│   │   │   ├── eth2
│   │   │   │   └── DepositContract.sol
│   │   │   ├── ExperimentalEncoder.sol
│   │   │   ├── ExternalCalls.sol
│   │   │   ├── FunctionInitializingState.sol
│   │   │   ├── FunctionPointers.sol
│   │   │   ├── FunctionSignatureCollision.sol
│   │   │   ├── HugeConstants.sol
│   │   │   ├── IgnoreEverything.sol
│   │   │   ├── InconsistentUints.sol
│   │   │   ├── IncorrectCaretOperator.sol
│   │   │   ├── IncorrectERC20.sol
│   │   │   ├── IncorrectERC721.sol
│   │   │   ├── IncorrectModifier.sol
│   │   │   ├── IncorrectShift.sol
│   │   │   ├── inheritance
│   │   │   │   ├── ExtendedInheritance.sol
│   │   │   │   ├── IContractInheritance.sol
│   │   │   │   └── InheritanceBase.sol
│   │   │   ├── InternalFunctions.sol
│   │   │   ├── KeccakContract.sol
│   │   │   ├── LocalVariableShadow.sol
│   │   │   ├── MissingInheritance.sol
│   │   │   ├── MisusedBoolean.sol
│   │   │   ├── MsgValueInLoop.sol
│   │   │   ├── MultipleConstructorSchemes.sol
│   │   │   ├── MultiplePlaceholders.sol
│   │   │   ├── nested
│   │   │   │   ├── 1
│   │   │   │   │   └── Nested.sol
│   │   │   │   └── 2
│   │   │   │       └── Nested.sol
│   │   │   ├── nested_mappings
│   │   │   │   ├── LaterVersion.sol
│   │   │   │   └── NestedMappings.sol
│   │   │   ├── OnceModifierExample.sol
│   │   │   ├── OnlyLibrary.sol
│   │   │   ├── OutOfOrderRetryable.sol
│   │   │   ├── parent_chain
│   │   │   │   └── ParentChainContract.sol
│   │   │   ├── PragmaRange.sol
│   │   │   ├── PreDeclaredVarUsage.sol
│   │   │   ├── PublicFunction.sol
│   │   │   ├── PublicVariableReadInExternalContext.sol
│   │   │   ├── RedundantStatements.sol
│   │   │   ├── ReturnBomb.sol
│   │   │   ├── reused_contract_name
│   │   │   │   ├── ContractA.sol
│   │   │   │   └── ContractB.sol
│   │   │   ├── RevertsAndRequriesInLoops.sol
│   │   │   ├── router
│   │   │   │   ├── ExternalCalls.sol
│   │   │   │   ├── FallbackAndReceiveOverrides.sol
│   │   │   │   ├── InternalCalls.sol
│   │   │   │   ├── ModifierCalls.sol
│   │   │   │   └── VarOverridesFunction.sol
│   │   │   ├── RTLO.sol
│   │   │   ├── SendEtherNoChecks.sol
│   │   │   ├── SendEtherNoChecksLibImport.sol
│   │   │   ├── StateChangeAfterExternalCall.sol
│   │   │   ├── StateShadowing.sol
│   │   │   ├── StateVariableCouldBeDeclaredConstant.sol
│   │   │   ├── StateVariableCouldBeDeclaredImmutable.sol
│   │   │   ├── StateVariables.sol
│   │   │   ├── StateVariablesChangesWithoutEvents.sol
│   │   │   ├── StateVariablesManipulation.sol
│   │   │   ├── StorageConditionals.sol
│   │   │   ├── StorageParameters.sol
│   │   │   ├── T11sTranferer.sol
│   │   │   ├── TautologicalCompare.sol
│   │   │   ├── TautologyOrContradiction.sol
│   │   │   ├── TestERC20.sol
│   │   │   ├── TransientKeyword.sol
│   │   │   ├── Trump.sol
│   │   │   ├── TxOriginUsedForAuth.sol
│   │   │   ├── U2.sol
│   │   │   ├── U3.sol
│   │   │   ├── U4.sol
│   │   │   ├── U5.sol
│   │   │   ├── UncheckedCalls.sol
│   │   │   ├── UncheckedReturn.sol
│   │   │   ├── UncheckedSend.sol
│   │   │   ├── UninitializedLocalVariables.sol
│   │   │   ├── UninitializedStateVariable.sol
│   │   │   ├── uniswap
│   │   │   │   ├── UniswapV2Swapper.sol
│   │   │   │   └── UniswapV3Swapper.sol
│   │   │   ├── UnprotectedInitialize.sol
│   │   │   ├── UnsafeERC721Mint.sol
│   │   │   ├── UnusedError.sol
│   │   │   ├── UnusedImport.sol
│   │   │   ├── UnusedStateVariables.sol
│   │   │   ├── UsingSelfdestruct.sol
│   │   │   ├── VoidConstructor.sol
│   │   │   ├── WeakRandomness.sol
│   │   │   ├── WrongOrderOfLayout.sol
│   │   │   ├── YulReturn.sol
│   │   │   └── ZeroAddressCheck.sol
│   │   └── test
│   │       └── Counter.t.sol
│   ├── foundry-nft-f23
│   │   ├── .github
│   │   │   └── workflows
│   │   │       └── test.yml
│   │   ├── .gitignore
│   │   ├── foundry.lock
│   │   ├── foundry.toml
│   │   ├── README.md
│   │   ├── remappings.txt
│   │   └── src
│   │       ├── BasicNft.sol
│   │       ├── F1.sol
│   │       ├── F2.sol
│   │       ├── Initializer.sol
│   │       └── inner-core-modules
│   │           └── ICM.sol
│   ├── foundry-nft-f23-icm
│   │   ├── .github
│   │   │   └── workflows
│   │   │       └── test.yml
│   │   ├── .gitignore
│   │   ├── aderyn.toml
│   │   ├── foundry.toml
│   │   ├── README.md
│   │   ├── remappings.txt
│   │   └── src
│   │       ├── BasicNft.sol
│   │       ├── F1.sol
│   │       ├── F2.sol
│   │       ├── Initializer.sol
│   │       └── inner-core-modules
│   │           └── ICM.sol
│   ├── hardhat-js-playground
│   │   ├── .gitignore
│   │   ├── artifacts
│   │   │   ├── build-info
│   │   │   │   └── cee6fe9a9a2f03f7ff10a27ab2746af6.json
│   │   │   └── contracts
│   │   │       ├── Counter.sol
│   │   │       │   ├── Counter.dbg.json
│   │   │       │   └── Counter.json
│   │   │       ├── ExtendedInheritance.sol
│   │   │       │   ├── ExtendedInheritance.dbg.json
│   │   │       │   └── ExtendedInheritance.json
│   │   │       ├── IContractInheritance.sol
│   │   │       │   ├── IContractInheritance.dbg.json
│   │   │       │   └── IContractInheritance.json
│   │   │       ├── InheritanceBase.sol
│   │   │       │   ├── InheritanceBase.dbg.json
│   │   │       │   └── InheritanceBase.json
│   │   │       ├── KeccakContract.sol
│   │   │       │   ├── KeccakContract.dbg.json
│   │   │       │   └── KeccakContract.json
│   │   │       ├── Lock.sol
│   │   │       │   ├── Lock.dbg.json
│   │   │       │   └── Lock.json
│   │   │       └── StateVariables.sol
│   │   │           ├── StateVariables.dbg.json
│   │   │           └── StateVariables.json
│   │   ├── contracts
│   │   │   ├── Counter.sol
│   │   │   ├── ExtendedInheritance.sol
│   │   │   ├── IContractInheritance.sol
│   │   │   ├── InheritanceBase.sol
│   │   │   ├── KeccakContract.sol
│   │   │   ├── Lock.sol
│   │   │   └── StateVariables.sol
│   │   ├── hardhat.config.js
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── scripts
│   │   │   └── deploy.js
│   │   ├── test
│   │   │   └── Lock.js
│   │   └── yarn.lock
│   ├── no-sol-files
│   │   ├── extra
│   │   │   └── HelloAgain.md
│   │   ├── Hello.txt
│   │   └── Hello.yul
│   └── toml
│       ├── nested_project1
│       │   ├── aderyn.toml
│       │   ├── folder1
│       │   │   └── hardhat.config.ts
│       │   ├── folder2
│       │   │   └── hardhat.config.ts
│       │   └── folder3
│       │       └── file.txt
│       └── nested_project2
│           ├── aderyn.toml
│           ├── folder1
│           │   └── foundry.toml
│           └── folder2
│               └── file1.txt
├── tools
│   └── xtask
│       ├── Cargo.toml
│       └── src
│           ├── blesspr.rs
│           ├── cut_release.rs
│           ├── flags.rs
│           ├── main.rs
│           ├── reportgen.rs
│           └── tomlgen.rs
└── typos.toml
```

# Files

--------------------------------------------------------------------------------
/reports/sablier-aderyn-toml-nested-root.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Aderyn Analysis Report
  2 | 
  3 | This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a static analysis tool built by [Cyfrin](https://cyfrin.io), a blockchain security company. This report is not a substitute for manual audit or security review. It should not be relied upon for any purpose other than to assist in the identification of potential security vulnerabilities.
  4 | # Table of Contents
  5 | 
  6 | - [Summary](#summary)
  7 |   - [Files Summary](#files-summary)
  8 |   - [Files Details](#files-details)
  9 |   - [Issue Summary](#issue-summary)
 10 | - [Low Issues](#low-issues)
 11 |   - [L-1: Unspecific Solidity Pragma](#l-1-unspecific-solidity-pragma)
 12 |   - [L-2: Address State Variable Set Without Checks](#l-2-address-state-variable-set-without-checks)
 13 |   - [L-3: Literal Instead of Constant](#l-3-literal-instead-of-constant)
 14 |   - [L-4: PUSH0 Opcode](#l-4-push0-opcode)
 15 |   - [L-5: Large Numeric Literal](#l-5-large-numeric-literal)
 16 |   - [L-6: Internal Function Used Only Once](#l-6-internal-function-used-only-once)
 17 |   - [L-7: Loop Contains `require`/`revert`](#l-7-loop-contains-requirerevert)
 18 |   - [L-8: Costly operations inside loop](#l-8-costly-operations-inside-loop)
 19 |   - [L-9: Unchecked Return](#l-9-unchecked-return)
 20 | 
 21 | 
 22 | # Summary
 23 | 
 24 | ## Files Summary
 25 | 
 26 | | Key | Value |
 27 | | --- | --- |
 28 | | .sol Files | 20 |
 29 | | Total nSLOC | 2190 |
 30 | 
 31 | 
 32 | ## Files Details
 33 | 
 34 | | Filepath | nSLOC |
 35 | | --- | --- |
 36 | | src/SablierV2LockupDynamic.sol | 211 |
 37 | | src/SablierV2LockupLinear.sol | 168 |
 38 | | src/SablierV2LockupTranched.sol | 161 |
 39 | | src/SablierV2NFTDescriptor.sol | 269 |
 40 | | src/abstracts/Adminable.sol | 16 |
 41 | | src/abstracts/NoDelegateCall.sol | 17 |
 42 | | src/abstracts/SablierV2Lockup.sol | 391 |
 43 | | src/interfaces/IAdminable.sol | 6 |
 44 | | src/interfaces/ISablierV2Lockup.sol | 56 |
 45 | | src/interfaces/ISablierV2LockupDynamic.sol | 29 |
 46 | | src/interfaces/ISablierV2LockupLinear.sol | 27 |
 47 | | src/interfaces/ISablierV2LockupTranched.sol | 29 |
 48 | | src/interfaces/ISablierV2NFTDescriptor.sol | 5 |
 49 | | src/interfaces/hooks/ISablierV2Recipient.sol | 12 |
 50 | | src/interfaces/hooks/ISablierV2Sender.sol | 4 |
 51 | | src/libraries/Errors.sol | 50 |
 52 | | src/libraries/Helpers.sol | 212 |
 53 | | src/libraries/NFTSVG.sol | 144 |
 54 | | src/libraries/SVGElements.sol | 200 |
 55 | | src/types/DataTypes.sol | 183 |
 56 | | **Total** | **2190** |
 57 | 
 58 | 
 59 | ## Issue Summary
 60 | 
 61 | | Category | No. of Issues |
 62 | | --- | --- |
 63 | | High | 0 |
 64 | | Low | 9 |
 65 | 
 66 | 
 67 | # Low Issues
 68 | 
 69 | ## L-1: Unspecific Solidity Pragma
 70 | 
 71 | Consider using a specific version of Solidity in your contracts instead of a wide version. For example, instead of `pragma solidity ^0.8.0;`, use `pragma solidity 0.8.0;`
 72 | 
 73 | <details><summary>15 Found Instances</summary>
 74 | 
 75 | 
 76 | - Found in src/SablierV2LockupDynamic.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupDynamic.sol#L2)
 77 | 
 78 | 	```solidity
 79 | 	pragma solidity >=0.8.22;
 80 | 	```
 81 | 
 82 | - Found in src/SablierV2LockupLinear.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupLinear.sol#L2)
 83 | 
 84 | 	```solidity
 85 | 	pragma solidity >=0.8.22;
 86 | 	```
 87 | 
 88 | - Found in src/SablierV2LockupTranched.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupTranched.sol#L2)
 89 | 
 90 | 	```solidity
 91 | 	pragma solidity >=0.8.22;
 92 | 	```
 93 | 
 94 | - Found in src/SablierV2NFTDescriptor.sol [Line: 3](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L3)
 95 | 
 96 | 	```solidity
 97 | 	pragma solidity >=0.8.22;
 98 | 	```
 99 | 
100 | - Found in src/abstracts/Adminable.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/abstracts/Adminable.sol#L2)
101 | 
102 | 	```solidity
103 | 	pragma solidity >=0.8.22;
104 | 	```
105 | 
106 | - Found in src/abstracts/NoDelegateCall.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/abstracts/NoDelegateCall.sol#L2)
107 | 
108 | 	```solidity
109 | 	pragma solidity >=0.8.22;
110 | 	```
111 | 
112 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L2)
113 | 
114 | 	```solidity
115 | 	pragma solidity >=0.8.22;
116 | 	```
117 | 
118 | - Found in src/interfaces/IAdminable.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/IAdminable.sol#L2)
119 | 
120 | 	```solidity
121 | 	pragma solidity >=0.8.22;
122 | 	```
123 | 
124 | - Found in src/interfaces/ISablierV2Lockup.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2Lockup.sol#L2)
125 | 
126 | 	```solidity
127 | 	pragma solidity >=0.8.22;
128 | 	```
129 | 
130 | - Found in src/interfaces/ISablierV2LockupDynamic.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2LockupDynamic.sol#L2)
131 | 
132 | 	```solidity
133 | 	pragma solidity >=0.8.22;
134 | 	```
135 | 
136 | - Found in src/interfaces/ISablierV2LockupLinear.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2LockupLinear.sol#L2)
137 | 
138 | 	```solidity
139 | 	pragma solidity >=0.8.22;
140 | 	```
141 | 
142 | - Found in src/interfaces/ISablierV2LockupTranched.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2LockupTranched.sol#L2)
143 | 
144 | 	```solidity
145 | 	pragma solidity >=0.8.22;
146 | 	```
147 | 
148 | - Found in src/interfaces/ISablierV2NFTDescriptor.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2NFTDescriptor.sol#L2)
149 | 
150 | 	```solidity
151 | 	pragma solidity >=0.8.22;
152 | 	```
153 | 
154 | - Found in src/interfaces/hooks/ISablierV2Recipient.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/hooks/ISablierV2Recipient.sol#L2)
155 | 
156 | 	```solidity
157 | 	pragma solidity >=0.8.22;
158 | 	```
159 | 
160 | - Found in src/interfaces/hooks/ISablierV2Sender.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/hooks/ISablierV2Sender.sol#L2)
161 | 
162 | 	```solidity
163 | 	pragma solidity >=0.8.22;
164 | 	```
165 | 
166 | </details>
167 | 
168 | 
169 | 
170 | ## L-2: Address State Variable Set Without Checks
171 | 
172 | Check for `address(0)` when assigning values to address state variables.
173 | 
174 | <details><summary>4 Found Instances</summary>
175 | 
176 | 
177 | - Found in src/abstracts/Adminable.sol [Line: 36](../tests/2024-05-Sablier/v2-core/src/abstracts/Adminable.sol#L36)
178 | 
179 | 	```solidity
180 | 	        admin = newAdmin;
181 | 	```
182 | 
183 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 55](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L55)
184 | 
185 | 	```solidity
186 | 	        admin = initialAdmin;
187 | 	```
188 | 
189 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 56](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L56)
190 | 
191 | 	```solidity
192 | 	        nftDescriptor = initialNFTDescriptor;
193 | 	```
194 | 
195 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 318](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L318)
196 | 
197 | 	```solidity
198 | 	        nftDescriptor = newNFTDescriptor;
199 | 	```
200 | 
201 | </details>
202 | 
203 | 
204 | 
205 | ## L-3: Literal Instead of Constant
206 | 
207 | Define and use `constant` variables instead of using literals. If the same constant literal value is used multiple times, create a constant state variable and reference it throughout the contract.
208 | 
209 | <details><summary>12 Found Instances</summary>
210 | 
211 | 
212 | - Found in src/SablierV2NFTDescriptor.sol [Line: 140](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L140)
213 | 
214 | 	```solidity
215 | 	            truncatedAmount = decimals == 0 ? amount : amount / 10 ** decimals;
216 | 	```
217 | 
218 | - Found in src/SablierV2NFTDescriptor.sol [Line: 156](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L156)
219 | 
220 | 	```solidity
221 | 	            while (truncatedAmount >= 1000) {
222 | 	```
223 | 
224 | - Found in src/SablierV2NFTDescriptor.sol [Line: 157](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L157)
225 | 
226 | 	```solidity
227 | 	                fractionalAmount = (truncatedAmount / 10) % 100; // keep the first two digits after the decimal point
228 | 	```
229 | 
230 | - Found in src/SablierV2NFTDescriptor.sol [Line: 158](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L158)
231 | 
232 | 	```solidity
233 | 	                truncatedAmount /= 1000;
234 | 	```
235 | 
236 | - Found in src/SablierV2NFTDescriptor.sol [Line: 223](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L223)
237 | 
238 | 	```solidity
239 | 	            uint256 saturation = ((bitField >> 8) & 0xFF) % 80 + 20;
240 | 	```
241 | 
242 | - Found in src/SablierV2NFTDescriptor.sol [Line: 228](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L228)
243 | 
244 | 	```solidity
245 | 	            uint256 lightness = (bitField & 0xFF) % 70 + 30;
246 | 	```
247 | 
248 | - Found in src/SablierV2NFTDescriptor.sol [Line: 346](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L346)
249 | 
250 | 	```solidity
251 | 	        if (bytes(symbol).length > 30) {
252 | 	```
253 | 
254 | - Found in src/SablierV2NFTDescriptor.sol [Line: 361](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L361)
255 | 
256 | 	```solidity
257 | 	        else if (fractionalAmount < 10) {
258 | 	```
259 | 
260 | - Found in src/SablierV2NFTDescriptor.sol [Line: 374](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L374)
261 | 
262 | 	```solidity
263 | 	        string memory fractionalPart = stringifyFractionalAmount(percentage % 100);
264 | 	```
265 | 
266 | - Found in src/SablierV2NFTDescriptor.sol [Line: 377](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L377)
267 | 
268 | 	```solidity
269 | 	        string memory wholePart = (percentage / 100).toString();
270 | 	```
271 | 
272 | </details>
273 | 
274 | 
275 | 
276 | ## L-4: PUSH0 Opcode
277 | 
278 | Solc compiler version 0.8.20 switches the default target EVM version to Shanghai, which means that the generated bytecode will include PUSH0 opcodes. Be sure to select the appropriate EVM version in case you intend to deploy on a chain other than mainnet like L2 chains that may not support PUSH0, otherwise deployment of your contracts will fail.
279 | 
280 | <details><summary>20 Found Instances</summary>
281 | 
282 | 
283 | - Found in src/SablierV2LockupDynamic.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupDynamic.sol#L2)
284 | 
285 | 	```solidity
286 | 	pragma solidity >=0.8.22;
287 | 	```
288 | 
289 | - Found in src/SablierV2LockupLinear.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupLinear.sol#L2)
290 | 
291 | 	```solidity
292 | 	pragma solidity >=0.8.22;
293 | 	```
294 | 
295 | - Found in src/SablierV2LockupTranched.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupTranched.sol#L2)
296 | 
297 | 	```solidity
298 | 	pragma solidity >=0.8.22;
299 | 	```
300 | 
301 | - Found in src/SablierV2NFTDescriptor.sol [Line: 3](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L3)
302 | 
303 | 	```solidity
304 | 	pragma solidity >=0.8.22;
305 | 	```
306 | 
307 | - Found in src/abstracts/Adminable.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/abstracts/Adminable.sol#L2)
308 | 
309 | 	```solidity
310 | 	pragma solidity >=0.8.22;
311 | 	```
312 | 
313 | - Found in src/abstracts/NoDelegateCall.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/abstracts/NoDelegateCall.sol#L2)
314 | 
315 | 	```solidity
316 | 	pragma solidity >=0.8.22;
317 | 	```
318 | 
319 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L2)
320 | 
321 | 	```solidity
322 | 	pragma solidity >=0.8.22;
323 | 	```
324 | 
325 | - Found in src/interfaces/IAdminable.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/IAdminable.sol#L2)
326 | 
327 | 	```solidity
328 | 	pragma solidity >=0.8.22;
329 | 	```
330 | 
331 | - Found in src/interfaces/ISablierV2Lockup.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2Lockup.sol#L2)
332 | 
333 | 	```solidity
334 | 	pragma solidity >=0.8.22;
335 | 	```
336 | 
337 | - Found in src/interfaces/ISablierV2LockupDynamic.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2LockupDynamic.sol#L2)
338 | 
339 | 	```solidity
340 | 	pragma solidity >=0.8.22;
341 | 	```
342 | 
343 | - Found in src/interfaces/ISablierV2LockupLinear.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2LockupLinear.sol#L2)
344 | 
345 | 	```solidity
346 | 	pragma solidity >=0.8.22;
347 | 	```
348 | 
349 | - Found in src/interfaces/ISablierV2LockupTranched.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2LockupTranched.sol#L2)
350 | 
351 | 	```solidity
352 | 	pragma solidity >=0.8.22;
353 | 	```
354 | 
355 | - Found in src/interfaces/ISablierV2NFTDescriptor.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/ISablierV2NFTDescriptor.sol#L2)
356 | 
357 | 	```solidity
358 | 	pragma solidity >=0.8.22;
359 | 	```
360 | 
361 | - Found in src/interfaces/hooks/ISablierV2Recipient.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/hooks/ISablierV2Recipient.sol#L2)
362 | 
363 | 	```solidity
364 | 	pragma solidity >=0.8.22;
365 | 	```
366 | 
367 | - Found in src/interfaces/hooks/ISablierV2Sender.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/interfaces/hooks/ISablierV2Sender.sol#L2)
368 | 
369 | 	```solidity
370 | 	pragma solidity >=0.8.22;
371 | 	```
372 | 
373 | - Found in src/libraries/Errors.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/libraries/Errors.sol#L2)
374 | 
375 | 	```solidity
376 | 	pragma solidity >=0.8.22;
377 | 	```
378 | 
379 | - Found in src/libraries/Helpers.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/libraries/Helpers.sol#L2)
380 | 
381 | 	```solidity
382 | 	pragma solidity >=0.8.22;
383 | 	```
384 | 
385 | - Found in src/libraries/NFTSVG.sol [Line: 3](../tests/2024-05-Sablier/v2-core/src/libraries/NFTSVG.sol#L3)
386 | 
387 | 	```solidity
388 | 	pragma solidity >=0.8.22;
389 | 	```
390 | 
391 | - Found in src/libraries/SVGElements.sol [Line: 3](../tests/2024-05-Sablier/v2-core/src/libraries/SVGElements.sol#L3)
392 | 
393 | 	```solidity
394 | 	pragma solidity >=0.8.22;
395 | 	```
396 | 
397 | - Found in src/types/DataTypes.sol [Line: 2](../tests/2024-05-Sablier/v2-core/src/types/DataTypes.sol#L2)
398 | 
399 | 	```solidity
400 | 	pragma solidity >=0.8.22;
401 | 	```
402 | 
403 | </details>
404 | 
405 | 
406 | 
407 | ## L-5: Large Numeric Literal
408 | 
409 | Large literal values multiples of 10000 can be replaced with scientific notation.Use `e` notation, for example: `1e18`, instead of its full numeric value.
410 | 
411 | <details><summary>2 Found Instances</summary>
412 | 
413 | 
414 | - Found in src/SablierV2NFTDescriptor.sol [Line: 200](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L200)
415 | 
416 | 	```solidity
417 | 	            return streamedAmount * 10_000 / depositedAmount;
418 | 	```
419 | 
420 | - Found in src/libraries/SVGElements.sol [Line: 217](../tests/2024-05-Sablier/v2-core/src/libraries/SVGElements.sol#L217)
421 | 
422 | 	```solidity
423 | 	            (10_000 - progressNumerical).toString(),
424 | 	```
425 | 
426 | </details>
427 | 
428 | 
429 | 
430 | ## L-6: Internal Function Used Only Once
431 | 
432 | Instead of separating the logic into a separate function, consider inlining the logic into the calling function. This can reduce the number of function calls and improve readability.
433 | 
434 | <details><summary>17 Found Instances</summary>
435 | 
436 | 
437 | - Found in src/SablierV2NFTDescriptor.sol [Line: 133](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L133)
438 | 
439 | 	```solidity
440 | 	    function abbreviateAmount(uint256 amount, uint256 decimals) internal pure returns (string memory) {
441 | 	```
442 | 
443 | - Found in src/SablierV2NFTDescriptor.sol [Line: 171](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L171)
444 | 
445 | 	```solidity
446 | 	    function calculateDurationInDays(uint256 startTime, uint256 endTime) internal pure returns (string memory) {
447 | 	```
448 | 
449 | - Found in src/SablierV2NFTDescriptor.sol [Line: 190](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L190)
450 | 
451 | 	```solidity
452 | 	    function calculateStreamedPercentage(
453 | 	```
454 | 
455 | - Found in src/SablierV2NFTDescriptor.sol [Line: 206](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L206)
456 | 
457 | 	```solidity
458 | 	    function generateAccentColor(address sablier, uint256 streamId) internal view returns (string memory) {
459 | 	```
460 | 
461 | - Found in src/SablierV2NFTDescriptor.sol [Line: 240](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L240)
462 | 
463 | 	```solidity
464 | 	    function generateAttributes(
465 | 	```
466 | 
467 | - Found in src/SablierV2NFTDescriptor.sol [Line: 261](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L261)
468 | 
469 | 	```solidity
470 | 	    function generateDescription(
471 | 	```
472 | 
473 | - Found in src/SablierV2NFTDescriptor.sol [Line: 301](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L301)
474 | 
475 | 	```solidity
476 | 	    function generateName(string memory sablierModel, string memory streamId) internal pure returns (string memory) {
477 | 	```
478 | 
479 | - Found in src/SablierV2NFTDescriptor.sol [Line: 307](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L307)
480 | 
481 | 	```solidity
482 | 	    function mapSymbol(IERC721Metadata sablier) internal view returns (string memory) {
483 | 	```
484 | 
485 | - Found in src/SablierV2NFTDescriptor.sol [Line: 322](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L322)
486 | 
487 | 	```solidity
488 | 	    function safeAssetDecimals(address asset) internal view returns (uint8) {
489 | 	```
490 | 
491 | - Found in src/SablierV2NFTDescriptor.sol [Line: 334](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L334)
492 | 
493 | 	```solidity
494 | 	    function safeAssetSymbol(address asset) internal view returns (string memory) {
495 | 	```
496 | 
497 | - Found in src/SablierV2NFTDescriptor.sol [Line: 372](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L372)
498 | 
499 | 	```solidity
500 | 	    function stringifyPercentage(uint256 percentage) internal pure returns (string memory) {
501 | 	```
502 | 
503 | - Found in src/SablierV2NFTDescriptor.sol [Line: 384](../tests/2024-05-Sablier/v2-core/src/SablierV2NFTDescriptor.sol#L384)
504 | 
505 | 	```solidity
506 | 	    function stringifyStatus(Lockup.Status status) internal pure returns (string memory) {
507 | 	```
508 | 
509 | - Found in src/libraries/NFTSVG.sol [Line: 98](../tests/2024-05-Sablier/v2-core/src/libraries/NFTSVG.sol#L98)
510 | 
511 | 	```solidity
512 | 	    function generateDefs(
513 | 	```
514 | 
515 | - Found in src/libraries/NFTSVG.sol [Line: 120](../tests/2024-05-Sablier/v2-core/src/libraries/NFTSVG.sol#L120)
516 | 
517 | 	```solidity
518 | 	    function generateFloatingText(
519 | 	```
520 | 
521 | - Found in src/libraries/NFTSVG.sol [Line: 146](../tests/2024-05-Sablier/v2-core/src/libraries/NFTSVG.sol#L146)
522 | 
523 | 	```solidity
524 | 	    function generateHrefs(
525 | 	```
526 | 
527 | - Found in src/libraries/SVGElements.sol [Line: 78](../tests/2024-05-Sablier/v2-core/src/libraries/SVGElements.sol#L78)
528 | 
529 | 	```solidity
530 | 	    function card(
531 | 	```
532 | 
533 | - Found in src/libraries/SVGElements.sol [Line: 255](../tests/2024-05-Sablier/v2-core/src/libraries/SVGElements.sol#L255)
534 | 
535 | 	```solidity
536 | 	    function stringifyCardType(CardType cardType) internal pure returns (string memory) {
537 | 	```
538 | 
539 | </details>
540 | 
541 | 
542 | 
543 | ## L-7: Loop Contains `require`/`revert`
544 | 
545 | Avoid `require` / `revert` statements in a loop because a single bad item can cause the whole transaction to fail. It's better to forgive on fail and return failed elements post processing of the loop
546 | 
547 | <details><summary>4 Found Instances</summary>
548 | 
549 | 
550 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 277](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L277)
551 | 
552 | 	```solidity
553 | 	        for (uint256 i = 0; i < count; ++i) {
554 | 	```
555 | 
556 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 452](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L452)
557 | 
558 | 	```solidity
559 | 	        for (uint256 i = 0; i < streamIdsCount; ++i) {
560 | 	```
561 | 
562 | - Found in src/libraries/Helpers.sol [Line: 252](../tests/2024-05-Sablier/v2-core/src/libraries/Helpers.sol#L252)
563 | 
564 | 	```solidity
565 | 	        for (uint256 index = 0; index < count; ++index) {
566 | 	```
567 | 
568 | - Found in src/libraries/Helpers.sol [Line: 315](../tests/2024-05-Sablier/v2-core/src/libraries/Helpers.sol#L315)
569 | 
570 | 	```solidity
571 | 	        for (uint256 index = 0; index < count; ++index) {
572 | 	```
573 | 
574 | </details>
575 | 
576 | 
577 | 
578 | ## L-8: Costly operations inside loop
579 | 
580 | Invoking `SSTORE` operations in loops may waste gas. Use a local variable to hold the loop computation result.
581 | 
582 | <details><summary>4 Found Instances</summary>
583 | 
584 | 
585 | - Found in src/SablierV2LockupDynamic.sol [Line: 344](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupDynamic.sol#L344)
586 | 
587 | 	```solidity
588 | 	            for (uint256 i = 0; i < segmentCount; ++i) {
589 | 	```
590 | 
591 | - Found in src/SablierV2LockupTranched.sol [Line: 248](../tests/2024-05-Sablier/v2-core/src/SablierV2LockupTranched.sol#L248)
592 | 
593 | 	```solidity
594 | 	            for (uint256 i = 0; i < trancheCount; ++i) {
595 | 	```
596 | 
597 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 277](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L277)
598 | 
599 | 	```solidity
600 | 	        for (uint256 i = 0; i < count; ++i) {
601 | 	```
602 | 
603 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 452](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L452)
604 | 
605 | 	```solidity
606 | 	        for (uint256 i = 0; i < streamIdsCount; ++i) {
607 | 	```
608 | 
609 | </details>
610 | 
611 | 
612 | 
613 | ## L-9: Unchecked Return
614 | 
615 | Function returns a value but it is ignored. Consider checking the return value.
616 | 
617 | <details><summary>1 Found Instances</summary>
618 | 
619 | 
620 | - Found in src/abstracts/SablierV2Lockup.sol [Line: 211](../tests/2024-05-Sablier/v2-core/src/abstracts/SablierV2Lockup.sol#L211)
621 | 
622 | 	```solidity
623 | 	        _requireOwned({ tokenId: streamId });
624 | 	```
625 | 
626 | </details>
627 | 
628 | 
629 | 
630 | 
```

--------------------------------------------------------------------------------
/aderyn_core/src/detect/detector.rs:
--------------------------------------------------------------------------------

```rust
  1 | use serde::{Deserialize, Serialize};
  2 | use strum::{Display, EnumCount, EnumIter, EnumString};
  3 | 
  4 | use crate::{
  5 |     ast::NodeID,
  6 |     context::workspace::WorkspaceContext,
  7 |     detect::{high::*, low::*},
  8 | };
  9 | 
 10 | use std::{
 11 |     collections::BTreeMap,
 12 |     error::Error,
 13 |     fmt::{self, Display},
 14 |     str::FromStr,
 15 | };
 16 | 
 17 | pub fn get_all_issue_detectors() -> Vec<Box<dyn IssueDetector>> {
 18 |     vec![
 19 |         Box::<DelegatecallInLoopDetector>::default(),
 20 |         Box::<CentralizationRiskDetector>::default(),
 21 |         Box::<SolmateSafeTransferLibDetector>::default(),
 22 |         Box::<AvoidAbiEncodePackedDetector>::default(),
 23 |         Box::<EcrecoverDetector>::default(),
 24 |         Box::<DeprecatedOZFunctionDetector>::default(),
 25 |         Box::<UnsafeERC20OperationDetector>::default(),
 26 |         Box::<UnspecificSolidityPragmaDetector>::default(),
 27 |         Box::<StateNoAddressCheckDetector>::default(),
 28 |         Box::<UnusedPublicFunctionDetector>::default(),
 29 |         Box::<LiteralsInsteadOfConstantsDetector>::default(),
 30 |         Box::<EmptyRequireRevertDetector>::default(),
 31 |         Box::<NonReentrantBeforeOthersDetector>::default(),
 32 |         Box::<BlockTimestampDeadlineDetector>::default(),
 33 |         Box::<UnsafeERC721MintDetector>::default(),
 34 |         Box::<PushZeroOpcodeDetector>::default(),
 35 |         Box::<ArbitraryTransferFromDetector>::default(),
 36 |         Box::<ModifierUsedOnlyOnceDetector>::default(),
 37 |         Box::<EmptyBlockDetector>::default(),
 38 |         Box::<LargeLiteralValueDetector>::default(),
 39 |         Box::<InternalFunctionUsedOnceDetector>::default(),
 40 |         Box::<TodoDetector>::default(),
 41 |         Box::<InconsistentTypeNamesDetector>::default(),
 42 |         Box::<UnprotectedInitializerDetector>::default(),
 43 |         Box::<UnusedErrorDetector>::default(),
 44 |         Box::<RequireRevertInLoopDetector>::default(),
 45 |         Box::<DivisionBeforeMultiplicationDetector>::default(),
 46 |         Box::<UnsafeCastingDetector>::default(),
 47 |         Box::<EnumerableLoopRemovalDetector>::default(),
 48 |         Box::<ExperimentalEncoderDetector>::default(),
 49 |         Box::<IncorrectShiftOrderDetector>::default(),
 50 |         Box::<StorageArrayMemoryEditDetector>::default(),
 51 |         Box::<MultipleConstructorsDetector>::default(),
 52 |         Box::<ReusedContractNameDetector>::default(),
 53 |         Box::<NestedStructInMappingDetector>::default(),
 54 |         Box::<SelfdestructDetector>::default(),
 55 |         Box::<DynamicArrayLengthAssignmentDetector>::default(),
 56 |         Box::<IncorrectUseOfCaretOperatorDetector>::default(),
 57 |         Box::<YulReturnDetector>::default(),
 58 |         Box::<StateVariableShadowingDetector>::default(),
 59 |         Box::<UncheckedSendDetector>::default(),
 60 |         Box::<MisusedBooleanDetector>::default(),
 61 |         Box::<SendEtherNoChecksDetector>::default(),
 62 |         Box::<DelegateCallUncheckedAddressDetector>::default(),
 63 |         Box::<TautologicalCompareDetector>::default(),
 64 |         Box::<RTLODetector>::default(),
 65 |         Box::<DangerousUnaryOperatorDetector>::default(),
 66 |         Box::<TautologyOrContraditionDetector>::default(),
 67 |         Box::<DangerousStrictEqualityOnBalanceDetector>::default(),
 68 |         Box::<StorageSignedIntegerArrayDetector>::default(),
 69 |         Box::<RedundantStatementDetector>::default(),
 70 |         Box::<StateVariableReadExternalDetector>::default(),
 71 |         Box::<WeakRandomnessDetector>::default(),
 72 |         Box::<PreDeclaredLocalVariableUsageDetector>::default(),
 73 |         Box::<DeletionNestedMappingDetector>::default(),
 74 |         Box::<UnusedStateVariablesDetector>::default(),
 75 |         Box::<ConstantFunctionContainsAssemblyDetector>::default(),
 76 |         Box::<BooleanEqualityDetector>::default(),
 77 |         Box::<TxOriginUsedForAuthDetector>::default(),
 78 |         Box::<MsgValueUsedInLoopDetector>::default(),
 79 |         Box::<ContractLocksEtherDetector>::default(),
 80 |         Box::<LocalVariableShadowingDetector>::default(),
 81 |         Box::<IncorrectERC721InterfaceDetector>::default(),
 82 |         Box::<IncorrectERC20InterfaceDetector>::default(),
 83 |         Box::<UninitializedLocalVariableDetector>::default(),
 84 |         Box::<ReturnBombDetector>::default(),
 85 |         Box::<OutOfOrderRetryableDetector>::default(),
 86 |         Box::<FunctionInitializingStateDetector>::default(),
 87 |         Box::<DeadCodeDetector>::default(),
 88 |         Box::<CacheArrayLengthDetector>::default(),
 89 |         Box::<AssertStateChangeDetector>::default(),
 90 |         Box::<CostlyLoopDetector>::default(),
 91 |         Box::<ConstantFunctionChangesStateDetector>::default(),
 92 |         Box::<BuiltinSymbolShadowingDetector>::default(),
 93 |         Box::<VoidConstructorDetector>::default(),
 94 |         Box::<FunctionSelectorCollisionDetector>::default(),
 95 |         Box::<MissingInheritanceDetector>::default(),
 96 |         Box::<UnusedImportDetector>::default(),
 97 |         Box::<UncheckedLowLevelCallDetector>::default(),
 98 |         Box::<FunctionPointerInConstructorDetector>::default(),
 99 |         Box::<StateVariableCouldBeConstantDetector>::default(),
100 |         Box::<StateVariableChangesWithoutEventDetector>::default(),
101 |         Box::<StateVariableCouldBeImmutableDetector>::default(),
102 |         Box::<MultiplePlaceholdersDetector>::default(),
103 |         Box::<ReentrancyStateChangeDetector>::default(),
104 |         Box::<IncorrectUseOfModifierDetector>::default(),
105 |         Box::<UncheckedReturnDetector>::default(),
106 |     ]
107 | }
108 | 
109 | pub fn get_all_detectors_names() -> Vec<String> {
110 |     get_all_issue_detectors().iter().map(|d| d.name()).collect()
111 | }
112 | 
113 | // Note to maintainers: DO NOT CHANGE THE ORDER OF THESE DERIVE ATTRIBUTES
114 | #[derive(Debug, PartialEq, EnumString, Display)]
115 | #[strum(serialize_all = "kebab-case")]
116 | pub enum IssueDetectorNamePool {
117 |     IncorrectUseOfModifier,
118 |     ReentrancyStateChange,
119 |     StateVariableCouldBeImmutable,
120 |     MultiplePlaceholders,
121 |     StateChangeWithoutEvent,
122 |     MissingInheritance,
123 |     UnusedImport,
124 |     VoidConstructor,
125 |     UncheckedLowLevelCall,
126 |     FunctionPointerInConstructor,
127 |     DeadCode,
128 |     FunctionSelectorCollision,
129 |     StorageArrayLengthNotCached,
130 |     AssertStateChange,
131 |     CostlyLoop,
132 |     ConstantFunctionChangesState,
133 |     BuiltinSymbolShadowing,
134 |     IncorrectERC721Interface,
135 |     FunctionInitializingState,
136 |     DelegatecallInLoop,
137 |     CentralizationRisk,
138 |     SolmateSafeTransferLib,
139 |     AbiEncodePackedHashCollision,
140 |     Ecrecover,
141 |     DeprecatedOzFunction,
142 |     UnsafeERC20Operation,
143 |     UnspecificSolidityPragma,
144 |     StateNoAddressCheck,
145 |     UnusedPublicFunction,
146 |     EmptyRequireRevert,
147 |     NonReentrantNotFirst,
148 |     BlockTimestampDeadline,
149 |     LiteralInsteadOfConstant,
150 |     UnsafeOzERC721Mint,
151 |     PushZeroOpcode,
152 |     ArbitraryTransferFrom,
153 |     ModifierUsedOnlyOnce,
154 |     UnusedError,
155 |     LargeNumericLiteral,
156 |     InternalFunctionUsedOnce,
157 |     EmptyBlock,
158 |     Todo,
159 |     InconsistentTypeNames,
160 |     UnprotectedInitializer,
161 |     RequireRevertInLoop,
162 |     DivisionBeforeMultiplication,
163 |     UnsafeCasting,
164 |     EnumerableLoopRemoval,
165 |     ExperimentalEncoder,
166 |     IncorrectShiftOrder,
167 |     StorageArrayMemoryEdit,
168 |     MultipleConstructors,
169 |     ReusedContractName,
170 |     NestedStructInMapping,
171 |     Selfdestruct,
172 |     DynamicArrayLengthAssignment,
173 |     IncorrectCaretOperator,
174 |     YulReturn,
175 |     StateVariableShadowing,
176 |     UncheckedSend,
177 |     MisusedBoolean,
178 |     EthSendUncheckedAddress,
179 |     DelegateCallUncheckedAddress,
180 |     TautologicalCompare,
181 |     #[allow(clippy::upper_case_acronyms)]
182 |     RTLO,
183 |     UncheckedReturn,
184 |     DangerousUnaryOperator,
185 |     TautologyOrContradiction,
186 |     StrictEqualityContractBalance,
187 |     SignedIntegerStorageArray,
188 |     RedundantStatement,
189 |     StateVariableReadExternal,
190 |     WeakRandomness,
191 |     PreDeclaredLocalVariableUsage,
192 |     DeleteNestedMapping,
193 |     UnusedStateVariable,
194 |     ConstantFunctionContainsAssembly,
195 |     BooleanEquality,
196 |     TxOriginUsedForAuth,
197 |     MsgValueInLoop,
198 |     ContractLocksEther,
199 |     LocalVariableShadowing,
200 |     IncorrectERC20Interface,
201 |     UninitializedLocalVariable,
202 |     ReturnBomb,
203 |     OutOfOrderRetryable,
204 |     StateVariableCouldBeConstant,
205 |     // NOTE: `Undecided` will be the default name (for new bots).
206 |     // If it's accepted, a new variant will be added to this enum before normalizing it in aderyn
207 |     Undecided,
208 | }
209 | 
210 | pub fn request_issue_detector_by_name(detector_name: &str) -> Option<Box<dyn IssueDetector>> {
211 |     // Expects a valid detector_name
212 |     let detector_name = IssueDetectorNamePool::from_str(detector_name).ok()?;
213 |     match detector_name {
214 |         IssueDetectorNamePool::ReentrancyStateChange => {
215 |             Some(Box::<ReentrancyStateChangeDetector>::default())
216 |         }
217 |         IssueDetectorNamePool::IncorrectUseOfModifier => {
218 |             Some(Box::<IncorrectUseOfModifierDetector>::default())
219 |         }
220 |         IssueDetectorNamePool::StateVariableCouldBeImmutable => {
221 |             Some(Box::<StateVariableCouldBeImmutableDetector>::default())
222 |         }
223 |         IssueDetectorNamePool::MultiplePlaceholders => {
224 |             Some(Box::<MultiplePlaceholdersDetector>::default())
225 |         }
226 |         IssueDetectorNamePool::StateChangeWithoutEvent => {
227 |             Some(Box::<StateVariableChangesWithoutEventDetector>::default())
228 |         }
229 |         IssueDetectorNamePool::MissingInheritance => {
230 |             Some(Box::<MissingInheritanceDetector>::default())
231 |         }
232 |         IssueDetectorNamePool::LocalVariableShadowing => {
233 |             Some(Box::<LocalVariableShadowingDetector>::default())
234 |         }
235 |         IssueDetectorNamePool::UnusedImport => Some(Box::<UnusedImportDetector>::default()),
236 |         IssueDetectorNamePool::VoidConstructor => Some(Box::<VoidConstructorDetector>::default()),
237 |         IssueDetectorNamePool::StateVariableCouldBeConstant => {
238 |             Some(Box::<StateVariableCouldBeConstantDetector>::default())
239 |         }
240 |         IssueDetectorNamePool::LiteralInsteadOfConstant => {
241 |             Some(Box::<LiteralsInsteadOfConstantsDetector>::default())
242 |         }
243 |         IssueDetectorNamePool::FunctionPointerInConstructor => {
244 |             Some(Box::<FunctionPointerInConstructorDetector>::default())
245 |         }
246 |         IssueDetectorNamePool::DeadCode => Some(Box::<DeadCodeDetector>::default()),
247 |         IssueDetectorNamePool::FunctionSelectorCollision => {
248 |             Some(Box::<FunctionSelectorCollisionDetector>::default())
249 |         }
250 |         IssueDetectorNamePool::StorageArrayLengthNotCached => {
251 |             Some(Box::<CacheArrayLengthDetector>::default())
252 |         }
253 |         IssueDetectorNamePool::AssertStateChange => {
254 |             Some(Box::<AssertStateChangeDetector>::default())
255 |         }
256 |         IssueDetectorNamePool::CostlyLoop => Some(Box::<CostlyLoopDetector>::default()),
257 |         IssueDetectorNamePool::ConstantFunctionChangesState => {
258 |             Some(Box::<ConstantFunctionChangesStateDetector>::default())
259 |         }
260 |         IssueDetectorNamePool::BuiltinSymbolShadowing => {
261 |             Some(Box::<BuiltinSymbolShadowingDetector>::default())
262 |         }
263 |         IssueDetectorNamePool::IncorrectERC721Interface => {
264 |             Some(Box::<IncorrectERC721InterfaceDetector>::default())
265 |         }
266 |         IssueDetectorNamePool::OutOfOrderRetryable => {
267 |             Some(Box::<OutOfOrderRetryableDetector>::default())
268 |         }
269 |         IssueDetectorNamePool::FunctionInitializingState => {
270 |             Some(Box::<FunctionInitializingStateDetector>::default())
271 |         }
272 |         IssueDetectorNamePool::IncorrectERC20Interface => {
273 |             Some(Box::<IncorrectERC20InterfaceDetector>::default())
274 |         }
275 |         IssueDetectorNamePool::UninitializedLocalVariable => {
276 |             Some(Box::<UninitializedLocalVariableDetector>::default())
277 |         }
278 |         IssueDetectorNamePool::ReturnBomb => Some(Box::<ReturnBombDetector>::default()),
279 |         IssueDetectorNamePool::UnusedStateVariable => {
280 |             Some(Box::<UnusedStateVariablesDetector>::default())
281 |         }
282 |         IssueDetectorNamePool::DelegatecallInLoop => {
283 |             Some(Box::<DelegatecallInLoopDetector>::default())
284 |         }
285 |         IssueDetectorNamePool::CentralizationRisk => {
286 |             Some(Box::<CentralizationRiskDetector>::default())
287 |         }
288 |         IssueDetectorNamePool::SolmateSafeTransferLib => {
289 |             Some(Box::<SolmateSafeTransferLibDetector>::default())
290 |         }
291 |         IssueDetectorNamePool::AbiEncodePackedHashCollision => {
292 |             Some(Box::<AvoidAbiEncodePackedDetector>::default())
293 |         }
294 |         IssueDetectorNamePool::Ecrecover => Some(Box::<EcrecoverDetector>::default()),
295 |         IssueDetectorNamePool::DeprecatedOzFunction => {
296 |             Some(Box::<DeprecatedOZFunctionDetector>::default())
297 |         }
298 |         IssueDetectorNamePool::UnsafeERC20Operation => {
299 |             Some(Box::<UnsafeERC20OperationDetector>::default())
300 |         }
301 |         IssueDetectorNamePool::UnspecificSolidityPragma => {
302 |             Some(Box::<UnspecificSolidityPragmaDetector>::default())
303 |         }
304 |         IssueDetectorNamePool::StateNoAddressCheck => {
305 |             Some(Box::<StateNoAddressCheckDetector>::default())
306 |         }
307 |         IssueDetectorNamePool::UnusedPublicFunction => {
308 |             Some(Box::<UnusedPublicFunctionDetector>::default())
309 |         }
310 |         IssueDetectorNamePool::EmptyRequireRevert => {
311 |             Some(Box::<EmptyRequireRevertDetector>::default())
312 |         }
313 |         IssueDetectorNamePool::NonReentrantNotFirst => {
314 |             Some(Box::<NonReentrantBeforeOthersDetector>::default())
315 |         }
316 |         IssueDetectorNamePool::BlockTimestampDeadline => {
317 |             Some(Box::<BlockTimestampDeadlineDetector>::default())
318 |         }
319 |         IssueDetectorNamePool::UnsafeOzERC721Mint => {
320 |             Some(Box::<UnsafeERC721MintDetector>::default())
321 |         }
322 |         IssueDetectorNamePool::PushZeroOpcode => Some(Box::<PushZeroOpcodeDetector>::default()),
323 |         IssueDetectorNamePool::ArbitraryTransferFrom => {
324 |             Some(Box::<ArbitraryTransferFromDetector>::default())
325 |         }
326 |         IssueDetectorNamePool::ModifierUsedOnlyOnce => {
327 |             Some(Box::<ModifierUsedOnlyOnceDetector>::default())
328 |         }
329 |         IssueDetectorNamePool::LargeNumericLiteral => {
330 |             Some(Box::<LargeLiteralValueDetector>::default())
331 |         }
332 |         IssueDetectorNamePool::InternalFunctionUsedOnce => {
333 |             Some(Box::<InternalFunctionUsedOnceDetector>::default())
334 |         }
335 |         IssueDetectorNamePool::EmptyBlock => Some(Box::<EmptyBlockDetector>::default()),
336 |         IssueDetectorNamePool::Todo => Some(Box::<TodoDetector>::default()),
337 |         IssueDetectorNamePool::InconsistentTypeNames => {
338 |             Some(Box::<InconsistentTypeNamesDetector>::default())
339 |         }
340 |         IssueDetectorNamePool::UnprotectedInitializer => {
341 |             Some(Box::<UnprotectedInitializerDetector>::default())
342 |         }
343 |         IssueDetectorNamePool::RequireRevertInLoop => {
344 |             Some(Box::<RequireRevertInLoopDetector>::default())
345 |         }
346 |         IssueDetectorNamePool::UnusedError => Some(Box::<UnusedErrorDetector>::default()),
347 |         IssueDetectorNamePool::DivisionBeforeMultiplication => {
348 |             Some(Box::<DivisionBeforeMultiplicationDetector>::default())
349 |         }
350 |         IssueDetectorNamePool::UnsafeCasting => Some(Box::<UnsafeCastingDetector>::default()),
351 |         IssueDetectorNamePool::EnumerableLoopRemoval => {
352 |             Some(Box::<EnumerableLoopRemovalDetector>::default())
353 |         }
354 |         IssueDetectorNamePool::ExperimentalEncoder => {
355 |             Some(Box::<ExperimentalEncoderDetector>::default())
356 |         }
357 |         IssueDetectorNamePool::IncorrectShiftOrder => {
358 |             Some(Box::<IncorrectShiftOrderDetector>::default())
359 |         }
360 |         IssueDetectorNamePool::StorageArrayMemoryEdit => {
361 |             Some(Box::<StorageArrayMemoryEditDetector>::default())
362 |         }
363 |         IssueDetectorNamePool::MultipleConstructors => {
364 |             Some(Box::<MultipleConstructorsDetector>::default())
365 |         }
366 |         IssueDetectorNamePool::ReusedContractName => {
367 |             Some(Box::<ReusedContractNameDetector>::default())
368 |         }
369 |         IssueDetectorNamePool::NestedStructInMapping => {
370 |             Some(Box::<NestedStructInMappingDetector>::default())
371 |         }
372 |         IssueDetectorNamePool::Selfdestruct => Some(Box::<SelfdestructDetector>::default()),
373 |         IssueDetectorNamePool::DynamicArrayLengthAssignment => {
374 |             Some(Box::<DynamicArrayLengthAssignmentDetector>::default())
375 |         }
376 | 
377 |         IssueDetectorNamePool::IncorrectCaretOperator => {
378 |             Some(Box::<IncorrectUseOfCaretOperatorDetector>::default())
379 |         }
380 |         IssueDetectorNamePool::YulReturn => Some(Box::<YulReturnDetector>::default()),
381 |         IssueDetectorNamePool::StateVariableShadowing => {
382 |             Some(Box::<StateVariableShadowingDetector>::default())
383 |         }
384 |         IssueDetectorNamePool::UncheckedSend => Some(Box::<UncheckedSendDetector>::default()),
385 |         IssueDetectorNamePool::MisusedBoolean => Some(Box::<MisusedBooleanDetector>::default()),
386 |         IssueDetectorNamePool::EthSendUncheckedAddress => {
387 |             Some(Box::<SendEtherNoChecksDetector>::default())
388 |         }
389 |         IssueDetectorNamePool::DelegateCallUncheckedAddress => {
390 |             Some(Box::<DelegateCallUncheckedAddressDetector>::default())
391 |         }
392 |         IssueDetectorNamePool::TautologicalCompare => {
393 |             Some(Box::<TautologicalCompareDetector>::default())
394 |         }
395 |         IssueDetectorNamePool::RTLO => Some(Box::<RTLODetector>::default()),
396 |         IssueDetectorNamePool::UncheckedReturn => Some(Box::<UncheckedReturnDetector>::default()),
397 |         IssueDetectorNamePool::DangerousUnaryOperator => {
398 |             Some(Box::<DangerousUnaryOperatorDetector>::default())
399 |         }
400 |         IssueDetectorNamePool::TautologyOrContradiction => {
401 |             Some(Box::<TautologyOrContraditionDetector>::default())
402 |         }
403 |         IssueDetectorNamePool::StrictEqualityContractBalance => {
404 |             Some(Box::<DangerousStrictEqualityOnBalanceDetector>::default())
405 |         }
406 |         IssueDetectorNamePool::SignedIntegerStorageArray => {
407 |             Some(Box::<StorageSignedIntegerArrayDetector>::default())
408 |         }
409 |         IssueDetectorNamePool::RedundantStatement => {
410 |             Some(Box::<RedundantStatementDetector>::default())
411 |         }
412 |         IssueDetectorNamePool::StateVariableReadExternal => {
413 |             Some(Box::<StateVariableReadExternalDetector>::default())
414 |         }
415 |         IssueDetectorNamePool::WeakRandomness => Some(Box::<WeakRandomnessDetector>::default()),
416 |         IssueDetectorNamePool::PreDeclaredLocalVariableUsage => {
417 |             Some(Box::<PreDeclaredLocalVariableUsageDetector>::default())
418 |         }
419 |         IssueDetectorNamePool::DeleteNestedMapping => {
420 |             Some(Box::<DeletionNestedMappingDetector>::default())
421 |         }
422 |         IssueDetectorNamePool::ConstantFunctionContainsAssembly => {
423 |             Some(Box::<ConstantFunctionContainsAssemblyDetector>::default())
424 |         }
425 |         IssueDetectorNamePool::BooleanEquality => Some(Box::<BooleanEqualityDetector>::default()),
426 |         IssueDetectorNamePool::TxOriginUsedForAuth => {
427 |             Some(Box::<TxOriginUsedForAuthDetector>::default())
428 |         }
429 |         IssueDetectorNamePool::MsgValueInLoop => Some(Box::<MsgValueUsedInLoopDetector>::default()),
430 |         IssueDetectorNamePool::ContractLocksEther => {
431 |             Some(Box::<ContractLocksEtherDetector>::default())
432 |         }
433 |         IssueDetectorNamePool::UncheckedLowLevelCall => {
434 |             Some(Box::<UncheckedLowLevelCallDetector>::default())
435 |         }
436 |         IssueDetectorNamePool::Undecided => None,
437 |     }
438 | }
439 | 
440 | pub fn get_issue_detector_by_name(detector_name: &str) -> Box<dyn IssueDetector> {
441 |     request_issue_detector_by_name(detector_name).unwrap()
442 | }
443 | 
444 | #[derive(Debug, PartialEq, Serialize, Deserialize, EnumCount, Clone, EnumIter)]
445 | pub enum IssueSeverity {
446 |     Low,
447 |     High,
448 | }
449 | 
450 | impl Display for IssueSeverity {
451 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
452 |         let issue_description = match self {
453 |             IssueSeverity::Low => "Low",
454 |             IssueSeverity::High => "High",
455 |         };
456 |         write!(f, "{}", issue_description).unwrap();
457 |         Ok(())
458 |     }
459 | }
460 | 
461 | impl dyn IssueDetector {
462 |     pub fn skeletal_clone(&self) -> Box<dyn IssueDetector> {
463 |         request_issue_detector_by_name(self.name().as_str()).unwrap()
464 |     }
465 | }
466 | 
467 | pub trait IssueDetector: Send + Sync + 'static {
468 |     fn detect(&mut self, _context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
469 |         Ok(true)
470 |     }
471 | 
472 |     fn severity(&self) -> IssueSeverity {
473 |         IssueSeverity::High
474 |     }
475 | 
476 |     fn title(&self) -> String {
477 |         String::from("Title")
478 |     }
479 | 
480 |     fn description(&self) -> String {
481 |         String::from("Description")
482 |     }
483 | 
484 |     fn name(&self) -> String {
485 |         format!("{}", IssueDetectorNamePool::Undecided)
486 |     }
487 | 
488 |     // Keys are source file name, line number and source location
489 |     // Value is ASTNode NodeID
490 |     fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
491 |         BTreeMap::new()
492 |     }
493 | 
494 |     fn hints(&self) -> BTreeMap<(String, usize, String), String> {
495 |         BTreeMap::new()
496 |     }
497 | }
498 | 
```

--------------------------------------------------------------------------------
/aderyn_core/src/detect/high/tautology_or_contradiction.rs:
--------------------------------------------------------------------------------

```rust
  1 | use std::{collections::BTreeMap, error::Error};
  2 | 
  3 | use crate::ast::{BinaryOperation, NodeID, TypeDescriptions};
  4 | 
  5 | use crate::{
  6 |     capture,
  7 |     context::workspace::WorkspaceContext,
  8 |     detect::{
  9 |         detector::{IssueDetector, IssueDetectorNamePool, IssueSeverity},
 10 |         helpers::get_literal_value_or_constant_variable_value,
 11 |     },
 12 | };
 13 | use eyre::Result;
 14 | use solidity_integer_helper::{
 15 |     does_operation_make_sense_with_lhs_value, does_operation_make_sense_with_rhs_value,
 16 | };
 17 | 
 18 | #[derive(Default)]
 19 | pub struct TautologyOrContraditionDetector {
 20 |     // Keys are: [0] source file name, [1] line number, [2] character location of node.
 21 |     // Do not add items manually, use `capture!` to add nodes to this BTreeMap.
 22 |     found_instances: BTreeMap<(String, usize, String), NodeID>,
 23 | }
 24 | 
 25 | impl IssueDetector for TautologyOrContraditionDetector {
 26 |     fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
 27 |         for binary_operation in context.binary_operations() {
 28 |             if let Some(is_tautlogy_or_contradiction) =
 29 |                 binary_operation.is_tautology_or_contradiction(context)
 30 |                 && is_tautlogy_or_contradiction
 31 |             {
 32 |                 capture!(self, context, binary_operation);
 33 |             }
 34 |         }
 35 | 
 36 |         Ok(!self.found_instances.is_empty())
 37 |     }
 38 | 
 39 |     fn severity(&self) -> IssueSeverity {
 40 |         IssueSeverity::High
 41 |     }
 42 | 
 43 |     fn title(&self) -> String {
 44 |         String::from("Tautology or Contradiction in comparison")
 45 |     }
 46 | 
 47 |     fn description(&self) -> String {
 48 |         String::from(
 49 |             "The condition has been determined to be either always true or always false due to the integer range in which we're operating.",
 50 |         )
 51 |     }
 52 | 
 53 |     fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
 54 |         self.found_instances.clone()
 55 |     }
 56 | 
 57 |     fn name(&self) -> String {
 58 |         IssueDetectorNamePool::TautologyOrContradiction.to_string()
 59 |     }
 60 | }
 61 | 
 62 | #[cfg(test)]
 63 | mod tautology_or_contradiction_tests {
 64 | 
 65 |     use crate::detect::{
 66 |         detector::IssueDetector, high::tautology_or_contradiction::TautologyOrContraditionDetector,
 67 |     };
 68 | 
 69 |     #[test]
 70 | 
 71 |     fn test_tautology_or_contradiction_detector() {
 72 |         let context = crate::detect::test_utils::load_solidity_source_unit(
 73 |             "../tests/contract-playground/src/TautologyOrContradiction.sol",
 74 |         );
 75 | 
 76 |         let mut detector = TautologyOrContraditionDetector::default();
 77 |         let found = detector.detect(&context).unwrap();
 78 |         assert!(found);
 79 |         assert_eq!(detector.instances().len(), 2);
 80 |     }
 81 | }
 82 | 
 83 | pub trait OperationIsTautologyOrContradiction {
 84 |     fn is_tautology_or_contradiction(&self, context: &WorkspaceContext) -> Option<bool>;
 85 | }
 86 | 
 87 | impl OperationIsTautologyOrContradiction for BinaryOperation {
 88 |     fn is_tautology_or_contradiction(&self, context: &WorkspaceContext) -> Option<bool> {
 89 |         if let (
 90 |             Some(TypeDescriptions { type_string: Some(lhs_type_string), .. }),
 91 |             Some(TypeDescriptions { type_string: Some(rhs_type_string), .. }),
 92 |             operator,
 93 |         ) = (
 94 |             self.left_expression.as_ref().type_descriptions(),
 95 |             self.right_expression.as_ref().type_descriptions(),
 96 |             self.operator.clone(),
 97 |         ) {
 98 |             let supported_operators = [">", ">=", "<", "<="];
 99 |             if supported_operators.into_iter().all(|op| op != operator) {
100 |                 return None;
101 |             }
102 | 
103 |             if let Some(lhs_value) = get_literal_value_or_constant_variable_value(
104 |                 self.left_expression.get_node_id()?,
105 |                 context,
106 |             ) && let Some(makes_sense) =
107 |                 does_operation_make_sense_with_lhs_value(&lhs_value, &operator, rhs_type_string)
108 |                 && !makes_sense
109 |             {
110 |                 return Some(true);
111 |             }
112 | 
113 |             if let Some(rhs_value) = get_literal_value_or_constant_variable_value(
114 |                 self.right_expression.get_node_id()?,
115 |                 context,
116 |             ) && let Some(makes_sense) =
117 |                 does_operation_make_sense_with_rhs_value(lhs_type_string, &operator, &rhs_value)
118 |                 && !makes_sense
119 |             {
120 |                 return Some(true);
121 |             }
122 |         }
123 | 
124 |         None
125 |     }
126 | }
127 | 
128 | pub mod solidity_integer_helper {
129 |     use num_bigint::BigInt;
130 |     use num_traits::One;
131 |     use std::{error::Error, ops::Neg};
132 | 
133 |     /// This data type is big enough to handle the extreme values of uint256 and int256
134 |     /// (Tests below)
135 |     #[derive(PartialEq, Debug, Clone)]
136 |     pub struct SolidityNumberRange {
137 |         min_val: BigInt,
138 |         max_val: BigInt,
139 |     }
140 | 
141 |     impl SolidityNumberRange {
142 |         fn fully_contains(&self, other_solidity_number_range: &SolidityNumberRange) -> bool {
143 |             (self.min_val <= other_solidity_number_range.min_val)
144 |                 && (self.max_val >= other_solidity_number_range.max_val)
145 |         }
146 | 
147 |         fn fully_excludes(&self, other_solidity_number_range: &SolidityNumberRange) -> bool {
148 |             (other_solidity_number_range.max_val < self.min_val)
149 |                 || (other_solidity_number_range.min_val > self.max_val)
150 |         }
151 |     }
152 | 
153 |     /// Does this make sense? (boolean answer)
154 |     /// ```no_code
155 |     ///     if(?uintX, operator, value)
156 |     /// ```
157 |     ///
158 |     /// Example (ways to call this function)
159 |     ///
160 |     /// Say x is uint8:
161 |     /// Then, when we come across a binary operation like follows:
162 |     ///     x >= 300
163 |     /// we can determine if it makes sense by calling this function
164 |     ///     does_operation_make_sense_with_rhs_value("uint8", ">=", "300")
165 |     ///
166 |     /// This function checks for the range of integer values of uint8 and returns true if it is
167 |     /// neither a tautology nor a contradiction.
168 |     ///
169 |     /// Here, I define tautology as the condition where the range Ex: (>=300) FULLY COVERS the Range
170 |     /// of Uint8 Contradiction: When the range Ex:(>=300) fully excludes the Range of Uint8
171 |     ///
172 |     /// Notice how in the above example, the value is on the right hand side.
173 |     /// Hence this function is called "does_...rhs_value".
174 |     pub fn does_operation_make_sense_with_rhs_value(
175 |         type_string: &str,
176 |         operator: &str,
177 |         value: &str,
178 |     ) -> Option<bool> {
179 |         let allowed_range = get_range_for_type_string(type_string).ok()?;
180 |         let allowed_min_val = allowed_range.min_val.clone();
181 |         let allowed_max_val = allowed_range.max_val.clone();
182 | 
183 |         let value_as_big_int = BigInt::parse_bytes(value.as_bytes(), 10)?;
184 | 
185 |         // First and foremost if the value is out of range it's 100% either a tautology or a
186 |         // contradiction. Hence, return false.
187 |         if value_as_big_int < allowed_min_val || value_as_big_int > allowed_max_val {
188 |             return Some(false);
189 |         }
190 |         // At this point, we know that the value we are comparing to, is in the allowed range.
191 |         // Now, we can get the represented range, and see if it fully contains the allowed range
192 |         // (tatutology) or fully excludes the allowed range (contradiction)
193 |         let represented_range = {
194 |             match operator {
195 |                 ">=" => Some(SolidityNumberRange {
196 |                     min_val: value_as_big_int.clone(),
197 |                     max_val: allowed_max_val.clone(),
198 |                 }),
199 |                 ">" => Some(SolidityNumberRange {
200 |                     min_val: value_as_big_int.clone() + BigInt::one(),
201 |                     max_val: allowed_max_val.clone(),
202 |                 }),
203 |                 "<=" => Some(SolidityNumberRange {
204 |                     min_val: allowed_min_val.clone(),
205 |                     max_val: value_as_big_int.clone(),
206 |                 }),
207 |                 "<" => Some(SolidityNumberRange {
208 |                     min_val: allowed_min_val.clone(),
209 |                     max_val: value_as_big_int.clone() - BigInt::one(),
210 |                 }),
211 |                 &_ => None,
212 |             }
213 |         };
214 | 
215 |         if let Some(represented_range) = represented_range {
216 |             return Some(
217 |                 !(represented_range.fully_contains(&allowed_range)
218 |                     || represented_range.fully_excludes(&allowed_range)),
219 |             );
220 |         }
221 | 
222 |         None
223 |     }
224 | 
225 |     /// Does this make sense? (boolean answer)
226 |     /// ```no_code
227 |     ///     if(value, operator, uint8?)
228 |     /// ```
229 |     ///
230 |     /// Take advantage of the above method by reusing code
231 |     ///
232 |     /// Example (ways to call this function)
233 |     ///
234 |     /// Say x is uint8:
235 |     /// Then, when we come across a binary operation like follows:
236 |     ///     300 >= x
237 |     /// we can determine if it makes sense by calling this function
238 |     ///     does_operation_make_sense_with_lhs_value("300", ">=", "uint8")
239 |     ///
240 |     /// Notice, here the value 300 is on the left hand side.
241 |     pub fn does_operation_make_sense_with_lhs_value(
242 |         value: &str,
243 |         operator: &str,
244 |         type_string: &str,
245 |     ) -> Option<bool> {
246 |         let inverse_operator = {
247 |             match operator {
248 |                 ">=" => Some("<="),
249 |                 "<=" => Some(">="),
250 |                 ">" => Some("<"),
251 |                 "<" => Some(">"),
252 |                 _ => None,
253 |             }
254 |         }?;
255 |         does_operation_make_sense_with_rhs_value(type_string, inverse_operator, value)
256 |     }
257 | 
258 |     /// Accept the type string to calculate the range.
259 |     pub fn get_range_for_type_string(
260 |         type_string: &str,
261 |     ) -> Result<SolidityNumberRange, Box<dyn Error>> {
262 |         if type_string.starts_with("uint") {
263 |             if let Some((_, num_of_bits)) = &type_string.split_once("uint") {
264 |                 let num_of_bits = num_of_bits.parse::<u32>()?;
265 |                 return Ok(SolidityNumberRange {
266 |                     min_val: find_uint_min(num_of_bits),
267 |                     max_val: find_uint_max(num_of_bits),
268 |                 });
269 |             }
270 |         } else if type_string.starts_with("int")
271 |             && let Some((_, num_of_bits)) = &type_string.split_once("int")
272 |         {
273 |             let num_of_bits = num_of_bits.parse::<u32>()?;
274 |             return Ok(SolidityNumberRange {
275 |                 min_val: find_int_min(num_of_bits),
276 |                 max_val: find_int_max(num_of_bits),
277 |             });
278 |         }
279 |         Err("Invalid type string provided!".into())
280 |     }
281 | 
282 |     // Helpers to calculate min and max for uint types like uint8, uint16, uint24, and so on . . .
283 | 
284 |     fn find_uint_max(num_of_bits: u32) -> BigInt {
285 |         BigInt::parse_bytes(b"2", 10).unwrap().pow(num_of_bits) - BigInt::one()
286 |     }
287 | 
288 |     fn find_uint_min(_: u32) -> BigInt {
289 |         BigInt::ZERO
290 |     }
291 | 
292 |     // Helpers to calculate min and max for int types like int8, int16, int24, and so on . . .
293 | 
294 |     fn find_int_max(num_of_bits: u32) -> BigInt {
295 |         BigInt::parse_bytes(b"2", 10).unwrap().pow(num_of_bits - 1) - BigInt::one()
296 |     }
297 | 
298 |     fn find_int_min(num_of_bits: u32) -> BigInt {
299 |         BigInt::parse_bytes(b"2", 10).unwrap().pow(num_of_bits - 1).neg()
300 |     }
301 | 
302 |     #[cfg(test)]
303 |     mod test_num_bigint_primitives {
304 | 
305 |         use std::ops::Neg;
306 | 
307 |         use num_bigint::BigInt;
308 |         use num_traits::{FromPrimitive, One};
309 | 
310 |         use crate::detect::high::tautology_or_contradiction::solidity_integer_helper::{
311 |             does_operation_make_sense_with_rhs_value, find_int_max, find_int_min, find_uint_max,
312 |         };
313 | 
314 |         use super::{
315 |             SolidityNumberRange, does_operation_make_sense_with_lhs_value,
316 |             get_range_for_type_string,
317 |         };
318 | 
319 |         /*
320 |             Tests to ensure that num_bigint crate holds the capacity to work with numbers
321 |             in the range that Solidity language operates in.
322 |         */
323 | 
324 |         #[test]
325 |         fn test_2_raised_to_3() {
326 |             let two_raised_to_three = BigInt::parse_bytes(b"2", 10).unwrap().pow(3);
327 |             assert_eq!(two_raised_to_three, BigInt::from_u8(8).unwrap());
328 |         }
329 | 
330 |         #[test]
331 |         fn can_find_max_of_uint256() {
332 |             // This test shows that we can calculate the biggest possible number in Solidity for
333 |             // uint which is 2^256 - 1.
334 |             // hence we conclude that because we can represent 2^256 - 1, we can easily cover all
335 |             // the smaller variants of uint that is uint8, uint16, .... all the ay upto uint256
336 |             // because they are lesser than 2^256 - 1
337 |             let uint256_max = BigInt::parse_bytes(b"2", 10).unwrap().pow(256) - BigInt::one();
338 |             assert_eq!(
339 |                 uint256_max,
340 |                 BigInt::parse_bytes(
341 |                     b"115792089237316195423570985008687907853269984665640564039457584007913129639935",
342 |                     10
343 |                 )
344 |                 .unwrap()
345 |             );
346 |         }
347 | 
348 |         #[test]
349 |         fn can_find_min_of_int256() {
350 |             let int_256_min = BigInt::parse_bytes(b"2", 10).unwrap().pow(255).neg();
351 |             assert_eq!(
352 |                 int_256_min,
353 |                 BigInt::parse_bytes(
354 |                     b"-57896044618658097711785492504343953926634992332820282019728792003956564819968",
355 |                     10
356 |                 )
357 |                 .unwrap()
358 |             );
359 |         }
360 | 
361 |         #[test]
362 |         fn can_find_max_of_int256() {
363 |             let int_256_max = BigInt::parse_bytes(b"2", 10).unwrap().pow(255) - BigInt::one();
364 |             assert_eq!(
365 |                 int_256_max,
366 |                 BigInt::parse_bytes(
367 |                     b"57896044618658097711785492504343953926634992332820282019728792003956564819967",
368 |                     10
369 |                 )
370 |                 .unwrap()
371 |             );
372 |         }
373 | 
374 |         /*
375 |             Tests that our helper methods work which will ensure that min and max value can be calculated
376 |             for every bit range from 0 to 256 .
377 |         */
378 | 
379 |         #[test]
380 |         fn helper_method_can_find_max_of_uint256() {
381 |             let uint256_max = find_uint_max(256);
382 |             assert_eq!(
383 |                 uint256_max,
384 |                 BigInt::parse_bytes(
385 |                     b"115792089237316195423570985008687907853269984665640564039457584007913129639935",
386 |                     10
387 |                 )
388 |                 .unwrap()
389 |             );
390 |         }
391 | 
392 |         #[test]
393 |         fn helper_method_can_find_min_of_int256() {
394 |             let int_256_min = find_int_min(256);
395 |             assert_eq!(
396 |                 int_256_min,
397 |                 BigInt::parse_bytes(
398 |                     b"-57896044618658097711785492504343953926634992332820282019728792003956564819968",
399 |                     10
400 |                 )
401 |                 .unwrap()
402 |             );
403 |         }
404 | 
405 |         #[test]
406 |         fn helper_method_can_find_max_of_int256() {
407 |             let int_256_max = find_int_max(256);
408 |             assert_eq!(
409 |                 int_256_max,
410 |                 BigInt::parse_bytes(
411 |                     b"57896044618658097711785492504343953926634992332820282019728792003956564819967",
412 |                     10
413 |                 )
414 |                 .unwrap()
415 |             );
416 |         }
417 | 
418 |         #[test]
419 |         fn helper_method_can_find_range_for_int176() {
420 |             let actual_range = get_range_for_type_string("int176").unwrap();
421 |             let expected_range = SolidityNumberRange {
422 |                 min_val: BigInt::parse_bytes(
423 |                     b"-47890485652059026823698344598447161988085597568237568",
424 |                     10,
425 |                 )
426 |                 .unwrap(),
427 |                 max_val: BigInt::parse_bytes(
428 |                     b"47890485652059026823698344598447161988085597568237567",
429 |                     10,
430 |                 )
431 |                 .unwrap(),
432 |             };
433 |             assert_eq!(actual_range, expected_range);
434 |         }
435 | 
436 |         #[test]
437 |         fn helper_method_can_find_range_for_int248() {
438 |             let actual_range = get_range_for_type_string("int248").unwrap();
439 |             let expected_range = SolidityNumberRange {
440 |                 min_val: BigInt::parse_bytes(
441 |                     b"-226156424291633194186662080095093570025917938800079226639565593765455331328",
442 |                     10,
443 |                 )
444 |                 .unwrap(),
445 |                 max_val: BigInt::parse_bytes(
446 |                     b"226156424291633194186662080095093570025917938800079226639565593765455331327",
447 |                     10,
448 |                 )
449 |                 .unwrap(),
450 |             };
451 |             assert_eq!(actual_range, expected_range);
452 |         }
453 | 
454 |         #[test]
455 |         fn helper_method_can_find_range_for_int24() {
456 |             let actual_range = get_range_for_type_string("int24").unwrap();
457 |             let expected_range = SolidityNumberRange {
458 |                 min_val: BigInt::parse_bytes(b"-8388608", 10).unwrap(),
459 |                 max_val: BigInt::parse_bytes(b"8388607", 10).unwrap(),
460 |             };
461 |             assert_eq!(actual_range, expected_range);
462 |         }
463 | 
464 |         #[test]
465 |         fn helper_method_can_find_range_for_uint144() {
466 |             let actual_range = get_range_for_type_string("uint144").unwrap();
467 |             let expected_range = SolidityNumberRange {
468 |                 min_val: BigInt::ZERO,
469 |                 max_val: BigInt::parse_bytes(b"22300745198530623141535718272648361505980415", 10)
470 |                     .unwrap(),
471 |             };
472 |             assert_eq!(actual_range, expected_range);
473 |         }
474 | 
475 |         #[test]
476 |         fn helper_method_can_find_range_for_uint232() {
477 |             let actual_range = get_range_for_type_string("uint232").unwrap();
478 |             let expected_range = SolidityNumberRange {
479 |                 min_val: BigInt::ZERO,
480 |                 max_val: BigInt::parse_bytes(
481 |                     b"6901746346790563787434755862277025452451108972170386555162524223799295",
482 |                     10,
483 |                 )
484 |                 .unwrap(),
485 |             };
486 |             assert_eq!(actual_range, expected_range);
487 |         }
488 | 
489 |         #[test]
490 |         fn helper_method_can_find_range_for_uint256() {
491 |             let actual_range = get_range_for_type_string("uint256").unwrap();
492 |             let expected_range = SolidityNumberRange {
493 |                 min_val: BigInt::ZERO,
494 |                 max_val: BigInt::parse_bytes(
495 |                     b"115792089237316195423570985008687907853269984665640564039457584007913129639935",
496 |                     10,
497 |                 )
498 |                 .unwrap(),
499 |             };
500 |             assert_eq!(actual_range, expected_range);
501 |         }
502 | 
503 |         #[test]
504 |         fn helper_method_can_find_range_for_uint8() {
505 |             let actual_range = get_range_for_type_string("uint8").unwrap();
506 |             let expected_range = SolidityNumberRange {
507 |                 min_val: BigInt::ZERO,
508 |                 max_val: BigInt::parse_bytes(b"255", 10).unwrap(),
509 |             };
510 |             assert_eq!(actual_range, expected_range);
511 |         }
512 | 
513 |         #[test]
514 |         fn does_operation_make_sense_lhs_uint8_part1() {
515 |             let does_not_make_sense =
516 |                 !does_operation_make_sense_with_lhs_value("256", ">=", "uint8").unwrap();
517 |             assert!(does_not_make_sense);
518 |         }
519 | 
520 |         #[test]
521 |         fn does_operation_make_sense_rhs_uint8_part1() {
522 |             let does_make_sense =
523 |                 does_operation_make_sense_with_rhs_value("uint8", "<", "255").unwrap();
524 |             assert!(does_make_sense);
525 |         }
526 | 
527 |         #[test]
528 |         fn does_operation_make_sense_lhs_uint8_part2() {
529 |             let does_not_make_sense =
530 |                 !does_operation_make_sense_with_lhs_value("255", ">=", "uint8").unwrap();
531 |             assert!(does_not_make_sense);
532 |         }
533 | 
534 |         #[test]
535 |         fn does_operation_make_sense_lhs_uint8_part3() {
536 |             let does_make_sense =
537 |                 does_operation_make_sense_with_lhs_value("245", ">=", "uint8").unwrap();
538 |             assert!(does_make_sense);
539 |         }
540 | 
541 |         #[test]
542 |         fn does_operation_make_sense_rhs_uint8_part2() {
543 |             let does_make_sense =
544 |                 does_operation_make_sense_with_rhs_value("uint8", "<", "89").unwrap();
545 |             assert!(does_make_sense);
546 |         }
547 | 
548 |         #[test]
549 |         fn does_operation_make_sense_rhs_uint256_part3() {
550 |             let does_make_sense =
551 |                 does_operation_make_sense_with_rhs_value("uint256", ">", "0").unwrap();
552 |             assert!(does_make_sense);
553 |         }
554 | 
555 |         #[test]
556 |         fn does_operation_make_sense_rhs_uint256_part4() {
557 |             let does_not_make_sense =
558 |                 !does_operation_make_sense_with_rhs_value("uint256", ">=", "0").unwrap();
559 |             assert!(does_not_make_sense);
560 |         }
561 | 
562 |         #[test]
563 |         fn does_operation_make_sense_rhs_uint72_part5() {
564 |             let does_not_make_sense =
565 |                 !does_operation_make_sense_with_rhs_value("uint72", "<", "0").unwrap();
566 |             assert!(does_not_make_sense);
567 |         }
568 | 
569 |         #[test]
570 |         fn does_operation_make_sense_rhs_uint8_part6() {
571 |             let does_not_make_sense =
572 |                 !does_operation_make_sense_with_rhs_value("uint8", ">", "258").unwrap();
573 |             assert!(does_not_make_sense);
574 |         }
575 |     }
576 | }
577 | 
```

--------------------------------------------------------------------------------
/aderyn_core/src/ast/ast_nodes.rs:
--------------------------------------------------------------------------------

```rust
  1 | use super::{
  2 |     macros::{ast_node, ast_node_no_partial_eq, expr_node, node_group, stmt_node},
  3 |     *,
  4 | };
  5 | use std::collections::{BTreeMap, HashMap};
  6 | 
  7 | use serde::{Deserialize, Serialize};
  8 | 
  9 | node_group! {
 10 |     SourceUnitNode;
 11 | 
 12 |     ContractDefinition,
 13 |     EnumDefinition,
 14 |     ErrorDefinition,
 15 |     EventDefinition,
 16 |     FunctionDefinition,
 17 |     ImportDirective,
 18 |     PragmaDirective,
 19 |     StructDefinition,
 20 |     UserDefinedValueTypeDefinition,
 21 |     UsingForDirective,
 22 |     VariableDeclaration,
 23 | }
 24 | 
 25 | node_group! {
 26 |     Expression;
 27 | 
 28 |     Assignment,
 29 |     BinaryOperation,
 30 |     Conditional,
 31 |     ElementaryTypeNameExpression,
 32 |     FunctionCall,
 33 |     FunctionCallOptions,
 34 |     Identifier,
 35 |     IndexAccess,
 36 |     IndexRangeAccess,
 37 |     Literal,
 38 |     MemberAccess,
 39 |     NewExpression,
 40 |     TupleExpression,
 41 |     UnaryOperation,
 42 | }
 43 | 
 44 | node_group! {
 45 |     Statement;
 46 | 
 47 |     Block,
 48 |     Break,
 49 |     Continue,
 50 |     DoWhileStatement,
 51 |     EmitStatement,
 52 |     ExpressionStatement,
 53 |     ForStatement,
 54 |     IfStatement,
 55 |     InlineAssembly,
 56 |     PlaceholderStatement,
 57 |     Return,
 58 |     RevertStatement,
 59 |     TryStatement,
 60 |     UncheckedBlock,
 61 |     VariableDeclarationStatement,
 62 |     WhileStatement,
 63 | }
 64 | 
 65 | node_group! {
 66 |     ContractDefinitionNode;
 67 | 
 68 |     EnumDefinition,
 69 |     ErrorDefinition,
 70 |     EventDefinition,
 71 |     FunctionDefinition,
 72 |     ModifierDefinition,
 73 |     StructDefinition,
 74 |     UserDefinedValueTypeDefinition,
 75 |     UsingForDirective,
 76 |     VariableDeclaration,
 77 | }
 78 | 
 79 | #[derive(Clone, Debug, Eq, Serialize, PartialEq, Hash)]
 80 | pub enum TypeName {
 81 |     ArrayTypeName(ArrayTypeName),
 82 |     ElementaryTypeName(ElementaryTypeName),
 83 |     FunctionTypeName(FunctionTypeName),
 84 |     Mapping(Mapping),
 85 |     /// A string representing the type name.
 86 |     ///
 87 |     /// This variant applies to older compiler versions.
 88 |     Raw(String),
 89 |     UserDefinedTypeName(UserDefinedTypeName),
 90 | }
 91 | 
 92 | impl<'de> Deserialize<'de> for TypeName {
 93 |     fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
 94 |         let json = serde_json::Value::deserialize(deserializer)?;
 95 |         let node_type = json.get("nodeType");
 96 | 
 97 |         if node_type.is_none() {
 98 |             return Ok(TypeName::Raw(json.to_string()));
 99 |         }
100 | 
101 |         let type_name = node_type.unwrap().as_str().unwrap();
102 | 
103 |         match type_name {
104 |             "FunctionTypeName" => {
105 |                 Ok(TypeName::FunctionTypeName(serde_json::from_value(json).unwrap()))
106 |             }
107 |             "ArrayTypeName" => Ok(TypeName::ArrayTypeName(serde_json::from_value(json).unwrap())),
108 |             "Mapping" => Ok(TypeName::Mapping(serde_json::from_value(json).unwrap())),
109 |             "UserDefinedTypeName" => {
110 |                 Ok(TypeName::UserDefinedTypeName(serde_json::from_value(json).unwrap()))
111 |             }
112 |             "ElementaryTypeName" => {
113 |                 Ok(TypeName::ElementaryTypeName(serde_json::from_value(json).unwrap()))
114 |             }
115 |             _ => panic!("Unrecognized type name {type_name}"),
116 |         }
117 |     }
118 | }
119 | 
120 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
121 | #[serde(tag = "nodeType")]
122 | pub enum UserDefinedTypeNameOrIdentifierPath {
123 |     UserDefinedTypeName(UserDefinedTypeName),
124 |     IdentifierPath(IdentifierPath),
125 | }
126 | 
127 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
128 | #[serde(tag = "nodeType")]
129 | pub enum ExpressionOrVariableDeclarationStatement {
130 |     ExpressionStatement(ExpressionStatement),
131 |     VariableDeclarationStatement(VariableDeclarationStatement),
132 | }
133 | 
134 | impl ExpressionOrVariableDeclarationStatement {
135 |     pub fn get_node_id(&self) -> Option<NodeID> {
136 |         match self {
137 |             ExpressionOrVariableDeclarationStatement::ExpressionStatement(expression) => {
138 |                 Some(expression.id)
139 |             }
140 |             ExpressionOrVariableDeclarationStatement::VariableDeclarationStatement(vd_stmnt) => {
141 |                 Some(vd_stmnt.id)
142 |             }
143 |         }
144 |     }
145 | }
146 | 
147 | ast_node!(
148 |     #[derive(Hash)]
149 |     struct Block {
150 |         statements: Vec<Statement>,
151 |     }
152 | );
153 | 
154 | stmt_node!(
155 |     #[derive(Hash)]
156 |     struct UncheckedBlock {
157 |         statements: Vec<Statement>,
158 |     }
159 | );
160 | 
161 | #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
162 | #[serde(rename_all = "lowercase")]
163 | pub enum ContractKind {
164 |     Contract,
165 |     Interface,
166 |     Library,
167 | }
168 | 
169 | ast_node!(
170 |     #[derive(Hash)]
171 |     struct InheritanceSpecifier {
172 |         base_name: UserDefinedTypeNameOrIdentifierPath,
173 |         arguments: Option<Vec<Expression>>,
174 |     }
175 | );
176 | 
177 | ast_node!(
178 |     #[derive(Hash)]
179 |     struct ContractDefinition {
180 |         name: String,
181 |         name_location: Option<String>,
182 |         documentation: Option<Documentation>,
183 |         #[serde(rename = "contractKind")]
184 |         kind: ContractKind,
185 |         #[serde(default, rename = "abstract")]
186 |         is_abstract: bool,
187 |         base_contracts: Vec<InheritanceSpecifier>,
188 |         canonical_name: Option<String>,
189 |         contract_dependencies: Vec<NodeID>,
190 |         used_errors: Option<Vec<NodeID>>,
191 |         used_events: Option<Vec<usize>>,
192 |         #[serde(default, rename = "internalFunctionIDs")]
193 |         internal_function_ids: BTreeMap<String, usize>,
194 |         nodes: Vec<ContractDefinitionNode>,
195 |         scope: NodeID,
196 |         fully_implemented: bool,
197 |         linearized_base_contracts: Vec<NodeID>,
198 |     }
199 | );
200 | 
201 | #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Hash)]
202 | #[serde(untagged)]
203 | pub enum Documentation {
204 |     String(Option<String>),
205 |     Structured(Option<StructuredDocumentation>),
206 | }
207 | 
208 | ast_node!(
209 |     #[derive(Hash)]
210 |     struct StructuredDocumentation {
211 |         text: String,
212 |     }
213 | );
214 | 
215 | ast_node!(
216 |     #[derive(Hash)]
217 |     struct EnumValue {
218 |         name: String,
219 |         name_location: Option<String>,
220 |     }
221 | );
222 | 
223 | ast_node!(
224 |     #[derive(Hash)]
225 |     struct EnumDefinition {
226 |         name: String,
227 |         name_location: Option<String>,
228 |         members: Vec<EnumValue>,
229 |         canonical_name: Option<String>,
230 |     }
231 | );
232 | 
233 | ast_node!(
234 |     #[derive(Hash)]
235 |     struct ErrorDefinition {
236 |         documentation: Option<Documentation>,
237 |         error_selector: Option<String>,
238 |         name: String,
239 |         name_location: Option<String>,
240 |         parameters: ParameterList,
241 |     }
242 | );
243 | 
244 | ast_node!(
245 |     #[derive(Hash)]
246 |     struct EventDefinition {
247 |         anonymous: bool,
248 |         documentation: Option<Documentation>,
249 |         name: String,
250 |         name_location: Option<String>,
251 |         parameters: ParameterList,
252 |         event_selector: Option<String>,
253 |     }
254 | );
255 | 
256 | expr_node!(
257 |     #[derive(Hash)]
258 |     struct UnaryOperation {
259 |         operator: String,
260 |         /// Whether the unary operator is before or after the expression (e.g. `x++` vs. `++x`)
261 |         prefix: bool,
262 |         sub_expression: Box<Expression>,
263 |     }
264 | );
265 | 
266 | expr_node!(
267 |     #[derive(Hash)]
268 |     struct BinaryOperation {
269 |         common_type: TypeDescriptions,
270 |         left_expression: Box<Expression>,
271 |         right_expression: Box<Expression>,
272 |         operator: String,
273 |     }
274 | );
275 | 
276 | expr_node!(
277 |     #[derive(Hash)]
278 |     struct Conditional {
279 |         condition: Box<Expression>,
280 |         true_expression: Box<Expression>,
281 |         false_expression: Box<Expression>,
282 |     }
283 | );
284 | 
285 | expr_node!(
286 |     #[derive(Hash)]
287 |     struct Assignment {
288 |         left_hand_side: Box<Expression>,
289 |         right_hand_side: Box<Expression>,
290 |         operator: String,
291 |     }
292 | );
293 | 
294 | expr_node!(
295 |     #[derive(Hash)]
296 |     struct FunctionCall {
297 |         kind: FunctionCallKind,
298 |         #[serde(default)]
299 |         try_call: bool,
300 |         names: Vec<String>,
301 |         arguments: Vec<Expression>,
302 |         expression: Box<Expression>,
303 |     }
304 | );
305 | 
306 | #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
307 | #[serde(rename_all = "camelCase")]
308 | pub enum FunctionCallKind {
309 |     FunctionCall,
310 |     TypeConversion,
311 |     StructConstructorCall,
312 | }
313 | 
314 | expr_node!(
315 |     #[derive(Hash)]
316 |     struct FunctionCallOptions {
317 |         names: Vec<String>,
318 |         options: Vec<Expression>,
319 |         arguments: Option<Vec<Expression>>,
320 |         expression: Box<Expression>,
321 |     }
322 | );
323 | 
324 | expr_node!(
325 |     #[derive(Hash)]
326 |     struct NewExpression {
327 |         type_name: TypeName,
328 |     }
329 | );
330 | 
331 | expr_node!(
332 |     #[derive(Hash)]
333 |     struct IndexAccess {
334 |         base_expression: Box<Expression>,
335 |         index_expression: Option<Box<Expression>>,
336 |     }
337 | );
338 | 
339 | expr_node!(
340 |     #[derive(Hash)]
341 |     struct IndexRangeAccess {
342 |         base_expression: Box<Expression>,
343 |         start_expression: Option<Box<Expression>>,
344 |         end_expression: Option<Box<Expression>>,
345 |     }
346 | );
347 | 
348 | expr_node!(
349 |     #[derive(Hash)]
350 |     struct MemberAccess {
351 |         member_name: String,
352 |         expression: Box<Expression>,
353 |         referenced_declaration: Option<NodeID>,
354 |     }
355 | );
356 | 
357 | expr_node!(
358 |     #[derive(Hash)]
359 |     struct ElementaryTypeNameExpression {
360 |         type_name: TypeName,
361 |     }
362 | );
363 | 
364 | expr_node!(
365 |     #[derive(Hash)]
366 |     struct TupleExpression {
367 |         components: Vec<Option<Expression>>,
368 |         is_inline_array: bool,
369 |     }
370 | );
371 | 
372 | #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
373 | #[serde(rename_all = "camelCase")]
374 | pub enum FunctionKind {
375 |     Constructor,
376 |     Function,
377 |     Receive,
378 |     Fallback,
379 |     FreeFunction,
380 | }
381 | 
382 | ast_node!(
383 |     #[derive(Hash)]
384 |     struct ParameterList {
385 |         parameters: Vec<VariableDeclaration>,
386 |     }
387 | );
388 | 
389 | ast_node!(
390 |     #[derive(Hash)]
391 |     struct OverrideSpecifier {
392 |         overrides: Vec<UserDefinedTypeNameOrIdentifierPath>,
393 |     }
394 | );
395 | 
396 | ast_node!(
397 |     #[derive(Hash)]
398 |     struct FunctionDefinition {
399 |         base_functions: Option<Vec<NodeID>>,
400 |         body: Option<Block>,
401 |         documentation: Option<Documentation>,
402 |         function_selector: Option<String>,
403 |         implemented: bool,
404 |         /// The kind of function this node defines. Only valid for Solidity versions 0.5.x and
405 |         /// above.
406 |         ///
407 |         /// For cross-version compatibility use [`FunctionDefinition::kind()`].
408 |         kind: Option<FunctionKind>,
409 |         #[serde(default)]
410 |         /// For cross-version compatibility use [`FunctionDefinition::state_mutability()`].
411 |         state_mutability: Option<StateMutability>,
412 |         #[serde(default, rename = "virtual")]
413 |         is_virtual: bool,
414 |         /// Whether or not this function is the constructor. Only valid for Solidity versions below
415 |         /// 0.5.x.
416 |         ///
417 |         /// After 0.5.x you must use `kind`. For cross-version compatibility use
418 |         /// [`FunctionDefinition::kind()`].
419 |         #[serde(default)]
420 |         is_constructor: bool,
421 |         /// Whether or not this function is constant (view or pure). Only valid for Solidity
422 |         /// versions below 0.5.x.
423 |         ///
424 |         /// After 0.5.x you must use `state_mutability`. For cross-version compatibility use
425 |         /// [`FunctionDefinition::state_mutability()`].
426 |         #[serde(default)]
427 |         is_declared_const: bool,
428 |         /// Whether or not this function is payable. Only valid for Solidity versions below
429 |         /// 0.5.x.
430 |         ///
431 |         /// After 0.5.x you must use `state_mutability`. For cross-version compatibility use
432 |         /// [`FunctionDefinition::state_mutability()`].
433 |         #[serde(default)]
434 |         is_payable: bool,
435 |         modifiers: Vec<ModifierInvocation>,
436 |         name: String,
437 |         name_location: Option<String>,
438 |         overrides: Option<OverrideSpecifier>,
439 |         parameters: ParameterList,
440 |         return_parameters: ParameterList,
441 |         scope: NodeID,
442 |         super_function: Option<NodeID>,
443 |         visibility: Visibility,
444 |     }
445 | );
446 | 
447 | ast_node_no_partial_eq!(
448 |     struct Identifier {
449 |         argument_types: Option<Vec<TypeDescriptions>>,
450 |         name: String,
451 |         overloaded_declarations: Vec<NodeID>,
452 |         referenced_declaration: Option<NodeID>,
453 |         type_descriptions: TypeDescriptions,
454 |     }
455 | );
456 | 
457 | ast_node_no_partial_eq!(
458 |     struct IdentifierPath {
459 |         name: String,
460 |         referenced_declaration: i64,
461 |     }
462 | );
463 | 
464 | #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Hash)]
465 | #[serde(rename_all = "camelCase")]
466 | pub struct SymbolAlias {
467 |     pub foreign: Identifier,
468 |     pub local: Option<String>,
469 |     pub name_location: Option<String>,
470 | }
471 | 
472 | ast_node!(
473 |     #[derive(Hash)]
474 |     struct ImportDirective {
475 |         file: String,
476 |         source_unit: NodeID,
477 |         scope: NodeID,
478 |         absolute_path: Option<String>,
479 |         unit_alias: String,
480 |         name_location: Option<String>,
481 |         symbol_aliases: Vec<SymbolAlias>,
482 |     }
483 | );
484 | 
485 | #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
486 | #[serde(rename_all = "camelCase")]
487 | pub enum LiteralKind {
488 |     Bool,
489 |     Number,
490 |     String,
491 |     HexString,
492 |     Address,
493 |     UnicodeString,
494 | }
495 | 
496 | expr_node!(
497 |     #[derive(Hash)]
498 |     struct Literal {
499 |         hex_value: String,
500 |         value: Option<String>,
501 |         subdenomination: Option<String>,
502 |         kind: LiteralKind,
503 |     }
504 | );
505 | 
506 | ast_node!(
507 |     #[derive(Hash)]
508 |     struct ModifierDefinition {
509 |         body: Option<Block>,
510 |         base_modifiers: Option<Vec<usize>>,
511 |         overrides: Option<OverrideSpecifier>,
512 |         documentation: Option<Documentation>,
513 |         name: String,
514 |         name_location: Option<String>,
515 |         parameters: ParameterList,
516 |         #[serde(default, rename = "virtual")]
517 |         is_virtual: bool,
518 |         visibility: Visibility,
519 |     }
520 | );
521 | 
522 | #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
523 | #[serde(rename_all = "camelCase")]
524 | pub enum ModifierInvocationKind {
525 |     ModifierInvocation,
526 |     BaseConstructorSpecifier,
527 | }
528 | 
529 | ast_node!(
530 |     #[derive(Hash)]
531 |     struct ModifierInvocation {
532 |         arguments: Option<Vec<Expression>>,
533 |         modifier_name: IdentifierOrIdentifierPath,
534 |         kind: Option<ModifierInvocationKind>,
535 |     }
536 | );
537 | 
538 | #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Hash)]
539 | #[serde(tag = "nodeType")]
540 | pub enum IdentifierOrIdentifierPath {
541 |     Identifier(Identifier),
542 |     IdentifierPath(IdentifierPath),
543 | }
544 | 
545 | ast_node!(
546 |     #[derive(Hash)]
547 |     struct PragmaDirective {
548 |         literals: Vec<String>,
549 |     }
550 | );
551 | 
552 | ast_node!(
553 |     struct SourceUnit {
554 |         license: Option<String>,
555 |         nodes: Vec<SourceUnitNode>,
556 |         exported_symbols: Option<HashMap<String, Vec<NodeID>>>,
557 |         absolute_path: Option<String>,
558 | 
559 |         #[serde(skip_serializing)]
560 |         source: Option<String>,
561 |     }
562 | );
563 | 
564 | stmt_node!(
565 |     #[derive(Hash)]
566 |     struct ExpressionStatement {
567 |         expression: Expression,
568 |     }
569 | );
570 | 
571 | stmt_node!(
572 |     #[derive(Hash)]
573 |     struct VariableDeclarationStatement {
574 |         assignments: Vec<Option<NodeID>>,
575 |         declarations: Vec<Option<VariableDeclaration>>,
576 |         initial_value: Option<Expression>,
577 |     }
578 | );
579 | 
580 | #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Hash)]
581 | #[serde(untagged)]
582 | pub enum BlockOrStatement {
583 |     Block(Box<Block>),
584 |     Statement(Box<Statement>),
585 | }
586 | 
587 | stmt_node!(
588 |     #[derive(Hash)]
589 |     struct IfStatement {
590 |         condition: Expression,
591 |         true_body: BlockOrStatement,
592 |         false_body: Option<BlockOrStatement>,
593 |     }
594 | );
595 | 
596 | stmt_node!(
597 |     #[derive(Hash)]
598 |     struct ForStatement {
599 |         initialization_expression: Option<Box<ExpressionOrVariableDeclarationStatement>>,
600 |         condition: Option<Expression>,
601 |         loop_expression: Option<Box<ExpressionStatement>>,
602 |         body: BlockOrStatement,
603 |     }
604 | );
605 | 
606 | stmt_node!(
607 |     #[derive(Hash)]
608 |     struct DoWhileStatement {
609 |         body: Block,
610 |         condition: Expression,
611 |     }
612 | );
613 | 
614 | stmt_node!(
615 |     #[derive(Hash)]
616 |     struct EmitStatement {
617 |         event_call: FunctionCall,
618 |     }
619 | );
620 | 
621 | stmt_node!(
622 |     #[derive(Hash)]
623 |     struct TryStatement {
624 |         clauses: Vec<TryCatchClause>,
625 |         external_call: FunctionCall,
626 |     }
627 | );
628 | 
629 | stmt_node!(
630 |     #[derive(Hash)]
631 |     struct RevertStatement {
632 |         error_call: FunctionCall,
633 |     }
634 | );
635 | 
636 | ast_node!(
637 |     #[derive(Hash)]
638 |     struct TryCatchClause {
639 |         block: Block,
640 |         error_name: String,
641 |         parameters: Option<ParameterList>,
642 |     }
643 | );
644 | 
645 | stmt_node!(
646 |     #[derive(Hash)]
647 |     struct Return {
648 |         function_return_parameters: Option<NodeID>, /* When returning in a modifier, this can be
649 |                                                      * none */
650 |         expression: Option<Expression>,
651 |     }
652 | );
653 | 
654 | ast_node!(
655 |     #[derive(Hash)]
656 |     struct InlineAssembly {
657 |         #[serde(rename = "AST")]
658 |         ast: Option<YulBlock>,
659 |         evm_version: Option<String>,
660 |         external_references: Vec<ExternalReference>,
661 |         operations: Option<String>,
662 |     }
663 | );
664 | 
665 | stmt_node!(
666 |     #[derive(Hash)]
667 |     struct Break {}
668 | );
669 | 
670 | stmt_node!(
671 |     #[derive(Hash)]
672 |     struct Continue {}
673 | );
674 | 
675 | stmt_node!(
676 |     #[derive(Hash)]
677 |     struct PlaceholderStatement {}
678 | );
679 | 
680 | stmt_node!(
681 |     #[derive(Hash)]
682 |     struct WhileStatement {
683 |         condition: Expression,
684 |         body: BlockOrStatement,
685 |     }
686 | );
687 | 
688 | ast_node!(
689 |     #[derive(Hash)]
690 |     struct StructDefinition {
691 |         name: String,
692 |         name_location: Option<String>,
693 |         visibility: Visibility,
694 |         members: Vec<VariableDeclaration>,
695 |         scope: NodeID,
696 |         canonical_name: Option<String>,
697 |     }
698 | );
699 | 
700 | #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Hash)]
701 | #[serde(rename_all = "camelCase")]
702 | pub struct TypeDescriptions {
703 |     pub type_identifier: Option<String>,
704 |     pub type_string: Option<String>,
705 | }
706 | 
707 | ast_node_no_partial_eq!(
708 |     struct ElementaryTypeName {
709 |         state_mutability: Option<StateMutability>,
710 |         name: String,
711 |         type_descriptions: TypeDescriptions,
712 |     }
713 | );
714 | 
715 | ast_node_no_partial_eq!(
716 |     struct UserDefinedTypeName {
717 |         path_node: Option<IdentifierPath>,
718 |         referenced_declaration: NodeID,
719 |         name: Option<String>,
720 |         type_descriptions: TypeDescriptions,
721 |         contract_scope: Option<String>,
722 |     }
723 | );
724 | 
725 | ast_node!(
726 |     #[derive(Hash)]
727 |     struct FunctionTypeName {
728 |         visibility: Visibility,
729 |         state_mutability: StateMutability,
730 |         parameter_types: ParameterList,
731 |         return_parameter_types: ParameterList,
732 |         type_descriptions: TypeDescriptions,
733 |     }
734 | );
735 | 
736 | ast_node!(
737 |     #[derive(Hash)]
738 |     struct ArrayTypeName {
739 |         base_type: Box<TypeName>,
740 |         length: Box<Option<Expression>>,
741 |         type_descriptions: TypeDescriptions,
742 |     }
743 | );
744 | 
745 | ast_node!(
746 |     #[derive(Hash)]
747 |     struct Mapping {
748 |         key_type: Box<TypeName>,
749 |         value_type: Box<TypeName>,
750 |         type_descriptions: TypeDescriptions,
751 |     }
752 | );
753 | 
754 | ast_node!(
755 |     #[derive(Hash)]
756 |     struct UserDefinedValueTypeDefinition {
757 |         underlying_type: TypeName,
758 |         name: String,
759 |         name_location: Option<String>,
760 |         canonical_name: Option<String>,
761 |     }
762 | );
763 | 
764 | ast_node!(
765 |     #[derive(Hash)]
766 |     struct UsingForDirective {
767 |         function_list: Option<Vec<UsingForFunctionItem>>,
768 |         #[serde(default)]
769 |         global: bool,
770 |         library_name: Option<UserDefinedTypeNameOrIdentifierPath>,
771 |         type_name: Option<TypeName>,
772 |     }
773 | );
774 | 
775 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
776 | #[serde(untagged)]
777 | pub enum UsingForFunctionItem {
778 |     Function(FunctionIdentifierPath),
779 |     OverloadedOperator(OverloadedOperator),
780 | }
781 | 
782 | /// A wrapper around [IdentifierPath] for the [UsingForDirective].
783 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
784 | pub struct FunctionIdentifierPath {
785 |     pub function: IdentifierPath,
786 | }
787 | 
788 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
789 | pub struct OverloadedOperator {
790 |     pub definition: IdentifierPath,
791 |     pub operator: String,
792 | }
793 | 
794 | #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
795 | #[serde(rename_all = "lowercase")]
796 | pub enum Mutability {
797 |     Immutable,
798 |     Mutable,
799 |     Constant,
800 | }
801 | 
802 | #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
803 | #[serde(rename_all = "lowercase")]
804 | pub enum StateMutability {
805 |     NonPayable,
806 |     Payable,
807 |     View,
808 |     Pure,
809 | }
810 | 
811 | #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
812 | #[serde(rename_all = "lowercase")]
813 | pub enum Visibility {
814 |     Public,
815 |     Private,
816 |     Internal,
817 |     External,
818 | }
819 | 
820 | #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
821 | #[serde(rename_all = "lowercase")]
822 | pub enum StorageLocation {
823 |     Default,
824 |     Memory,
825 |     Calldata,
826 |     Storage,
827 |     Transient,
828 | }
829 | 
830 | ast_node!(
831 |     #[derive(Hash)]
832 |     struct VariableDeclaration {
833 |         base_functions: Option<Vec<NodeID>>,
834 |         /// Marks whether or not the variable is a constant before Solidity 0.7.x.
835 |         ///
836 |         /// After 0.7.x you must use `mutability`. For cross-version compatibility use
837 |         /// [`VariableDeclaration::mutability()`].
838 |         #[serde(default)]
839 |         constant: bool,
840 |         documentation: Option<Documentation>,
841 |         function_selector: Option<String>,
842 |         indexed: Option<bool>,
843 |         /// Marks the variable's mutability from Solidity 0.7.x onwards.
844 |         /// For cross-version compatibility use [`VariableDeclaration::mutability()`].
845 |         #[serde(default)]
846 |         mutability: Option<Mutability>,
847 |         name: String,
848 |         name_location: Option<String>,
849 |         overrides: Option<OverrideSpecifier>,
850 |         scope: NodeID,
851 |         /// Marks whether or not the variable is a state variable before Solidity 0.7.x.
852 |         ///
853 |         /// After 0.7.x you must use `mutability`. For cross-version compatibility use
854 |         /// [`VariableDeclaration::mutability()`].
855 |         #[serde(default)]
856 |         state_variable: bool,
857 |         storage_location: StorageLocation,
858 |         type_descriptions: TypeDescriptions,
859 |         type_name: Option<TypeName>,
860 |         value: Option<Expression>,
861 |         visibility: Visibility,
862 |     }
863 | );
864 | 
```
Page 96/103FirstPrevNextLast