Skip to content

Commit 56e5da5

Browse files
authored
Recognise the proxy slot pattern (#95)
This commit implements a feature for the analyzer to recognise the commonly used proxy-slot pattern. It does this by a limited form of constant folding for values that are likely to be hashes of encoded strings. This commit also improves the analyzer by causing it to constant fold lengths in memory reads, thereby giving itself more accurate information about the values actually being passed around in the program.
1 parent 24b0d97 commit 56e5da5

24 files changed

+956
-106
lines changed

src/analyzer/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ impl Analyzer<state::VMReady> {
244244
impl Analyzer<state::ExecutionComplete> {
245245
/// Takes thew results of execution and uses them to prepare a new inference
246246
/// engine.
247+
#[allow(clippy::missing_panics_doc)] // Explicit closure can never return Err
247248
#[must_use]
248249
pub fn prepare_unifier(self) -> Analyzer<state::InferenceReady> {
249250
unsafe {

src/constant.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ pub const DEFAULT_CONDITIONAL_JUMP_PER_TARGET_FORK_LIMIT: usize = 50;
9191
/// culled.
9292
pub const DEFAULT_VALUE_SIZE_LIMIT: usize = 250;
9393

94-
/// The number of loop iterations the analyzer will wait before polling the
95-
/// watchdog.
94+
/// The default number of loop iterations the analyzer will wait before polling
95+
/// the watchdog.
9696
pub const DEFAULT_WATCHDOG_POLL_LOOP_ITERATIONS: usize = 100;
97+
98+
/// The value that solidity uses to type tag `string` in ABI encoding.
99+
pub const SOLIDITY_STRING_POINTER: usize = 0x20;

src/inference/lift/dynamic_array_access.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,13 @@ impl Lift for DynamicArrayIndex {
7373
} else {
7474
return None;
7575
}
76-
.clone()
77-
.constant_fold();
76+
.clone();
77+
78+
let data = match data.data() {
79+
RSVD::Concat { values } if values.len() == 1 => values[0].clone().constant_fold(),
80+
RSVD::Concat { .. } => return None,
81+
_ => data,
82+
};
7883

7984
let access = RSVD::DynamicArrayIndex {
8085
slot: data.transform_data(lift_dyn_array_accesses),

src/inference/lift/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod mapping_index;
77
pub mod mapping_offset;
88
pub mod mul_shifted;
99
pub mod packed_encoding;
10+
pub mod proxy_slots;
1011
pub mod recognise_hashed_slots;
1112
pub mod storage_slots;
1213
pub mod sub_word;
@@ -27,6 +28,7 @@ use crate::{
2728
mapping_offset::MappingOffset,
2829
mul_shifted::MulShiftedValue,
2930
packed_encoding::PackedEncoding,
31+
proxy_slots::ProxySlots,
3032
recognise_hashed_slots::StorageSlotHashes,
3133
storage_slots::StorageSlots,
3234
sub_word::SubWordValue,
@@ -130,6 +132,7 @@ impl Default for LiftingPasses {
130132
Self {
131133
passes: vec![
132134
StorageSlotHashes::new(),
135+
ProxySlots::new(),
133136
MappingIndex::new(),
134137
SubWordValue::new(),
135138
MulShiftedValue::new(),

0 commit comments

Comments
 (0)