1
1
diff -ruN DoubleLinkedList.sol DoubleLinkedList.sol
2
- --- DoubleLinkedList.sol 2023-05-23 16:01:50.888803463 +0200
3
- +++ DoubleLinkedList.sol 2023-05-23 16:34:10.324900474 +0200
4
- @@ -18,6 +18,8 @@
2
+ --- DoubleLinkedList.sol
3
+ +++ DoubleLinkedList.sol
4
+ @@ -16,6 +16,8 @@
5
+
6
+ struct List {
5
7
mapping(address => Account) accounts;
6
- address head;
7
- address tail;
8
8
+ address insertedBefore; // HARNESS: address of the account before which the account was inserted at last insertion.
9
9
+ address insertedAfter; // HARNESS: address of the account after which the account was inserted at last insertion.
10
10
}
11
11
12
12
/* ERRORS */
13
- @@ -93,24 +95,23 @@
13
+ @@ -90,21 +92,20 @@
14
14
/// @param list The list to search in.
15
15
/// @param id The address of the account.
16
16
/// @param value The value of the account.
@@ -21,120 +21,18 @@ diff -ruN DoubleLinkedList.sol DoubleLinkedList.sol
21
21
if (id == address(0)) revert AddressIsZero();
22
22
if (list.accounts[id].value != 0) revert AccountAlreadyInserted();
23
23
24
- - uint256 numberOfIterations;
25
- - address next = list.head; // If not added at the end of the list `id` will be inserted before `next`.
26
- + list.insertedAfter = address(0);
27
- + address next = list.head; // `id` will be inserted before `next`.
24
+ address next = getHead(list); // `id` will be inserted before `next`.
28
25
29
- - while (numberOfIterations < maxIterations && next != address(0) && list.accounts[next].value >= value) {
30
- + while (next != address(0) && list.accounts[next].value >= value) {
31
- + list.insertedAfter = next;
32
- next = list.accounts[next].next;
33
- - unchecked {
34
- - ++numberOfIterations;
35
- - }
26
+ - uint256 numberOfIterations;
27
+ - for (; numberOfIterations < maxIterations; numberOfIterations++) {
28
+ + for (;;) {
29
+ if (next == address(0) || list.accounts[next].value < value) break;
30
+ + list.insertedAfter = next; // HARNESS
31
+ next = getNext(list, next);
36
32
}
37
33
38
- + list.insertedBefore = next;
39
- +
40
- // Account is not the new tail.
41
- - if (numberOfIterations < maxIterations && next != address(0)) {
42
- + if (next != address(0)) {
43
- // Account is the new head.
44
- if (next == list.head) {
45
- list.accounts[id] = Account({prev: address(0), next: next, value: value});
46
- diff -ruN MockDLL.sol MockDLL.sol
47
- --- MockDLL.sol 1970-01-01 01:00:00.000000000 +0100
48
- +++ MockDLL.sol 2023-05-23 16:16:00.233326262 +0200
49
- @@ -0,0 +1,91 @@
50
- + // SPDX-License-Identifier: AGPL-3.0-only
51
- + pragma solidity ^0.8.0;
52
- +
53
- + import "./DoubleLinkedList.sol";
54
- +
55
- + contract MockDLL {
56
- + using DoubleLinkedList for DoubleLinkedList.List;
57
- +
58
- + // VERIFICATION INTERFACE
59
- +
60
- + DoubleLinkedList.List public dll;
61
- +
62
- + uint256 internal dummy_state_variable;
63
- +
64
- + function dummy_state_modifying_function() public {
65
- + // to fix a CVL error when only one function is accessible
66
- + dummy_state_variable = 1;
67
- + }
68
- +
69
- + function getValueOf(address _id) public view returns (uint256) {
70
- + return dll.getValueOf(_id);
71
- + }
72
- +
73
- + function getHead() public view returns (address) {
74
- + return dll.getHead();
75
- + }
76
- +
77
- + function getTail() public view returns (address) {
78
- + return dll.getTail();
79
- + }
80
- +
81
- + function getNext(address _id) public view returns (address) {
82
- + return dll.getNext(_id);
83
- + }
84
- +
85
- + function getPrev(address _id) public view returns (address) {
86
- + return dll.getPrev(_id);
87
- + }
88
- +
89
- + function remove(address _id) public {
90
- + dll.remove(_id);
91
- + }
92
- +
93
- + function insertSorted(address _id, uint256 _value) public {
94
- + dll.insertSorted(_id, _value);
95
- + }
96
- +
97
- + // SPECIFICATION HELPERS
98
- +
99
- + function getInsertedAfter() public view returns (address) {
100
- + return dll.insertedAfter;
101
- + }
102
- +
103
- + function getInsertedBefore() public view returns (address) {
104
- + return dll.insertedBefore;
105
- + }
106
- +
107
- + function getLength() internal view returns (uint256) {
108
- + uint256 len;
109
- + for (address current = getHead(); current != address(0); current = getNext(current)) len++;
110
- + return len;
111
- + }
112
- +
113
- + function linkBetween(address _start, address _end) internal view returns (bool, address) {
114
- + if (_start == _end) return (true, address(0));
115
- + for (uint256 maxIter = getLength(); maxIter > 0; maxIter--) {
116
- + address next = getNext(_start);
117
- + if (next == _end) return (true, _start);
118
- + _start = next;
119
- + }
120
- + return (false, address(0));
121
- + }
122
- +
123
- + function isForwardLinkedBetween(address _start, address _end) public view returns (bool ret) {
124
- + (ret, ) = linkBetween(_start, _end);
125
- + }
126
- +
127
- + function getPreceding(address _end) public view returns (address last) {
128
- + (, last) = linkBetween(getHead(), _end);
129
- + }
130
- +
131
- + function isDecrSortedFrom(address _start) public view returns (bool) {
132
- + for (uint256 maxIter = getLength(); maxIter > 0; maxIter--) {
133
- + address next = getNext(_start);
134
- + if (next == address(0)) return true;
135
- + if (getValueOf(_start) < getValueOf(next)) return false;
136
- + _start = getNext(_start);
137
- + }
138
- + return true;
139
- + }
140
- + }
34
+ - if (numberOfIterations == maxIterations) next = address(0);
35
+ + list.insertedBefore = next; // HARNESS
36
+
37
+ address prev = getPrev(list, next);
38
+ list.accounts[id] = Account(prev, next, value);
0 commit comments