This is page 11 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
--------------------------------------------------------------------------------
/aderyn_driver/src/config.rs:
--------------------------------------------------------------------------------
```rust
1 | use std::{
2 | collections::HashMap,
3 | env, fs,
4 | path::{Path, PathBuf},
5 | };
6 |
7 | use serde::Deserialize;
8 |
9 | use crate::process::PreprocessedConfig;
10 |
11 | /// `aderyn.toml` file structure
12 | #[derive(Deserialize, Clone)]
13 | pub struct AderynConfig {
14 | pub version: usize,
15 | pub root: Option<String>,
16 | pub src: Option<String>,
17 | pub exclude: Option<Vec<String>>,
18 | pub include: Option<Vec<String>>,
19 | pub env: Option<HashMap<String, String>>,
20 | }
21 |
22 | pub fn supplement_values_from_aderyn_toml(
23 | current: PreprocessedConfig,
24 | ) -> Result<PreprocessedConfig, Box<dyn std::error::Error + Send + Sync>> {
25 | let root_path = current.root_path.clone();
26 | Ok(supplement(current, aderyn_toml_config(&root_path)?))
27 | }
28 |
29 | /// Load the aderyn.toml file and deserialize it to AderynConfig
30 | fn aderyn_toml_config(root: &Path) -> Result<AderynConfig, String> {
31 | let config_path = root.join("aderyn.toml");
32 | // Read the file
33 | let content = fs::read_to_string(config_path)
34 | .map_err(|err| format!("Error reading config file: {}", err))?;
35 |
36 | // Deserialize the TOML string to AderynConfig
37 | let mut config: AderynConfig =
38 | toml::from_str(&content).map_err(|err| format!("Error parsing config file: {}", err))?;
39 |
40 | if config.version != 1 {
41 | return Err("aderyn.toml version not supported".to_owned());
42 | }
43 |
44 | // Clear empty vectors
45 | clear_empty_vectors(&mut config.exclude);
46 | clear_empty_vectors(&mut config.include);
47 |
48 | Ok(config)
49 | }
50 |
51 | fn supplement(current: PreprocessedConfig, config: AderynConfig) -> PreprocessedConfig {
52 | // Load env variables
53 | if let Some(map) = config.env.clone() {
54 | map.iter().for_each(|(k, v)| {
55 | unsafe { env::set_var(k, v) };
56 | })
57 | }
58 |
59 | let mut local_root: PathBuf = current.root_path;
60 | if let Some(config_root) = &config.root {
61 | // append the config_root to the local_root
62 | local_root.push(config_root);
63 | }
64 |
65 | // If config.src is some, command line arg src overrides config.src
66 | let mut local_src: Option<String> = current.src.clone();
67 | if let Some(config_src) = &config.src
68 | && local_src.is_none()
69 | {
70 | local_src = Some(config_src.clone());
71 | }
72 |
73 | // If config.exclude is some, append each value to exclude if it is not already present
74 | let mut local_exclude = current.exclude.clone();
75 | if let Some(config_exclude) = &config.exclude {
76 | if let Some(local_exclude) = &mut local_exclude {
77 | for item in config_exclude {
78 | if !local_exclude.contains(item) {
79 | local_exclude.push(item.clone());
80 | }
81 | }
82 | } else {
83 | local_exclude = Some(config_exclude.clone());
84 | }
85 | }
86 |
87 | // If config.include is some, append each value to include if it is not already present
88 | let mut local_include = current.include.clone();
89 | if let Some(config_scope) = &config.include {
90 | if let Some(local_include) = &mut local_include {
91 | for item in config_scope {
92 | if !local_include.contains(item) {
93 | local_include.push(item.clone());
94 | }
95 | }
96 | } else {
97 | local_include = Some(config_scope.clone());
98 | }
99 | }
100 |
101 | PreprocessedConfig {
102 | root_path: local_root,
103 | src: local_src,
104 | exclude: local_exclude,
105 | include: local_include,
106 | }
107 | }
108 |
109 | fn clear_empty_vectors<T>(vec: &mut Option<Vec<T>>) {
110 | if let Some(v) = vec
111 | && v.is_empty()
112 | {
113 | *vec = None;
114 | }
115 | }
116 |
117 | #[cfg(test)]
118 | mod tests {
119 | use std::{collections::HashMap, env};
120 |
121 | use crate::process::PreprocessedConfig;
122 |
123 | #[test]
124 | fn test_interpret_aderyn_config_correctly_appends_and_replaces() {
125 | // Act
126 | let current = {
127 | let root = std::path::Path::new("ARG_ROOT");
128 | let src = Some("ARG_SRC".to_string());
129 | let exclude = Some(vec!["ARG_EXCLUDE_1".to_string(), "ARG_EXCLUDE_2".to_string()]);
130 | let include = Some(vec!["ARG_SCOPE_1".to_string(), "ARG_SCOPE_2".to_string()]);
131 | PreprocessedConfig { root_path: root.to_path_buf(), src, include, exclude }
132 | };
133 | let result = {
134 | let env = HashMap::from_iter(vec![(
135 | "FOUNDRY_PROFILE".to_string(),
136 | "ENV_VAR_VALUE".to_string(),
137 | )]);
138 | let config = super::AderynConfig {
139 | version: 1,
140 | root: Some("CONFIG_ROOT".to_string()),
141 | src: Some("CONFIG_SRC".to_string()),
142 | exclude: Some(vec!["CONFIG_EXCLUDE".to_string()]),
143 | include: Some(vec!["CONFIG_SCOPE".to_string()]),
144 | env: Some(env),
145 | };
146 | super::supplement(current, config)
147 | };
148 |
149 | // Assert
150 | assert_eq!(env::var("FOUNDRY_PROFILE").unwrap(), "ENV_VAR_VALUE");
151 | assert_eq!(result.root_path, std::path::Path::new("ARG_ROOT/CONFIG_ROOT"));
152 | assert_eq!(result.src, Some("ARG_SRC".to_string()));
153 | assert_eq!(
154 | result.exclude,
155 | Some(vec![
156 | "ARG_EXCLUDE_1".to_string(),
157 | "ARG_EXCLUDE_2".to_string(),
158 | "CONFIG_EXCLUDE".to_string()
159 | ])
160 | );
161 | assert_eq!(
162 | result.include,
163 | Some(vec![
164 | "ARG_SCOPE_1".to_string(),
165 | "ARG_SCOPE_2".to_string(),
166 | "CONFIG_SCOPE".to_string()
167 | ])
168 | );
169 | }
170 |
171 | #[test]
172 | fn test_clear_empty_vectors() {
173 | let mut vec_1 = Some(vec!["a".to_string(), "b".to_string()]);
174 | super::clear_empty_vectors(&mut vec_1);
175 | assert_eq!(vec_1, Some(vec!["a".to_string(), "b".to_string()]));
176 |
177 | let mut vec_2: Option<Vec<String>> = Some(vec![]);
178 | super::clear_empty_vectors(&mut vec_2);
179 | assert_eq!(vec_2, None);
180 | }
181 | }
182 |
```
--------------------------------------------------------------------------------
/aderyn_core/src/detect/low/constant_function_contains_assembly.rs:
--------------------------------------------------------------------------------
```rust
1 | use std::{collections::BTreeMap, error::Error, str::FromStr};
2 |
3 | use crate::ast::{ASTNode, NodeID, NodeType, StateMutability};
4 |
5 | use crate::{
6 | capture,
7 | context::browser::{
8 | ExtractInlineAssemblies, ExtractPragmaDirectives, GetClosestAncestorOfTypeX,
9 | },
10 | };
11 |
12 | use crate::{
13 | context::{
14 | graph::{CallGraphConsumer, CallGraphDirection, CallGraphVisitor},
15 | workspace::WorkspaceContext,
16 | },
17 | detect::{
18 | detector::{IssueDetector, IssueDetectorNamePool, IssueSeverity},
19 | helpers::{self, pragma_directive_to_semver},
20 | },
21 | };
22 | use eyre::Result;
23 | use semver::{Version, VersionReq};
24 |
25 | #[derive(Default)]
26 | pub struct ConstantFunctionContainsAssemblyDetector {
27 | // Keys are: [0] source file name, [1] line number, [2] character location of node.
28 | // Do not add items manually, use `capture!` to add nodes to this BTreeMap.
29 | found_instances: BTreeMap<(String, usize, String), NodeID>,
30 | }
31 |
32 | impl IssueDetector for ConstantFunctionContainsAssemblyDetector {
33 | fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
34 | for function in helpers::get_implemented_external_and_public_functions(context) {
35 | // First, check the eligibility for this function by checking
36 | if let Some(ASTNode::SourceUnit(source_unit)) =
37 | function.closest_ancestor_of_type(context, NodeType::SourceUnit)
38 | {
39 | // Store the extracted directives in a variable to extend its lifetime
40 | let extracted_directives = ExtractPragmaDirectives::from(source_unit).extracted;
41 | let pragma_directive = extracted_directives.first();
42 |
43 | if let Some(pragma_directive) = pragma_directive {
44 | let version_req = pragma_directive_to_semver(pragma_directive);
45 | if let Ok(version_req) = version_req
46 | && version_req_allows_below_0_5_0(&version_req)
47 | {
48 | // Only run the logic if pragma is allowed to run on solc <0.5.0
49 |
50 | if function.state_mutability() == &StateMutability::View
51 | || function.state_mutability() == &StateMutability::Pure
52 | {
53 | let mut tracker = AssemblyTracker { has_assembly: false };
54 | // keep legacy because < 0.5.0
55 | let callgraph = CallGraphConsumer::get_legacy(
56 | context,
57 | &[&(function.into())],
58 | CallGraphDirection::Inward,
59 | )?;
60 | callgraph.accept(context, &mut tracker)?;
61 |
62 | if tracker.has_assembly {
63 | capture!(self, context, function);
64 | }
65 | }
66 | }
67 | }
68 | }
69 | }
70 |
71 | Ok(!self.found_instances.is_empty())
72 | }
73 |
74 | fn severity(&self) -> IssueSeverity {
75 | IssueSeverity::Low
76 | }
77 |
78 | fn title(&self) -> String {
79 | String::from("Constant Function Contains Assembly")
80 | }
81 |
82 | fn description(&self) -> String {
83 | String::from(
84 | "constant/pure/view was not enforced prior to Solidity 0.5. Starting from Solidity 0.5, a call to a constant/pure/view function uses the STATICCALL opcode, \
85 | which reverts in case of state modification. As a result, a call to an incorrectly labeled function may trap a contract compiled with Solidity 0.5. \
86 | https://docs.soliditylang.org/en/develop/050-breaking-changes.html#interoperability-with-older-contracts",
87 | )
88 | }
89 |
90 | fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
91 | self.found_instances.clone()
92 | }
93 |
94 | fn name(&self) -> String {
95 | format!("{}", IssueDetectorNamePool::ConstantFunctionContainsAssembly)
96 | }
97 | }
98 |
99 | fn version_req_allows_below_0_5_0(version_req: &VersionReq) -> bool {
100 | // If it matches any 0.4.0 to 0.4.26, return true
101 | for i in 0..=26 {
102 | let version: semver::Version = Version::from_str(&format!("0.4.{}", i)).unwrap();
103 | if version_req.matches(&version) {
104 | return true;
105 | }
106 | }
107 |
108 | // Else, return false
109 | false
110 | }
111 |
112 | struct AssemblyTracker {
113 | has_assembly: bool,
114 | }
115 |
116 | impl CallGraphVisitor for AssemblyTracker {
117 | fn visit_any(&mut self, node: &crate::ast::ASTNode) -> eyre::Result<()> {
118 | // If we are already satisfied, do not bother checking
119 | if self.has_assembly {
120 | return Ok(());
121 | }
122 |
123 | if let ASTNode::FunctionDefinition(function) = node {
124 | // Ignore checking functions that start with `_`
125 | // Example - templegold contains math functions like `_rpow()`, etc that are used by
126 | // view functions That should be okay .. I guess? (idk ... it's open for
127 | // discussion)
128 | if function.name.starts_with('_') {
129 | return Ok(());
130 | }
131 | }
132 |
133 | // Check if this node has assembly code
134 | let assemblies = ExtractInlineAssemblies::from(node).extracted;
135 | if !assemblies.is_empty() {
136 | self.has_assembly = true;
137 | }
138 | Ok(())
139 | }
140 | }
141 |
142 | #[cfg(test)]
143 | mod constant_functions_assembly_detector {
144 |
145 | use crate::detect::{
146 | detector::IssueDetector,
147 | low::constant_function_contains_assembly::ConstantFunctionContainsAssemblyDetector,
148 | };
149 |
150 | #[test]
151 |
152 | fn test_constant_functions_assembly() {
153 | let context = crate::detect::test_utils::load_solidity_source_unit(
154 | "../tests/contract-playground/src/ConstantFuncsAssembly.sol",
155 | );
156 |
157 | let mut detector = ConstantFunctionContainsAssemblyDetector::default();
158 | let found = detector.detect(&context).unwrap();
159 | assert!(found);
160 | assert_eq!(detector.instances().len(), 3);
161 | }
162 | }
163 |
```
--------------------------------------------------------------------------------
/benchmarks/useless-public-function/report/relative_regression_small.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="450" height="300" viewBox="0 0 450 300" xmlns="http://www.w3.org/2000/svg">
2 | <text x="15" y="130" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 15, 130)">
3 | Total sample time (ms)
4 | </text>
5 | <text x="255" y="285" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
6 | Iterations
7 | </text>
8 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="75" y2="15"/>
9 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="134" y1="244" x2="134" y2="15"/>
10 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="194" y1="244" x2="194" y2="15"/>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="254" y1="244" x2="254" y2="15"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="314" y1="244" x2="314" y2="15"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="374" y1="244" x2="374" y2="15"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="434" y1="244" x2="434" y2="15"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="434" y2="244"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="212" x2="434" y2="212"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="180" x2="434" y2="180"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="147" x2="434" y2="147"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="115" x2="434" y2="115"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="83" x2="434" y2="83"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="50" x2="434" y2="50"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="18" x2="434" y2="18"/>
23 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="74,15 74,244 "/>
24 | <text x="65" y="244" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
25 | 0.0
26 | </text>
27 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,244 74,244 "/>
28 | <text x="65" y="212" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
29 | 20.0
30 | </text>
31 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,212 74,212 "/>
32 | <text x="65" y="180" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
33 | 40.0
34 | </text>
35 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,180 74,180 "/>
36 | <text x="65" y="147" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
37 | 60.0
38 | </text>
39 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,147 74,147 "/>
40 | <text x="65" y="115" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
41 | 80.0
42 | </text>
43 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,115 74,115 "/>
44 | <text x="65" y="83" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
45 | 100.0
46 | </text>
47 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,83 74,83 "/>
48 | <text x="65" y="50" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
49 | 120.0
50 | </text>
51 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,50 74,50 "/>
52 | <text x="65" y="18" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
53 | 140.0
54 | </text>
55 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,18 74,18 "/>
56 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 434,245 "/>
57 | <text x="75" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
58 | 0
59 | </text>
60 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 75,250 "/>
61 | <text x="134" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
62 | 50
63 | </text>
64 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="134,245 134,250 "/>
65 | <text x="194" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
66 | 100
67 | </text>
68 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="194,245 194,250 "/>
69 | <text x="254" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
70 | 150
71 | </text>
72 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="254,245 254,250 "/>
73 | <text x="314" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
74 | 200
75 | </text>
76 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="314,245 314,250 "/>
77 | <text x="374" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
78 | 250
79 | </text>
80 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="374,245 374,250 "/>
81 | <text x="434" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
82 | 300
83 | </text>
84 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="434,245 434,250 "/>
85 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="75,244 434,24 "/>
86 | <polygon opacity="0.25" fill="#E31A1C" points="75,244 434,27 434,21 "/>
87 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="75,244 434,15 "/>
88 | <polygon opacity="0.25" fill="#1F78B4" points="75,244 434,20 434,15 "/>
89 | </svg>
90 |
```
--------------------------------------------------------------------------------
/benchmarks/zero-address-check/report/relative_regression_small.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="450" height="300" viewBox="0 0 450 300" xmlns="http://www.w3.org/2000/svg">
2 | <text x="15" y="130" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 15, 130)">
3 | Total sample time (ms)
4 | </text>
5 | <text x="255" y="285" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
6 | Iterations
7 | </text>
8 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="75" y2="15"/>
9 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="134" y1="244" x2="134" y2="15"/>
10 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="194" y1="244" x2="194" y2="15"/>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="254" y1="244" x2="254" y2="15"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="314" y1="244" x2="314" y2="15"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="374" y1="244" x2="374" y2="15"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="434" y1="244" x2="434" y2="15"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="434" y2="244"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="215" x2="434" y2="215"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="185" x2="434" y2="185"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="155" x2="434" y2="155"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="125" x2="434" y2="125"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="95" x2="434" y2="95"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="65" x2="434" y2="65"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="35" x2="434" y2="35"/>
23 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="74,15 74,244 "/>
24 | <text x="65" y="244" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
25 | 0.0
26 | </text>
27 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,244 74,244 "/>
28 | <text x="65" y="215" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
29 | 20.0
30 | </text>
31 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,215 74,215 "/>
32 | <text x="65" y="185" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
33 | 40.0
34 | </text>
35 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,185 74,185 "/>
36 | <text x="65" y="155" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
37 | 60.0
38 | </text>
39 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,155 74,155 "/>
40 | <text x="65" y="125" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
41 | 80.0
42 | </text>
43 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,125 74,125 "/>
44 | <text x="65" y="95" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
45 | 100.0
46 | </text>
47 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,95 74,95 "/>
48 | <text x="65" y="65" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
49 | 120.0
50 | </text>
51 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,65 74,65 "/>
52 | <text x="65" y="35" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
53 | 140.0
54 | </text>
55 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,35 74,35 "/>
56 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 434,245 "/>
57 | <text x="75" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
58 | 0
59 | </text>
60 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 75,250 "/>
61 | <text x="134" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
62 | 50
63 | </text>
64 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="134,245 134,250 "/>
65 | <text x="194" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
66 | 100
67 | </text>
68 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="194,245 194,250 "/>
69 | <text x="254" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
70 | 150
71 | </text>
72 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="254,245 254,250 "/>
73 | <text x="314" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
74 | 200
75 | </text>
76 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="314,245 314,250 "/>
77 | <text x="374" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
78 | 250
79 | </text>
80 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="374,245 374,250 "/>
81 | <text x="434" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
82 | 300
83 | </text>
84 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="434,245 434,250 "/>
85 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="75,244 434,15 "/>
86 | <polygon opacity="0.25" fill="#E31A1C" points="75,244 434,24 434,15 "/>
87 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="75,244 434,45 "/>
88 | <polygon opacity="0.25" fill="#1F78B4" points="75,244 434,47 434,42 "/>
89 | </svg>
90 |
```
--------------------------------------------------------------------------------
/benchmarks/useless-modifier/report/relative_regression_small.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="450" height="300" viewBox="0 0 450 300" xmlns="http://www.w3.org/2000/svg">
2 | <text x="15" y="130" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 15, 130)">
3 | Total sample time (ms)
4 | </text>
5 | <text x="255" y="285" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
6 | Iterations (x 10^3)
7 | </text>
8 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="75" y2="15"/>
9 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="122" y1="244" x2="122" y2="15"/>
10 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="169" y1="244" x2="169" y2="15"/>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="216" y1="244" x2="216" y2="15"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="263" y1="244" x2="263" y2="15"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="311" y1="244" x2="311" y2="15"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="358" y1="244" x2="358" y2="15"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="405" y1="244" x2="405" y2="15"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="434" y2="244"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="207" x2="434" y2="207"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="169" x2="434" y2="169"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="131" x2="434" y2="131"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="93" x2="434" y2="93"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="55" x2="434" y2="55"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="18" x2="434" y2="18"/>
23 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="74,15 74,244 "/>
24 | <text x="65" y="244" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
25 | 0.0
26 | </text>
27 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,244 74,244 "/>
28 | <text x="65" y="207" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
29 | 20.0
30 | </text>
31 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,207 74,207 "/>
32 | <text x="65" y="169" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
33 | 40.0
34 | </text>
35 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,169 74,169 "/>
36 | <text x="65" y="131" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
37 | 60.0
38 | </text>
39 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,131 74,131 "/>
40 | <text x="65" y="93" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
41 | 80.0
42 | </text>
43 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,93 74,93 "/>
44 | <text x="65" y="55" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
45 | 100.0
46 | </text>
47 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,55 74,55 "/>
48 | <text x="65" y="18" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
49 | 120.0
50 | </text>
51 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,18 74,18 "/>
52 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 434,245 "/>
53 | <text x="75" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
54 | 0
55 | </text>
56 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 75,250 "/>
57 | <text x="122" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
58 | 0.5
59 | </text>
60 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="122,245 122,250 "/>
61 | <text x="169" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
62 | 1
63 | </text>
64 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="169,245 169,250 "/>
65 | <text x="216" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
66 | 1.5
67 | </text>
68 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="216,245 216,250 "/>
69 | <text x="263" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
70 | 2
71 | </text>
72 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="263,245 263,250 "/>
73 | <text x="311" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
74 | 2.5
75 | </text>
76 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="311,245 311,250 "/>
77 | <text x="358" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
78 | 3
79 | </text>
80 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="358,245 358,250 "/>
81 | <text x="405" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
82 | 3.5
83 | </text>
84 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="405,245 405,250 "/>
85 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="75,244 434,15 "/>
86 | <polygon opacity="0.25" fill="#E31A1C" points="75,244 434,26 434,15 "/>
87 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="75,244 434,70 "/>
88 | <polygon opacity="0.25" fill="#1F78B4" points="75,244 434,71 434,68 "/>
89 | </svg>
90 |
```
--------------------------------------------------------------------------------
/benchmarks/block-timestamp-deadline/report/relative_regression_small.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="450" height="300" viewBox="0 0 450 300" xmlns="http://www.w3.org/2000/svg">
2 | <text x="15" y="130" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 15, 130)">
3 | Total sample time (ms)
4 | </text>
5 | <text x="255" y="285" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
6 | Iterations
7 | </text>
8 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="75" y2="15"/>
9 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="119" y1="244" x2="119" y2="15"/>
10 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="164" y1="244" x2="164" y2="15"/>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="209" y1="244" x2="209" y2="15"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="254" y1="244" x2="254" y2="15"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="299" y1="244" x2="299" y2="15"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="344" y1="244" x2="344" y2="15"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="389" y1="244" x2="389" y2="15"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="434" y1="244" x2="434" y2="15"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="434" y2="244"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="205" x2="434" y2="205"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="166" x2="434" y2="166"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="126" x2="434" y2="126"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="87" x2="434" y2="87"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="48" x2="434" y2="48"/>
23 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="74,15 74,244 "/>
24 | <text x="65" y="244" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
25 | 0.0
26 | </text>
27 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,244 74,244 "/>
28 | <text x="65" y="205" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
29 | 20.0
30 | </text>
31 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,205 74,205 "/>
32 | <text x="65" y="166" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
33 | 40.0
34 | </text>
35 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,166 74,166 "/>
36 | <text x="65" y="126" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
37 | 60.0
38 | </text>
39 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,126 74,126 "/>
40 | <text x="65" y="87" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
41 | 80.0
42 | </text>
43 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,87 74,87 "/>
44 | <text x="65" y="48" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
45 | 100.0
46 | </text>
47 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,48 74,48 "/>
48 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 434,245 "/>
49 | <text x="75" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
50 | 0
51 | </text>
52 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 75,250 "/>
53 | <text x="119" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
54 | 50
55 | </text>
56 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="119,245 119,250 "/>
57 | <text x="164" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
58 | 100
59 | </text>
60 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="164,245 164,250 "/>
61 | <text x="209" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
62 | 150
63 | </text>
64 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="209,245 209,250 "/>
65 | <text x="254" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
66 | 200
67 | </text>
68 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="254,245 254,250 "/>
69 | <text x="299" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
70 | 250
71 | </text>
72 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="299,245 299,250 "/>
73 | <text x="344" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
74 | 300
75 | </text>
76 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="344,245 344,250 "/>
77 | <text x="389" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
78 | 350
79 | </text>
80 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="389,245 389,250 "/>
81 | <text x="434" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
82 | 400
83 | </text>
84 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="434,245 434,250 "/>
85 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="75,244 434,15 "/>
86 | <polygon opacity="0.25" fill="#E31A1C" points="75,244 434,18 434,15 "/>
87 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="75,244 434,21 "/>
88 | <polygon opacity="0.25" fill="#1F78B4" points="75,244 434,24 434,17 "/>
89 | </svg>
90 |
```
--------------------------------------------------------------------------------
/benchmarks/unsafe-oz-erc721-mint/report/relative_regression_small.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="450" height="300" viewBox="0 0 450 300" xmlns="http://www.w3.org/2000/svg">
2 | <text x="15" y="130" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 15, 130)">
3 | Total sample time (ms)
4 | </text>
5 | <text x="255" y="285" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
6 | Iterations
7 | </text>
8 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="75" y2="15"/>
9 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="119" y1="244" x2="119" y2="15"/>
10 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="164" y1="244" x2="164" y2="15"/>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="209" y1="244" x2="209" y2="15"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="254" y1="244" x2="254" y2="15"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="299" y1="244" x2="299" y2="15"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="344" y1="244" x2="344" y2="15"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="389" y1="244" x2="389" y2="15"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="434" y1="244" x2="434" y2="15"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="434" y2="244"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="204" x2="434" y2="204"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="163" x2="434" y2="163"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="122" x2="434" y2="122"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="81" x2="434" y2="81"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="40" x2="434" y2="40"/>
23 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="74,15 74,244 "/>
24 | <text x="65" y="244" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
25 | 0.0
26 | </text>
27 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,244 74,244 "/>
28 | <text x="65" y="204" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
29 | 20.0
30 | </text>
31 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,204 74,204 "/>
32 | <text x="65" y="163" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
33 | 40.0
34 | </text>
35 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,163 74,163 "/>
36 | <text x="65" y="122" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
37 | 60.0
38 | </text>
39 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,122 74,122 "/>
40 | <text x="65" y="81" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
41 | 80.0
42 | </text>
43 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,81 74,81 "/>
44 | <text x="65" y="40" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
45 | 100.0
46 | </text>
47 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,40 74,40 "/>
48 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 434,245 "/>
49 | <text x="75" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
50 | 0
51 | </text>
52 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 75,250 "/>
53 | <text x="119" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
54 | 50
55 | </text>
56 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="119,245 119,250 "/>
57 | <text x="164" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
58 | 100
59 | </text>
60 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="164,245 164,250 "/>
61 | <text x="209" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
62 | 150
63 | </text>
64 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="209,245 209,250 "/>
65 | <text x="254" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
66 | 200
67 | </text>
68 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="254,245 254,250 "/>
69 | <text x="299" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
70 | 250
71 | </text>
72 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="299,245 299,250 "/>
73 | <text x="344" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
74 | 300
75 | </text>
76 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="344,245 344,250 "/>
77 | <text x="389" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
78 | 350
79 | </text>
80 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="389,245 389,250 "/>
81 | <text x="434" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
82 | 400
83 | </text>
84 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="434,245 434,250 "/>
85 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="75,244 434,46 "/>
86 | <polygon opacity="0.25" fill="#E31A1C" points="75,244 434,48 434,45 "/>
87 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="75,244 434,15 "/>
88 | <polygon opacity="0.25" fill="#1F78B4" points="75,244 434,20 434,15 "/>
89 | </svg>
90 |
```
--------------------------------------------------------------------------------
/benchmarks/unspecific-solidity-pragma/report/both/regression.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="960" height="540" viewBox="0 0 960 540" xmlns="http://www.w3.org/2000/svg">
2 | <text x="480" y="32" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="16.129032258064516" opacity="1" fill="#000000">
3 | unspecific-solidity-pragma
4 | </text>
5 | <text x="27" y="263" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 27, 263)">
6 | Total sample time (ms)
7 | </text>
8 | <text x="510" y="513" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
9 | Iterations (x 10^3)
10 | </text>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="472" x2="87" y2="53"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="225" y1="472" x2="225" y2="53"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="364" y1="472" x2="364" y2="53"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="502" y1="472" x2="502" y2="53"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="641" y1="472" x2="641" y2="53"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="779" y1="472" x2="779" y2="53"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="918" y1="472" x2="918" y2="53"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="472" x2="932" y2="472"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="397" x2="932" y2="397"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="321" x2="932" y2="321"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="245" x2="932" y2="245"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="169" x2="932" y2="169"/>
23 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="93" x2="932" y2="93"/>
24 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="86,53 86,472 "/>
25 | <text x="77" y="472" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
26 | 0.0
27 | </text>
28 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,472 86,472 "/>
29 | <text x="77" y="397" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
30 | 20.0
31 | </text>
32 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,397 86,397 "/>
33 | <text x="77" y="321" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
34 | 40.0
35 | </text>
36 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,321 86,321 "/>
37 | <text x="77" y="245" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
38 | 60.0
39 | </text>
40 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,245 86,245 "/>
41 | <text x="77" y="169" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
42 | 80.0
43 | </text>
44 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,169 86,169 "/>
45 | <text x="77" y="93" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
46 | 100.0
47 | </text>
48 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,93 86,93 "/>
49 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="87,473 932,473 "/>
50 | <text x="87" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
51 | 0
52 | </text>
53 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="87,473 87,478 "/>
54 | <text x="225" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
55 | 1
56 | </text>
57 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="225,473 225,478 "/>
58 | <text x="364" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
59 | 2
60 | </text>
61 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="364,473 364,478 "/>
62 | <text x="502" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
63 | 3
64 | </text>
65 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="502,473 502,478 "/>
66 | <text x="641" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
67 | 4
68 | </text>
69 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="641,473 641,478 "/>
70 | <text x="779" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
71 | 5
72 | </text>
73 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="779,473 779,478 "/>
74 | <text x="918" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
75 | 6
76 | </text>
77 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="918,473 918,478 "/>
78 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="87,472 932,53 "/>
79 | <polygon opacity="0.25" fill="#E31A1C" points="87,472 932,64 932,53 "/>
80 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="87,472 932,98 "/>
81 | <polygon opacity="0.25" fill="#1F78B4" points="87,472 932,100 932,96 "/>
82 | <text x="132" y="68" dy="0.76em" text-anchor="start" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
83 | Base Sample
84 | </text>
85 | <text x="132" y="83" dy="0.76em" text-anchor="start" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
86 | New Sample
87 | </text>
88 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="2" points="102,73 122,73 "/>
89 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="2" points="102,88 122,88 "/>
90 | </svg>
91 |
```
--------------------------------------------------------------------------------
/benchmarks/unsafe-erc20-functions/report/both/regression.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="960" height="540" viewBox="0 0 960 540" xmlns="http://www.w3.org/2000/svg">
2 | <text x="480" y="32" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="16.129032258064516" opacity="1" fill="#000000">
3 | unsafe-erc20-functions
4 | </text>
5 | <text x="27" y="263" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 27, 263)">
6 | Total sample time (ms)
7 | </text>
8 | <text x="510" y="513" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
9 | Iterations (x 10^3)
10 | </text>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="472" x2="87" y2="53"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="237" y1="472" x2="237" y2="53"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="388" y1="472" x2="388" y2="53"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="539" y1="472" x2="539" y2="53"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="690" y1="472" x2="690" y2="53"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="841" y1="472" x2="841" y2="53"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="472" x2="932" y2="472"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="405" x2="932" y2="405"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="338" x2="932" y2="338"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="271" x2="932" y2="271"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="203" x2="932" y2="203"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="136" x2="932" y2="136"/>
23 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="87" y1="69" x2="932" y2="69"/>
24 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="86,53 86,472 "/>
25 | <text x="77" y="472" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
26 | 0.0
27 | </text>
28 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,472 86,472 "/>
29 | <text x="77" y="405" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
30 | 20.0
31 | </text>
32 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,405 86,405 "/>
33 | <text x="77" y="338" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
34 | 40.0
35 | </text>
36 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,338 86,338 "/>
37 | <text x="77" y="271" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
38 | 60.0
39 | </text>
40 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,271 86,271 "/>
41 | <text x="77" y="203" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
42 | 80.0
43 | </text>
44 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,203 86,203 "/>
45 | <text x="77" y="136" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
46 | 100.0
47 | </text>
48 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,136 86,136 "/>
49 | <text x="77" y="69" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
50 | 120.0
51 | </text>
52 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="81,69 86,69 "/>
53 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="87,473 932,473 "/>
54 | <text x="87" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
55 | 0
56 | </text>
57 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="87,473 87,478 "/>
58 | <text x="237" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
59 | 0.5
60 | </text>
61 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="237,473 237,478 "/>
62 | <text x="388" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
63 | 1
64 | </text>
65 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="388,473 388,478 "/>
66 | <text x="539" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
67 | 1.5
68 | </text>
69 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="539,473 539,478 "/>
70 | <text x="690" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
71 | 2
72 | </text>
73 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="690,473 690,478 "/>
74 | <text x="841" y="483" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
75 | 2.5
76 | </text>
77 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="841,473 841,478 "/>
78 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="87,472 932,135 "/>
79 | <polygon opacity="0.25" fill="#E31A1C" points="87,472 932,135 932,134 "/>
80 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="87,472 932,53 "/>
81 | <polygon opacity="0.25" fill="#1F78B4" points="87,472 932,60 932,53 "/>
82 | <text x="132" y="68" dy="0.76em" text-anchor="start" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
83 | Base Sample
84 | </text>
85 | <text x="132" y="83" dy="0.76em" text-anchor="start" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
86 | New Sample
87 | </text>
88 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="2" points="102,73 122,73 "/>
89 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="2" points="102,88 122,88 "/>
90 | </svg>
91 |
```
--------------------------------------------------------------------------------
/aderyn_core/src/detect/high/signed_integer_storage_array.rs:
--------------------------------------------------------------------------------
```rust
1 | use std::{collections::BTreeMap, error::Error, str::FromStr};
2 |
3 | use crate::ast::{
4 | ASTNode, Expression, Identifier, NodeID, TupleExpression, TypeDescriptions, UnaryOperation,
5 | };
6 |
7 | use crate::{
8 | capture,
9 | context::{
10 | browser::{ExtractPragmaDirectives, ExtractTupleExpressions, GetImmediateParent},
11 | workspace::WorkspaceContext,
12 | },
13 | detect::{
14 | detector::{IssueDetector, IssueDetectorNamePool, IssueSeverity},
15 | helpers,
16 | },
17 | };
18 | use eyre::Result;
19 | use lazy_regex::regex;
20 | use semver::{Version, VersionReq};
21 |
22 | #[derive(Default)]
23 | pub struct StorageSignedIntegerArrayDetector {
24 | // Keys are: [0] source file name, [1] line number, [2] character location of node.
25 | // Do not add items manually, use `capture!` to add nodes to this BTreeMap.
26 | found_instances: BTreeMap<(String, usize, String), NodeID>,
27 | }
28 |
29 | impl IssueDetector for StorageSignedIntegerArrayDetector {
30 | fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
31 | for source_unit in context.source_units() {
32 | let tuple_expressions = ExtractTupleExpressions::from(source_unit).extracted;
33 | let pragma_directives = ExtractPragmaDirectives::from(source_unit).extracted;
34 |
35 | if let Some(pragma_directive) = pragma_directives.first()
36 | && let Ok(pragma_semver) = helpers::pragma_directive_to_semver(pragma_directive)
37 | && version_req_allows_below_0_5_10(&pragma_semver)
38 | {
39 | // Search for a literal array with one negative value in it
40 | for tuple_expression in tuple_expressions
41 | .into_iter()
42 | .filter(|tuple_expression| tuple_expression.is_inline_array)
43 | {
44 | // First, make sure it's being assigned to an array pointer to storage
45 | if !is_tuple_being_assigned_to_storage_array(&tuple_expression, context) {
46 | continue;
47 | }
48 |
49 | // Now, make sure there is at least 1 negative value in the tuple array
50 | let negative_component_present = tuple_expression.components.iter().any(|c| {
51 | if let Some(Expression::UnaryOperation(UnaryOperation {
52 | operator, ..
53 | })) = c
54 | {
55 | return operator == "-";
56 | }
57 | false
58 | });
59 |
60 | if negative_component_present {
61 | capture!(self, context, tuple_expression);
62 | }
63 | }
64 | }
65 | }
66 |
67 | Ok(!self.found_instances.is_empty())
68 | }
69 |
70 | fn severity(&self) -> IssueSeverity {
71 | IssueSeverity::High
72 | }
73 |
74 | fn title(&self) -> String {
75 | String::from("Signed integer array in storage (solc `<0.5.10`)")
76 | }
77 |
78 | fn description(&self) -> String {
79 | String::from(
80 | "solc versions 0.4.7-0.5.9 contain a compiler bug leading to incorrect values in signed integer arrays.\
81 | Use solidity version 0.5.10 or above.",
82 | )
83 | }
84 |
85 | fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
86 | self.found_instances.clone()
87 | }
88 |
89 | fn name(&self) -> String {
90 | IssueDetectorNamePool::SignedIntegerStorageArray.to_string()
91 | }
92 | }
93 |
94 | fn version_req_allows_below_0_5_10(version_req: &VersionReq) -> bool {
95 | // If it matches any 0.4.0 to 0.4.26, return true
96 | for i in 0..=26 {
97 | let version = Version::from_str(&format!("0.4.{}", i)).unwrap();
98 | if version_req.matches(&version) {
99 | return true;
100 | }
101 | }
102 |
103 | // If it matches any 0.5.0 to 0.5.9 return true
104 | for i in 0..=9 {
105 | let version = Version::from_str(&format!("0.5.{}", i)).unwrap();
106 | if version_req.matches(&version) {
107 | return true;
108 | }
109 | }
110 |
111 | // Else, return false
112 | false
113 | }
114 |
115 | // Build a regular expression to catch type names that correspond to pointers to storage arrays
116 | static SIGNED_STORAGE_ARRAY_POINTER: &lazy_regex::Lazy<lazy_regex::Regex> =
117 | regex!(r"^int[0-9]*\[[0-9]*] storage ref$");
118 |
119 | fn is_tuple_being_assigned_to_storage_array(
120 | tuple_expression: &TupleExpression,
121 | context: &WorkspaceContext,
122 | ) -> bool {
123 | if let Some(ASTNode::Assignment(assignment)) = tuple_expression.parent(context)
124 | && let Expression::Identifier(Identifier {
125 | type_descriptions: TypeDescriptions { type_string: Some(type_string), .. },
126 | ..
127 | }) = assignment.left_hand_side.as_ref()
128 | && SIGNED_STORAGE_ARRAY_POINTER.is_match(type_string)
129 | {
130 | return true;
131 | }
132 | false
133 | }
134 |
135 | #[cfg(test)]
136 | mod storage_signed_array_detector {
137 |
138 | use crate::detect::{
139 | detector::IssueDetector,
140 | high::signed_integer_storage_array::{
141 | SIGNED_STORAGE_ARRAY_POINTER, StorageSignedIntegerArrayDetector,
142 | },
143 | };
144 |
145 | #[test]
146 |
147 | fn test_storage_signed_array() {
148 | let context = crate::detect::test_utils::load_solidity_source_unit(
149 | "../tests/contract-playground/src/CompilerBugStorageSignedIntegerArray.sol",
150 | );
151 |
152 | let mut detector = StorageSignedIntegerArrayDetector::default();
153 | let found = detector.detect(&context).unwrap();
154 |
155 | assert!(found);
156 | assert_eq!(detector.instances().len(), 1);
157 | }
158 |
159 | #[test]
160 | fn test_regular_expression_works() {
161 | // TARGET signed storage array references
162 |
163 | assert!(SIGNED_STORAGE_ARRAY_POINTER.is_match("int256[3] storage ref"));
164 | assert!(SIGNED_STORAGE_ARRAY_POINTER.is_match("int[1300] storage ref"));
165 | assert!(SIGNED_STORAGE_ARRAY_POINTER.is_match("int8[] storage ref"));
166 | assert!(SIGNED_STORAGE_ARRAY_POINTER.is_match("int[] storage ref"));
167 | assert!(!SIGNED_STORAGE_ARRAY_POINTER.is_match("uint256[3] storage ref"));
168 | assert!(!SIGNED_STORAGE_ARRAY_POINTER.is_match("uint[1300] storage ref"));
169 | assert!(!SIGNED_STORAGE_ARRAY_POINTER.is_match("uint8[] storage ref"));
170 | assert!(!SIGNED_STORAGE_ARRAY_POINTER.is_match("uint[] storage ref"));
171 | }
172 | }
173 |
```
--------------------------------------------------------------------------------
/aderyn_core/src/detect/low/function_pointer_in_constructor.rs:
--------------------------------------------------------------------------------
```rust
1 | use std::{collections::BTreeMap, error::Error};
2 |
3 | use crate::ast::{FunctionKind, NodeID};
4 |
5 | use crate::{
6 | capture,
7 | context::{browser::ExtractVariableDeclarations, workspace::WorkspaceContext},
8 | detect::detector::{IssueDetector, IssueDetectorNamePool, IssueSeverity},
9 | };
10 | use eyre::Result;
11 |
12 | #[derive(Default)]
13 | pub struct FunctionPointerInConstructorDetector {
14 | // Keys are: [0] source file name, [1] line number, [2] character location of node.
15 | // Do not add items manually, use `capture!` to add nodes to this BTreeMap.
16 | found_instances: BTreeMap<(String, usize, String), NodeID>,
17 | }
18 |
19 | impl IssueDetector for FunctionPointerInConstructorDetector {
20 | fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
21 | // PLAN:
22 | // Catch all the function pointers in constructors that compile below 0.5.9
23 |
24 | for func in context
25 | .function_definitions()
26 | .into_iter()
27 | .filter(|f| f.kind() == &FunctionKind::Constructor)
28 | .filter(|f| f.compiles_for_solc_below_0_5_9(context))
29 | {
30 | let variable_declarations = ExtractVariableDeclarations::from(func).extracted;
31 |
32 | for variable_declaration in variable_declarations {
33 | if variable_declaration
34 | .type_descriptions
35 | .type_string
36 | .as_ref()
37 | .is_some_and(|type_string| type_string.starts_with("function "))
38 | {
39 | capture!(self, context, variable_declaration);
40 | }
41 | }
42 | }
43 |
44 | Ok(!self.found_instances.is_empty())
45 | }
46 |
47 | fn severity(&self) -> IssueSeverity {
48 | IssueSeverity::Low
49 | }
50 |
51 | fn title(&self) -> String {
52 | String::from("Function Pointer in Constructor")
53 | }
54 |
55 | fn description(&self) -> String {
56 | String::from(
57 | "solc versions below 0.5.9 contain a compiler bug leading to unexpected behavior when calling uninitialized function pointers in constructors. It is recommended to not use function pointers in constructors.",
58 | )
59 | }
60 |
61 | fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
62 | self.found_instances.clone()
63 | }
64 |
65 | fn name(&self) -> String {
66 | format!("{}", IssueDetectorNamePool::FunctionPointerInConstructor)
67 | }
68 | }
69 |
70 | mod func_compilation_solc_pragma_helper {
71 | use std::str::FromStr;
72 |
73 | use semver::{Version, VersionReq};
74 |
75 | use crate::{
76 | ast::{FunctionDefinition, NodeType},
77 | context::{
78 | browser::{ExtractPragmaDirectives, GetClosestAncestorOfTypeX},
79 | workspace::WorkspaceContext,
80 | },
81 | detect::helpers,
82 | };
83 |
84 | impl FunctionDefinition {
85 | pub fn compiles_for_solc_below_0_5_9(&self, context: &WorkspaceContext) -> bool {
86 | if let Some(source_unit) = self.closest_ancestor_of_type(context, NodeType::SourceUnit)
87 | {
88 | let pragma_directives = ExtractPragmaDirectives::from(source_unit).extracted;
89 |
90 | if let Some(pragma_directive) = pragma_directives.first()
91 | && let Ok(pragma_semver) = helpers::pragma_directive_to_semver(pragma_directive)
92 | && version_req_allows_below_0_5_9(&pragma_semver)
93 | {
94 | return true;
95 | }
96 | }
97 | false
98 | }
99 | pub fn compiles_for_solc_below_0_6_5(&self, context: &WorkspaceContext) -> bool {
100 | if let Some(source_unit) = self.closest_ancestor_of_type(context, NodeType::SourceUnit)
101 | {
102 | let pragma_directives = ExtractPragmaDirectives::from(source_unit).extracted;
103 |
104 | if let Some(pragma_directive) = pragma_directives.first()
105 | && let Ok(pragma_semver) = helpers::pragma_directive_to_semver(pragma_directive)
106 | && version_req_allows_below_0_6_5(&pragma_semver)
107 | {
108 | return true;
109 | }
110 | }
111 | false
112 | }
113 | }
114 |
115 | fn version_req_allows_below_0_5_9(version_req: &VersionReq) -> bool {
116 | // If it matches any 0.4.0 to 0.4.26, return true
117 | for i in 0..=26 {
118 | let version = Version::from_str(&format!("0.4.{}", i)).unwrap();
119 | if version_req.matches(&version) {
120 | return true;
121 | }
122 | }
123 |
124 | // If it matches any 0.5.0 to 0.5.8, return true
125 | for i in 0..=8 {
126 | let version = Version::from_str(&format!("0.5.{}", i)).unwrap();
127 | if version_req.matches(&version) {
128 | return true;
129 | }
130 | }
131 |
132 | // Else, return false
133 | false
134 | }
135 | fn version_req_allows_below_0_6_5(version_req: &VersionReq) -> bool {
136 | // If it matches any 0.4.0 to 0.4.26, return true
137 | for i in 0..=26 {
138 | let version = Version::from_str(&format!("0.4.{}", i)).unwrap();
139 | if version_req.matches(&version) {
140 | return true;
141 | }
142 | }
143 |
144 | // If it matches any 0.5.0 to 0.5.17, return true
145 | for i in 0..=17 {
146 | let version = Version::from_str(&format!("0.5.{}", i)).unwrap();
147 | if version_req.matches(&version) {
148 | return true;
149 | }
150 | }
151 |
152 | // If it matches any 0.6.0 to 0.6.4, return true
153 | for i in 0..=4 {
154 | let version = Version::from_str(&format!("0.4.{}", i)).unwrap();
155 | if version_req.matches(&version) {
156 | return true;
157 | }
158 | }
159 | // Else, return false
160 | false
161 | }
162 | }
163 |
164 | #[cfg(test)]
165 | mod function_pointers_tests {
166 |
167 | use crate::detect::{
168 | detector::IssueDetector,
169 | low::function_pointer_in_constructor::FunctionPointerInConstructorDetector,
170 | };
171 |
172 | #[test]
173 |
174 | fn test_function_pointers() {
175 | let context = crate::detect::test_utils::load_solidity_source_unit(
176 | "../tests/contract-playground/src/FunctionPointers.sol",
177 | );
178 |
179 | let mut detector = FunctionPointerInConstructorDetector::default();
180 | let found = detector.detect(&context).unwrap();
181 | assert!(found);
182 | assert_eq!(detector.instances().len(), 1);
183 | }
184 | }
185 |
```
--------------------------------------------------------------------------------
/aderyn_core/src/detect/low/push_0_opcode.rs:
--------------------------------------------------------------------------------
```rust
1 | use std::{collections::BTreeMap, error::Error};
2 |
3 | use crate::{
4 | ast::NodeID,
5 | capture,
6 | context::workspace::WorkspaceContext,
7 | detect::{
8 | detector::{IssueDetector, IssueDetectorNamePool, IssueSeverity},
9 | helpers::pragma_directive_to_semver,
10 | },
11 | };
12 | use eyre::Result;
13 | use semver::{Op, VersionReq};
14 | use solidity_ast::EvmVersion;
15 |
16 | #[derive(Default)]
17 | pub struct PushZeroOpcodeDetector {
18 | // Keys are: [0] source file name, [1] line number, [2] character location of node.
19 | // Do not add items manually, use `capture!` to add nodes to this BTreeMap.
20 | found_instances: BTreeMap<(String, usize, String), NodeID>,
21 | }
22 |
23 | fn version_req_allows_above_0_8_19(version_req: &VersionReq) -> bool {
24 | match version_req.comparators.len() {
25 | 1 => {
26 | let comp = &version_req.comparators[0];
27 | match comp.op {
28 | Op::Tilde | Op::Caret => comp.major > 0 || comp.minor >= Some(8),
29 | Op::Greater | Op::GreaterEq => true,
30 | Op::Exact => comp.major == 0 && comp.minor == Some(8) && comp.patch == Some(20),
31 | _ => false,
32 | }
33 | }
34 | 2 => {
35 | let comp = &version_req.comparators[1];
36 | match comp.op {
37 | Op::Less | Op::LessEq => {
38 | comp.major > 0
39 | || comp.minor > Some(8)
40 | || (comp.minor == Some(8) && comp.patch >= Some(20))
41 | }
42 | _ => false,
43 | }
44 | }
45 | _ => false,
46 | }
47 | }
48 |
49 | impl IssueDetector for PushZeroOpcodeDetector {
50 | fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
51 | if context.evm_version >= EvmVersion::Shanghai {
52 | for pragma_directive in context.pragma_directives() {
53 | let req = pragma_directive_to_semver(pragma_directive)?;
54 | if version_req_allows_above_0_8_19(&req) {
55 | capture!(self, context, pragma_directive);
56 | }
57 | }
58 | }
59 | Ok(!self.found_instances.is_empty())
60 | }
61 |
62 | fn severity(&self) -> IssueSeverity {
63 | IssueSeverity::Low
64 | }
65 |
66 | fn title(&self) -> String {
67 | String::from("PUSH0 Opcode")
68 | }
69 |
70 | fn description(&self) -> String {
71 | String::from(
72 | "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.",
73 | )
74 | }
75 |
76 | fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
77 | self.found_instances.clone()
78 | }
79 |
80 | fn name(&self) -> String {
81 | format!("{}", IssueDetectorNamePool::PushZeroOpcode)
82 | }
83 | }
84 |
85 | #[cfg(test)]
86 | mod unspecific_solidity_pragma_tests {
87 |
88 | use crate::detect::detector::IssueDetector;
89 |
90 | #[test]
91 |
92 | fn test_push_0_opcode_detector_on_0_8_20_by_loading_contract_directly() {
93 | let context = crate::detect::test_utils::load_solidity_source_unit(
94 | "../tests/contract-playground/src/inheritance/ExtendedInheritance.sol",
95 | );
96 |
97 | let mut detector = super::PushZeroOpcodeDetector::default();
98 | let found = detector.detect(&context).unwrap();
99 | // assert that it found something
100 | assert!(found);
101 | // assert that the number of instances is correct
102 | assert_eq!(detector.instances().len(), 1);
103 | }
104 |
105 | #[test]
106 |
107 | fn test_push_0_opcode_detector_on_range_by_loading_contract_directly() {
108 | let context = crate::detect::test_utils::load_solidity_source_unit(
109 | "../tests/contract-playground/src/CrazyPragma.sol",
110 | );
111 |
112 | let mut detector = super::PushZeroOpcodeDetector::default();
113 | let found = detector.detect(&context).unwrap();
114 | // assert that it found something
115 | assert!(found);
116 | // assert that the number of instances is correct
117 | assert_eq!(detector.instances().len(), 1);
118 | }
119 |
120 | #[test]
121 |
122 | fn test_push_0_opcode_detector_on_0_8_19_by_loading_contract_directly() {
123 | let context = crate::detect::test_utils::load_solidity_source_unit(
124 | "../tests/contract-playground/src/ArbitraryTransferFrom.sol",
125 | );
126 |
127 | let mut detector = super::PushZeroOpcodeDetector::default();
128 | let found = detector.detect(&context).unwrap();
129 | // assert that it found something
130 | assert!(!found);
131 | // assert that the number of instances is correct
132 | assert_eq!(detector.instances().len(), 0);
133 | }
134 |
135 | #[test]
136 |
137 | fn test_push_0_opcode_detector_on_caret_0_8_13_by_loading_contract_directly() {
138 | let context = crate::detect::test_utils::load_solidity_source_unit(
139 | "../tests/contract-playground/src/Counter.sol",
140 | );
141 |
142 | let mut detector = super::PushZeroOpcodeDetector::default();
143 | let found = detector.detect(&context).unwrap();
144 | // assert that it found something
145 | assert!(found);
146 | // assert that the number of instances is correct
147 | assert_eq!(detector.instances().len(), 1);
148 | }
149 |
150 | #[test]
151 |
152 | fn test_push_0_opcode_detector_on_greter_equal_0_8_0_by_loading_contract_directly() {
153 | let context = crate::detect::test_utils::load_solidity_source_unit(
154 | "../tests/contract-playground/src/inheritance/IContractInheritance.sol",
155 | );
156 |
157 | let mut detector = super::PushZeroOpcodeDetector::default();
158 | let found = detector.detect(&context).unwrap();
159 | // assert that it found something
160 | assert!(found);
161 | // assert that the number of instances is correct
162 | assert_eq!(detector.instances().len(), 1);
163 | }
164 |
165 | #[test]
166 |
167 | fn test_push_0_opcode_detector_on_pragma_range_by_loading_contract_directly() {
168 | let context = crate::detect::test_utils::load_solidity_source_unit(
169 | "../tests/contract-playground/src/PragmaRange.sol",
170 | );
171 |
172 | let mut detector = super::PushZeroOpcodeDetector::default();
173 | let found = detector.detect(&context).unwrap();
174 | // assert that it found nothing
175 | assert!(!found);
176 | }
177 | }
178 |
```
--------------------------------------------------------------------------------
/benchmarks/unindexed-events/report/relative_regression_small.svg:
--------------------------------------------------------------------------------
```
1 | <svg width="450" height="300" viewBox="0 0 450 300" xmlns="http://www.w3.org/2000/svg">
2 | <text x="15" y="130" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000" transform="rotate(270, 15, 130)">
3 | Total sample time (ms)
4 | </text>
5 | <text x="255" y="285" dy="-0.5ex" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
6 | Iterations (x 10^3)
7 | </text>
8 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="75" y2="15"/>
9 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="115" y1="244" x2="115" y2="15"/>
10 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="156" y1="244" x2="156" y2="15"/>
11 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="197" y1="244" x2="197" y2="15"/>
12 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="238" y1="244" x2="238" y2="15"/>
13 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="278" y1="244" x2="278" y2="15"/>
14 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="319" y1="244" x2="319" y2="15"/>
15 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="360" y1="244" x2="360" y2="15"/>
16 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="401" y1="244" x2="401" y2="15"/>
17 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="244" x2="434" y2="244"/>
18 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="208" x2="434" y2="208"/>
19 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="172" x2="434" y2="172"/>
20 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="135" x2="434" y2="135"/>
21 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="99" x2="434" y2="99"/>
22 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="63" x2="434" y2="63"/>
23 | <line opacity="0.2" stroke="#000000" stroke-width="1" x1="75" y1="26" x2="434" y2="26"/>
24 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="74,15 74,244 "/>
25 | <text x="65" y="244" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
26 | 0.0
27 | </text>
28 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,244 74,244 "/>
29 | <text x="65" y="208" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
30 | 20.0
31 | </text>
32 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,208 74,208 "/>
33 | <text x="65" y="172" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
34 | 40.0
35 | </text>
36 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,172 74,172 "/>
37 | <text x="65" y="135" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
38 | 60.0
39 | </text>
40 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,135 74,135 "/>
41 | <text x="65" y="99" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
42 | 80.0
43 | </text>
44 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,99 74,99 "/>
45 | <text x="65" y="63" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
46 | 100.0
47 | </text>
48 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,63 74,63 "/>
49 | <text x="65" y="26" dy="0.5ex" text-anchor="end" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
50 | 120.0
51 | </text>
52 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="69,26 74,26 "/>
53 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 434,245 "/>
54 | <text x="75" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
55 | 0
56 | </text>
57 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="75,245 75,250 "/>
58 | <text x="115" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
59 | 0.5
60 | </text>
61 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="115,245 115,250 "/>
62 | <text x="156" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
63 | 1
64 | </text>
65 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="156,245 156,250 "/>
66 | <text x="197" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
67 | 1.5
68 | </text>
69 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="197,245 197,250 "/>
70 | <text x="238" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
71 | 2
72 | </text>
73 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="238,245 238,250 "/>
74 | <text x="278" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
75 | 2.5
76 | </text>
77 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="278,245 278,250 "/>
78 | <text x="319" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
79 | 3
80 | </text>
81 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="319,245 319,250 "/>
82 | <text x="360" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
83 | 3.5
84 | </text>
85 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="360,245 360,250 "/>
86 | <text x="401" y="255" dy="0.76em" text-anchor="middle" font-family="sans-serif" font-size="9.67741935483871" opacity="1" fill="#000000">
87 | 4
88 | </text>
89 | <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="401,245 401,250 "/>
90 | <polyline fill="none" opacity="1" stroke="#E31A1C" stroke-width="1" points="75,244 434,64 "/>
91 | <polygon opacity="0.25" fill="#E31A1C" points="75,244 434,66 434,63 "/>
92 | <polyline fill="none" opacity="1" stroke="#1F78B4" stroke-width="1" points="75,244 434,15 "/>
93 | <polygon opacity="0.25" fill="#1F78B4" points="75,244 434,17 434,15 "/>
94 | </svg>
95 |
```
--------------------------------------------------------------------------------
/aderyn_core/src/detect/high/tautological_compare.rs:
--------------------------------------------------------------------------------
```rust
1 | use std::{collections::BTreeMap, error::Error};
2 |
3 | use crate::ast::{Expression, Identifier, MemberAccess, NodeID};
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 |
15 | #[derive(Default)]
16 | pub struct TautologicalCompareDetector {
17 | // Keys are: [0] source file name, [1] line number, [2] character location of node.
18 | // Do not add items manually, use `capture!` to add nodes to this BTreeMap.
19 | found_instances: BTreeMap<(String, usize, String), NodeID>,
20 | }
21 |
22 | impl IssueDetector for TautologicalCompareDetector {
23 | fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
24 | for binary_operation in context.binary_operations().into_iter().filter(|binary_op| {
25 | ["&&", "||", ">=", ">", "<=", "<"].into_iter().any(|op| op == binary_op.operator)
26 | }) {
27 | match (
28 | binary_operation.left_expression.as_ref(),
29 | binary_operation.right_expression.as_ref(),
30 | ) {
31 | (
32 | Expression::Identifier(Identifier {
33 | referenced_declaration: Some(id0), ..
34 | }),
35 | Expression::Identifier(Identifier {
36 | referenced_declaration: Some(id1), ..
37 | }),
38 | )
39 | | (
40 | Expression::MemberAccess(MemberAccess {
41 | referenced_declaration: Some(id0),
42 | ..
43 | }),
44 | Expression::MemberAccess(MemberAccess {
45 | referenced_declaration: Some(id1),
46 | ..
47 | }),
48 | ) => {
49 | let v0 = get_literal_value_or_constant_variable_value(*id0, context);
50 | let v1 = get_literal_value_or_constant_variable_value(*id1, context);
51 |
52 | let is_equal_in_value = match (v0, v1) {
53 | (Some(ref s0), Some(ref s1)) => s0 == s1,
54 | _ => false,
55 | };
56 |
57 | if is_equal_in_value {
58 | capture!(self, context, binary_operation);
59 | }
60 | }
61 | _ => (),
62 | };
63 |
64 | let orientations = [
65 | (
66 | binary_operation.left_expression.as_ref(),
67 | binary_operation.right_expression.as_ref(),
68 | ),
69 | (
70 | binary_operation.right_expression.as_ref(),
71 | binary_operation.left_expression.as_ref(),
72 | ),
73 | ];
74 |
75 | for (lhs, rhs) in orientations {
76 | match (lhs, rhs) {
77 | (
78 | Expression::Identifier(Identifier {
79 | referenced_declaration: Some(id0),
80 | ..
81 | }),
82 | Expression::MemberAccess(MemberAccess {
83 | referenced_declaration: Some(id1),
84 | ..
85 | }),
86 | ) => {
87 | let v0 = get_literal_value_or_constant_variable_value(*id0, context);
88 | let v1 = get_literal_value_or_constant_variable_value(*id1, context);
89 |
90 | let is_equal_in_value = match (v0, v1) {
91 | (Some(ref s0), Some(ref s1)) => s0 == s1,
92 | _ => false,
93 | };
94 |
95 | if is_equal_in_value {
96 | capture!(self, context, binary_operation);
97 | }
98 | }
99 | (
100 | Expression::Literal(literal),
101 | Expression::MemberAccess(MemberAccess {
102 | referenced_declaration: Some(id1),
103 | ..
104 | }),
105 | )
106 | | (
107 | Expression::Literal(literal),
108 | Expression::Identifier(Identifier {
109 | referenced_declaration: Some(id1),
110 | ..
111 | }),
112 | ) => {
113 | let v0 = literal.value.to_owned();
114 | let v1 = get_literal_value_or_constant_variable_value(*id1, context);
115 |
116 | let is_equal_in_value = match (v0, v1) {
117 | (Some(ref s0), Some(ref s1)) => s0 == s1,
118 | _ => false,
119 | };
120 |
121 | if is_equal_in_value {
122 | capture!(self, context, binary_operation);
123 | }
124 | }
125 | _ => (),
126 | }
127 | }
128 | }
129 |
130 | Ok(!self.found_instances.is_empty())
131 | }
132 |
133 | fn severity(&self) -> IssueSeverity {
134 | IssueSeverity::High
135 | }
136 |
137 | fn title(&self) -> String {
138 | String::from("Tautological comparison")
139 | }
140 |
141 | fn description(&self) -> String {
142 | String::from(
143 | "The left hand side and the right hand side of the binary operation has the same value. This makes the condition always true or always false.",
144 | )
145 | }
146 |
147 | fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
148 | self.found_instances.clone()
149 | }
150 |
151 | fn name(&self) -> String {
152 | IssueDetectorNamePool::TautologicalCompare.to_string()
153 | }
154 | }
155 |
156 | #[cfg(test)]
157 | mod tautological_compare_tests {
158 |
159 | use crate::detect::{
160 | detector::IssueDetector, high::tautological_compare::TautologicalCompareDetector,
161 | };
162 |
163 | #[test]
164 |
165 | fn test_tatulogical_detector() {
166 | let context = crate::detect::test_utils::load_solidity_source_unit(
167 | "../tests/contract-playground/src/TautologicalCompare.sol",
168 | );
169 |
170 | let mut detector = TautologicalCompareDetector::default();
171 | let found = detector.detect(&context).unwrap();
172 | assert!(found);
173 | println!("{:#?}", detector.instances());
174 | assert_eq!(detector.instances().len(), 3);
175 | }
176 | }
177 |
```
--------------------------------------------------------------------------------
/aderyn_core/src/detect/low/incorrect_modifier.rs:
--------------------------------------------------------------------------------
```rust
1 | use std::{
2 | collections::{BTreeMap, HashMap},
3 | error::Error,
4 | };
5 |
6 | use crate::{
7 | ast::NodeID,
8 | capture,
9 | context::{
10 | browser::{ExtractFunctionCalls, ExtractPlaceholderStatements, ExtractRevertStatements},
11 | flow::{Cfg, CfgNodeId},
12 | workspace::WorkspaceContext,
13 | },
14 | detect::detector::{IssueDetector, IssueDetectorNamePool, IssueSeverity},
15 | };
16 | use eyre::Result;
17 |
18 | #[derive(Default)]
19 | pub struct IncorrectUseOfModifierDetector {
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 | hints: BTreeMap<(String, usize, String), String>,
24 | }
25 |
26 | impl IssueDetector for IncorrectUseOfModifierDetector {
27 | fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
28 | // When you have found an instance of the issue,
29 | // use the following macro to add it to `found_instances`:
30 | //
31 | // capture!(self, context, item);
32 | // capture!(self, context, item, "hint");
33 |
34 | for modifier in context.modifier_definitions() {
35 | let Some((cfg, start, _)) = Cfg::from_modifier_body(context, modifier) else {
36 | continue;
37 | };
38 |
39 | if !all_paths_have_revert_or_placeholder(context, &cfg, start) {
40 | capture!(self, context, modifier);
41 | }
42 | }
43 |
44 | Ok(!self.found_instances.is_empty())
45 | }
46 |
47 | fn severity(&self) -> IssueSeverity {
48 | IssueSeverity::Low
49 | }
50 |
51 | fn title(&self) -> String {
52 | String::from("Incorrect Use Of Modifier")
53 | }
54 |
55 | fn description(&self) -> String {
56 | String::from(
57 | "If a modifier does not execute `_` or revert, the execution of the function will return the default value, which can be misleading for the caller. It is recommended that all the paths in a modifier must execute _ or revert.",
58 | )
59 | }
60 |
61 | fn instances(&self) -> BTreeMap<(String, usize, String), NodeID> {
62 | self.found_instances.clone()
63 | }
64 |
65 | fn hints(&self) -> BTreeMap<(String, usize, String), String> {
66 | self.hints.clone()
67 | }
68 |
69 | fn name(&self) -> String {
70 | IssueDetectorNamePool::IncorrectUseOfModifier.to_string()
71 | }
72 | }
73 |
74 | fn all_paths_have_revert_or_placeholder(
75 | context: &WorkspaceContext,
76 | cfg: &Cfg,
77 | start: CfgNodeId,
78 | ) -> bool {
79 | // First bit on signifies revert is present in the path so far
80 | // Second bit on signifies placeholder is present in the path so far
81 | // ----------------------------
82 | // value | placeholder | revert
83 | // ----------------------------
84 | // 00 | N | N
85 | // 01 | N | Y
86 | // 10 | Y | N
87 | // 11 | Y | Y
88 | // ----------------------------
89 | type SoFar = usize;
90 |
91 | let mut visited = Default::default();
92 | let mut answers = Default::default();
93 |
94 | fn _all_paths_have_revert_or_placeholder(
95 | context: &WorkspaceContext,
96 | cfg: &Cfg,
97 | visited: &mut HashMap<CfgNodeId, Vec<bool>>,
98 | answers: &mut HashMap<CfgNodeId, Vec<bool>>,
99 | curr_node: CfgNodeId,
100 | so_far: SoFar,
101 | ) -> bool {
102 | if let Some(visited_node) = visited.get(&curr_node)
103 | && visited_node[so_far]
104 | {
105 | return answers.get(&curr_node).expect("answers corrupted!")[so_far];
106 | }
107 |
108 | let curr_cfg_node = cfg.nodes.get(&curr_node).expect("cfg is incomplete!");
109 |
110 | let mut inc: SoFar = so_far;
111 |
112 | if let Some(curr_ast_node) = curr_cfg_node.reflect(context) {
113 | // Check for placeholders in the current node
114 | let placeholders_in_curr_node =
115 | ExtractPlaceholderStatements::from(curr_ast_node).extracted;
116 |
117 | if !placeholders_in_curr_node.is_empty() {
118 | inc |= 1 << 1;
119 | }
120 |
121 | if (1 & inc) == 0 {
122 | // Check for possibility of revert
123 |
124 | let func_calls = ExtractFunctionCalls::from(curr_ast_node).extracted;
125 | if !func_calls.is_empty() {
126 | inc |= 1;
127 | }
128 |
129 | let revert_stmts = ExtractRevertStatements::from(curr_ast_node).extracted;
130 | if !revert_stmts.is_empty() {
131 | inc |= 1;
132 | }
133 | }
134 | }
135 |
136 | // At least one of placeholders/revert is present
137 | if inc != 0 {
138 | let visited_node = visited.entry(curr_node).or_insert_with(|| vec![false; 4]);
139 | visited_node[so_far] = true;
140 |
141 | let answer_node = answers.entry(curr_node).or_insert_with(|| vec![false; 4]);
142 | answer_node[so_far] = true;
143 |
144 | return true;
145 | }
146 |
147 | let children = curr_node.children(cfg);
148 |
149 | if children.is_empty() {
150 | let visited_node = visited.entry(curr_node).or_insert_with(|| vec![false; 4]);
151 | visited_node[so_far] = true;
152 |
153 | let answer_node = answers.entry(curr_node).or_insert_with(|| vec![false; 4]);
154 | answer_node[so_far] = false;
155 |
156 | return false;
157 | }
158 |
159 | let mut answer = true;
160 |
161 | for child in children {
162 | answer &=
163 | _all_paths_have_revert_or_placeholder(context, cfg, visited, answers, child, inc);
164 | }
165 |
166 | let visited_node = visited.entry(curr_node).or_insert_with(|| vec![false; 4]);
167 | visited_node[so_far] = true;
168 |
169 | let answer_node = answers.entry(curr_node).or_insert_with(|| vec![false; 4]);
170 | answer_node[so_far] = answer;
171 |
172 | answer
173 | }
174 |
175 | _all_paths_have_revert_or_placeholder(context, cfg, &mut visited, &mut answers, start, 0);
176 |
177 | let final_answer = answers.entry(start).or_default();
178 |
179 | // '0' because we start from having nothing
180 | final_answer[0]
181 | }
182 |
183 | #[cfg(test)]
184 | mod test_incorrect_modifier {
185 |
186 | use crate::detect::{
187 | detector::IssueDetector, low::incorrect_modifier::IncorrectUseOfModifierDetector,
188 | };
189 |
190 | #[test]
191 |
192 | fn test_incorrect_modifier_detector() {
193 | let context = crate::detect::test_utils::load_solidity_source_unit(
194 | "../tests/contract-playground/src/IncorrectModifier.sol",
195 | );
196 | let mut detector = IncorrectUseOfModifierDetector::default();
197 | let found = detector.detect(&context).unwrap();
198 | assert!(found);
199 |
200 | assert_eq!(detector.instances().len(), 2);
201 | }
202 | }
203 |
```