-
Notifications
You must be signed in to change notification settings - Fork 288
/
Array-deletion.sol
95 lines (74 loc) · 2.83 KB
/
Array-deletion.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "forge-std/Test.sol";
/*
Name: Array Deletion Oversight: leading to data inconsistency
Description:
In Solidity where improper deletion of elements from dynamic arrays can result in data inconsistency.
When attempting to delete elements from an array, if the deletion process is not handled correctly,
the array may still retain storage space and exhibit unexpected behavior.
Mitigation:
Option1: By copying the last element and placing it in the position to be removed.
Option2: By shifting them from right to left.
REF:
https://twitter.com/1nf0s3cpt/status/1677167550277509120
https://blog.solidityscan.com/improper-array-deletion-82672eed8e8d
https://github.com/sherlock-audit/2023-03-teller-judging/issues/88
*/
contract ContractTest is Test {
ArrayDeletionBug ArrayDeletionBugContract;
FixedArrayDeletion FixedArrayDeletionContract;
function setUp() public {
ArrayDeletionBugContract = new ArrayDeletionBug();
FixedArrayDeletionContract = new FixedArrayDeletion();
}
function testArrayDeletion() public {
ArrayDeletionBugContract.myArray(1);
//delete incorrectly
ArrayDeletionBugContract.deleteElement(1);
ArrayDeletionBugContract.myArray(1);
ArrayDeletionBugContract.getLength();
}
function testFixedArrayDeletion() public {
FixedArrayDeletionContract.myArray(1);
//delete incorrectly
FixedArrayDeletionContract.deleteElement(1);
FixedArrayDeletionContract.myArray(1);
FixedArrayDeletionContract.getLength();
}
receive() external payable {}
}
contract ArrayDeletionBug {
uint[] public myArray = [1, 2, 3, 4, 5];
function deleteElement(uint index) external {
require(index < myArray.length, "Invalid index");
delete myArray[index];
}
function getLength() public view returns (uint) {
return myArray.length;
}
}
contract FixedArrayDeletion {
uint[] public myArray = [1, 2, 3, 4, 5];
//Mitigation 1: By copying the last element and placing it in the position to be removed.
function deleteElement(uint index) external {
require(index < myArray.length, "Invalid index");
// Swap the element to be deleted with the last element
myArray[index] = myArray[myArray.length - 1];
// Delete the last element
myArray.pop();
}
/*Mitigation 2: By shifting them from right to left.
function deleteElement(uint index) external {
require(index < myArray.length, "Invalid index");
for (uint i = _index; i < myArray.length - 1; i++) {
myArray[i] = myArray[i + 1];
}
// Delete the last element
myArray.pop();
}
*/
function getLength() public view returns (uint) {
return myArray.length;
}
}