-
Notifications
You must be signed in to change notification settings - Fork 28
Difference between encoding empty user states and abi.encode(0)
#654
Comments
Some examples to better understand this issue: 1. It is impossible to dispute a transfer from a nonexistent state leafIn order to do so, you would provide the following
Encoding of such hubble-contracts/contracts/libs/Transition.sol Lines 127 to 135 in 0032354
Possible fix to no. 1Encode zero hubble-contracts/contracts/libs/Transition.sol Lines 182 to 183 in 0032354
2. It is impossible to dispute a transfer to a nonexistent state leaf.Similarly as in no. 1 the following require would fail, reverting the dispute transaction: hubble-contracts/contracts/libs/Transition.sol Lines 155 to 162 in 0032354
The Possible fix to no. 1 would stop the require statement from failing but would not make such transfer disputable. 3. It is impossible to dispute a fraudulent transfer that in the same commitment is preceded by a transfer from/to a nonexistent state leafThe failing require statements mentioned in no. 1 and 2 would prevent a dispute transaction to finish. The Possible fix to no. 1 would solve this issue. |
Another possible fix could be changing the representation of a vacant state leaf to a hash of |
Making a zero'd user state ( Ideally, we could allow a watcher to call Another option is to have a zero state encode to 0 per workaround at top, and ban/prevent contract callers from creating deposits, bulk deposits, or c2t's that are zero user states. This adds complexity/gas costs to other contract function calls, but would also have the benefit of preventing callers from accidentally passing in likely bad data after initial hubble network setup. Thoughts? @ChihChengLiang your input would be appreciated as well. |
Another thing to add, working on the test case for the non-existent |
There are other options we can use for empty states.
Another possible fix without defining the preimage empty state is letting the disputer submit the stateHash. // disputer first justify the inclusion of stateHash
require(
MerkleTree.verify(
stateRoot,
stateHash,
senderStateIndex,
proof.witness
),
"Transition: Sender does not exist"
);
// check if sender is empty
if (stateHash == ZERO_BYTES32) return Types.Result.TransferFromNonexistentSender;
// sender is non-empty, the disputer now have to justify the preimage of the state
require(stateHash == keccak256(proof.state.encode(), "stateHash mismatch");
... other checks This alternative comes with additional costs of witnessing a stateHash and a separate |
From offline discussion of tradeoffs with @ChihChengLiang : If we use a special value for empty states (preimage), we will need to update all zero hashes and default state roots to match the new value. This keeps the interface to If we let the disputer submit the Going to let this bake for a bit before deciding on a path forward. Additional input/feedback appreciated. |
Just want to add that we still need to check The code would look similar but the benefit is no change in function signatures. stateHash = keccak256(proof.state.encode());
// disputer first justify the inclusion of stateHash
require(
MerkleTree.verify(
stateRoot,
stateHash,
senderStateIndex,
proof.witness
),
"Transition: Sender does not exist"
);
// check if sender is empty
if (stateHash == ZERO_BYTES32) return Types.Result.TransferFromNonexistentSender; |
So to summarise, I think we considered 3 solutions so far: 0. Encode empty user state as
|
Encoding a StateLeaf struct with all zeros produces a different output then
abi.encode(0)
. We've noticed thatabi.encode(0)
is used to represent a vacant state leaf.An example where this differences may be exploited is a TRANSFER transaction where receiver is an empty state leaf.
The disputer would have to provide a witness for the receiver state leaf in:
hubble-contracts/contracts/libs/Transition.sol
Line 157 in 0032354
But that's impossible to do since the witness leaf value is passed as a struct and it would be impossible to pass a struct which would have the same leaf hash as
abi.encode(0)
.The text was updated successfully, but these errors were encountered: