You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the following locations, the auditors identified opportunities to improve code quality and increase adherence to TypeScript best practices:
o1js/src/lib/provable/merkle-list.ts:
MerkleList.forEach(): Consider putting the isDummy argument first in the callback. In TypeScript, (element: T) => void will type-check as an instance of (element: T, isDummy: Bool, i: numbere) => void, but this almost certainly signals an error by the user.
MerkleList.popIf(): this.data is supposed to restore the state from before pop() if the condition evaluates to false. However, if the list was empty, and the condition was false, then the data beforehand was []. Restoring the state should keep it as [], rather than changing it to [{previousHash: emptyHash, element: provable.empty()}].
Luckily, this new list is functionally the same for the purposes of a MerkleList. Nonetheless, restoring the original data may prevent prover errors in the future.
MerkleListIterator.previous(): An inline comment mentions that “it returns a dummy element if we're at the start of the array". Note that a MerkleListIterator has two array-like structures:
The underlying JavaScript array, which is in the reverse order of the list.
The list, represented by the sequence of hashes.
We recommend clarifying in this comment that previous() returns a dummy element if at the start of the list, which corresponds to the end of the array.
MerkleList.next(): Unlike MerkleList.previous(), MerkleList.next() does not prove membership in the list. Instead, it only computes the “next hash” if this element were appended to the current hash.
This adds a very important caller requirement: users must remember to assert the iterator is at the end of the list! Otherwise, the circuit will be under-constrained.
We recommend adding documentation to next() warning of this fact, and moving it into the Unsafe module. If a “safe” implementation is required, we recommend requiring users to provide a function implementing their desired invocation of next(), which can be executed within a context that is guaranteed to call assertAtEnd().
The text was updated successfully, but these errors were encountered:
kantp
added
audit
Addresses findings from the audit
info
o1js
Issues that require changes in o1js itself, rather than in this repository
labels
Jul 2, 2024
In the following locations, the auditors identified opportunities to improve code quality and increase adherence to TypeScript best practices:
o1js/src/lib/provable/merkle-list.ts
:MerkleList.forEach()
: Consider putting theisDummy
argument first in thecallback
. In TypeScript,(element: T) => void
will type-check as an instance of(element: T, isDummy: Bool, i: numbere) => void
, but this almost certainly signals an error by the user.MerkleList.popIf()
:this.data
is supposed to restore the state from beforepop()
if thecondition
evaluates tofalse
. However, if the list was empty, and thecondition
was false, then thedata
beforehand was[]
. Restoring the state should keep it as[]
, rather than changing it to[{previousHash: emptyHash, element: provable.empty()}]
.Luckily, this new list is functionally the same for the purposes of a
MerkleList
. Nonetheless, restoring the originaldata
may prevent prover errors in the future.MerkleListIterator.previous()
: An inline comment mentions that “it returns a dummy element if we're at the start of the array
". Note that aMerkleListIterator
has two array-like structures:We recommend clarifying in this comment that
previous()
returns a dummy element if at the start of the list, which corresponds to the end of the array.MerkleList.next()
: UnlikeMerkleList.previous()
,MerkleList.next()
does not prove membership in the list. Instead, it only computes the “next hash” if this element were appended to the current hash.This adds a very important caller requirement: users must remember to assert the iterator is at the end of the list! Otherwise, the circuit will be under-constrained.
We recommend adding documentation to
next()
warning of this fact, and moving it into theUnsafe
module. If a “safe” implementation is required, we recommend requiring users to provide a function implementing their desired invocation ofnext()
, which can be executed within a context that is guaranteed to callassertAtEnd()
.The text was updated successfully, but these errors were encountered: