Omniscia Bonq Audit
linked-address-list Code Style Findings
linked-address-list Code Style Findings
LIN-01C: Generic Typographic Mistakes
Type | Severity | Location |
---|---|---|
Code Style | linked-address-list.sol:L29, L31 |
Description:
The referenced lines contain typographical mistakes or generic documentational errors (i.e. copy-paste) that should be corrected.
Example:
29"79d3d ref must exist or be 0x0"
Recommendation:
We advise them to be corrected enhancing the legibility of the codebase.
Alleviation:
The Bonq Protocol team has partially fixed the issue by correcting the revert string while the documentation error still exists.
LIN-02C: Inconsistent Logical Checks
Type | Severity | Location |
---|---|---|
Code Style | linked-address-list.sol:L94 |
Description:
The linked check performed is based on an indirect assumption by the system instead of directly evaluating that the _element
is equal to the _list._first
data entry, similarly to the last element evaluation.
Example:
90} else if (_element == _list._last) {91 // simplified process for removing the last element92 _list._last = _list._values[_element].prev;93 _list._values[_list._last].next = _list._last;94} else if (_element == _list._values[_element].prev) {95 // simplified process for removing the first element96 address next = _list._values[_element].next;97 _list._values[next].prev = next;98 _list._first = next;99} else {
Recommendation:
We advise the code to be updated to use the same logical checks across its structure and the comparison to be performed with the list's _first
data entry.
Alleviation:
The Bonq Protocol team has corrected the logical checks.
LIN-03C: Inefficient Utilization of Data Entries
Type | Severity | Location |
---|---|---|
Gas Optimization | linked-address-list.sol:L92-L93 |
Description:
The _list._last
data entry is read three times redundantly instead of being stored to a local variable similarly to the removal process of the first element.
Example:
90} else if (_element == _list._last) {91 // simplified process for removing the last element92 _list._last = _list._values[_element].prev;93 _list._values[_list._last].next = _list._last;94} else if (_element == _list._values[_element].prev) {95 // simplified process for removing the first element96 address next = _list._values[_element].next;97 _list._values[next].prev = next;98 _list._first = next;99} else {
Recommendation:
We advise the codebase to be optimized as such by caching the result of _list._values[_element].prev
to a local variable and consequently utilizing it for the assignments.
Alleviation:
The Bonq Protocol team has fixed the issue by optimizing the statements.
LIN-04C: Inefficient mapping
Lookups
Type | Severity | Location |
---|---|---|
Gas Optimization | linked-address-list.sol:L37-L38, L49-L50, L57-L58, L64-L65, L69-L70 |
Description:
The linked statements perform key-based lookup operations on mapping
declarations from storage multiple times for the same key redundantly.
Example:
31// the lement must not exist in order to be added32if (_list._values[_element].prev == address(0x0)) {33 // the list is empty34 if (_list._last == address(0x0)) {35 // console.log("the list is empty, adding", _element, "as only element");36 // if it is the first element in the list, it refers to itself to indicate this37 _list._values[_element].prev = _element;38 _list._values[_element].next = _element;39 // the new element is now officially the first40 _list._first = _element;41 // the new element is now officially the last42 _list._last = _element;43 } else {44 if (_before && (_reference == address(0x0) || _reference == _list._first)) {45 // console.log("the list has %s elements. adding %s as first element", _list._size, _element);46 // the element should be added as the first element47 address first = _list._first;48 _list._values[first].prev = _element;49 _list._values[_element].prev = _element;50 _list._values[_element].next = first;51 _list._first = _element;52 } else if (!_before && (_reference == address(0x0) || _reference == _list._last)) {53 // console.log("the list has %s elements. adding %s as last element", _list._size, _element);54 // the element should be added as the last element55 address last = _list._last;56 _list._values[last].next = _element;57 _list._values[_element].prev = last;58 _list._values[_element].next = _element;59 _list._last = _element;60 } else {61 // the element should be inserted in between two elements62 EntryLink memory ref = _list._values[_reference];63 if (_before) {64 _list._values[_element].prev = ref.prev;65 _list._values[_element].next = _reference;66 _list._values[_reference].prev = _element;67 _list._values[ref.prev].next = _element;68 } else {69 _list._values[_element].prev = _reference;70 _list._values[_element].next = ref.next;71 _list._values[_reference].next = _element;72 _list._values[ref.next].prev = _element;73 }74 // console.log("the list has '%s' elements. inserting '%s' ", _list._size, _element);75 }76 }77 // console.log("between %s and %s", _list._values[_element].prev, _list._values[_element].next);78 _list._size = _list._size + 1;79 return true;80}
Recommendation:
As the lookups internally perform an expensive keccak256
operation, we advise the lookups to be cached wherever possible to a single local declaration that either holds the value of the mapping
in case of primitive types or holds a storage
pointer to the struct
contained.
Alleviation:
The Bonq Protocol team has fixed the issue by storing a storage
pointer to the struct
.