Skip to content

Commit

Permalink
Entry points Audit Mode
Browse files Browse the repository at this point in the history
  • Loading branch information
alexroan committed Mar 6, 2025
1 parent 7855ecc commit cfd3889
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
3 changes: 2 additions & 1 deletion aderyn_core/src/audit/auditor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use prettytable::{format, Row, Table};

use crate::{
audit::{
attack_surface::AttackSurfaceDetector,
attack_surface::AttackSurfaceDetector, entry_points::EntryPointsDetector,
public_functions_no_sender::PublicFunctionsNoSenderChecksDetector,
},
context::workspace_context::WorkspaceContext,
Expand All @@ -14,6 +14,7 @@ pub fn get_auditor_detectors() -> Vec<Box<dyn AuditorDetector>> {
vec![
Box::<AttackSurfaceDetector>::default(),
Box::<PublicFunctionsNoSenderChecksDetector>::default(),
Box::<EntryPointsDetector>::default(),
]
}

Expand Down
101 changes: 101 additions & 0 deletions aderyn_core/src/audit/entry_points.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use prettytable::{row, Row};

use super::auditor::AuditorDetector;
use crate::{
ast::{FunctionKind, NodeType},
context::workspace_context::{ASTNode, WorkspaceContext},
detect::helpers::get_implemented_external_and_public_functions,
};
use std::{cmp::Ordering, collections::BTreeSet, error::Error};

#[derive(Clone, Eq, PartialEq)]
pub struct EntryPointsInstance {
pub contract_name: String,
pub function_name: String,
pub function_kind: FunctionKind,
}

impl Ord for EntryPointsInstance {
fn cmp(&self, other: &Self) -> Ordering {
let by_contract = self.contract_name.cmp(&other.contract_name);
if by_contract == Ordering::Equal {
self.function_name.cmp(&other.function_name)
} else {
by_contract
}
}
}

impl PartialOrd for EntryPointsInstance {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

#[derive(Default)]
pub struct EntryPointsDetector {
// contract_name, function_name
found_instances: BTreeSet<EntryPointsInstance>,
}

impl AuditorDetector for EntryPointsDetector {
fn detect(&mut self, context: &WorkspaceContext) -> Result<bool, Box<dyn Error>> {
let functions = get_implemented_external_and_public_functions(context);
functions.for_each(|function_definition| {
if let ASTNode::ContractDefinition(contract_definition) = context
.get_closest_ancestor(function_definition.id, NodeType::ContractDefinition)
.unwrap()
{
let contract_name = contract_definition.name.clone();
self.found_instances.insert(EntryPointsInstance {
contract_name,
function_name: function_definition.name.clone(),
function_kind: function_definition.kind().clone(),
});
}
});
Ok(!self.found_instances.is_empty())
}

fn title(&self) -> String {
String::from("Contract Entry Points")
}

fn skeletal_clone(&self) -> Box<dyn AuditorDetector> {
Box::<EntryPointsDetector>::default()
}

fn table_titles(&self) -> Row {
row!["Contract", "Function Kind", "Function Name"]
}

fn table_rows(&self) -> Vec<Row> {
self.found_instances
.iter()
.map(|instance| {
row![instance.contract_name, instance.function_kind, instance.function_name,]
})
.collect()
}
}

#[cfg(test)]
mod public_functions_no_sender_checks {
use crate::{
audit::{auditor::AuditorDetector, entry_points::EntryPointsDetector},
detect::test_utils::load_solidity_source_unit,
};

#[test]
fn test_public_functions_no_sender_checks() {
let context = load_solidity_source_unit(
"../tests/contract-playground/src/auditor_mode/PublicFunctionsWithoutSenderCheck.sol",
);

let mut detector = EntryPointsDetector::default();
let found = detector.detect(&context).unwrap();
// assert that the detector found an issue
assert!(found);
assert!(detector.found_instances.len() == 11);
}
}
1 change: 1 addition & 0 deletions aderyn_core/src/audit/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod attack_surface;
pub mod auditor;
pub mod entry_points;
pub mod public_functions_no_sender;

0 comments on commit cfd3889

Please sign in to comment.