Skip to content

Commit 2afe254

Browse files
committed
Add uint256[] memory test to integration tests
1 parent 2200d0d commit 2afe254

1 file changed

Lines changed: 99 additions & 2 deletions

File tree

packages/pointers/src/dereference/index.integration.test.ts

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,106 @@ export type ObserveTraceTests<M extends { [name: string]: any }> = {
2525
* for additional unexpected values in between and around the expected values.
2626
*/
2727
export const observeTraceTests: ObserveTraceTests<{
28-
"storage string": string;
28+
"string storage": string;
29+
"uint256[] memory": number[];
2930
}> = {
30-
"storage string": {
31+
"uint256[] memory": {
32+
pointer: findExamplePointer("uint256-array-memory-pointer-slot"),
33+
compileOptions: prepareCompileOptions({
34+
path: "Uint256Arraymemory.sol",
35+
contractName: "Uint256ArrayMemory",
36+
content: `contract Uint256ArrayMemory {
37+
constructor() {
38+
uint256[] memory values = new uint256[](0);
39+
values = appendToArray(values, 1);
40+
values = appendToArray(values, 2);
41+
values = appendToArray(values, 3);
42+
}
43+
44+
function appendToArray(
45+
uint256[] memory arr,
46+
uint256 value
47+
)
48+
private
49+
pure
50+
returns (uint256[] memory)
51+
{
52+
uint256[] memory newArray = new uint256[](arr.length + 1);
53+
54+
for (uint i = 0; i < arr.length; i++) {
55+
newArray[i] = arr[i];
56+
}
57+
58+
newArray[arr.length] = value;
59+
return newArray;
60+
}
61+
}
62+
`
63+
}),
64+
65+
expectedValues: [
66+
[],
67+
[1],
68+
[1, 2],
69+
[1, 2, 3]
70+
],
71+
72+
async observe({ regions, read }, state): Promise<number[]> {
73+
const items = regions.named("array-item");
74+
75+
return (await Promise.all(
76+
items.map(async (item) => {
77+
const data = await read(item);
78+
79+
return Number(data.asUint());
80+
})
81+
));
82+
},
83+
84+
equals(a, b) {
85+
if (a.length !== b.length) {
86+
return false;
87+
}
88+
89+
for (const [index, value] of a.entries()) {
90+
if (b[index] !== value) {
91+
return false;
92+
}
93+
}
94+
95+
return true;
96+
},
97+
98+
// this function uses observation of solc + viaIR behavior to determine
99+
// that the memory array we're looking for is going to have a pointer at
100+
// the bottom of the stack
101+
//
102+
// also include a check to exclude observation when that bottom stack value
103+
// would have `cursor.view` produce a ton of regions.
104+
async shouldObserve(state) {
105+
const stackLength = await state.stack.length;
106+
if (stackLength === 0n) {
107+
return false;
108+
}
109+
110+
// only consider the bottom of the stack
111+
const arrayOffset = await state.stack.peek({ depth: stackLength - 1n });
112+
113+
const arrayCount = await state.memory.read({
114+
slice: {
115+
offset: arrayOffset.asUint(),
116+
length: 32n
117+
}
118+
})
119+
120+
// return false;
121+
const isObservable = arrayCount.asUint() < 4n;
122+
if (isObservable) {
123+
}
124+
return isObservable;
125+
}
126+
},
127+
"string storage": {
31128
pointer: findExamplePointer("string-storage-contract-variable-slot"),
32129

33130
compileOptions: prepareCompileOptions({

0 commit comments

Comments
 (0)