Skip to content
This repository has been archived by the owner on Jun 29, 2023. It is now read-only.

Commit

Permalink
WIP Allow disputing a transfer from/to a non-existent state.
Browse files Browse the repository at this point in the history
Add stateHash field to StateMerkleProof to allow proof to dispute empty to/from indexes.
Sync some enums from Types.sol to match up in TS types in client.
Add more extensive test cases for disputeTransitionTransfer for triggering rollbacks.
Typo signautre -> signature.
  • Loading branch information
jacque006 committed Sep 14, 2021
1 parent e09c1fc commit 8898997
Show file tree
Hide file tree
Showing 7 changed files with 294 additions and 101 deletions.
24 changes: 22 additions & 2 deletions contracts/libs/Transition.sol
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,25 @@ library Transition {
uint256 fee,
Types.StateMerkleProof memory proof
) internal pure returns (bytes32 newRoot, Types.Result) {
// disputer must first justify the inclusion of the stateHash
require(
MerkleTree.verify(
stateRoot,
keccak256(proof.state.encode()),
proof.stateHash,
senderStateIndex,
proof.witness
),
"Transition: Sender does not exist"
);
// check if sender is empty
if (proof.stateHash == Types.ZERO_BYTES32)
return (bytes32(0), Types.Result.BadFromIndex);
// sender is non-empty, the disputer now has to justify the preimage of the state
require(
proof.stateHash == keccak256(proof.state.encode()),
"stateHash mismatch"
);

(Types.UserState memory newSender, Types.Result result) =
validateAndApplySender(tokenID, amount, fee, proof.state);
if (result != Types.Result.Ok) return (bytes32(0), result);
Expand All @@ -151,15 +161,25 @@ library Transition {
uint256 amount,
Types.StateMerkleProof memory proof
) internal pure returns (bytes32 newRoot, Types.Result) {
// disputer must first justify the inclusion of the stateHash
require(
MerkleTree.verify(
stateRoot,
keccak256(proof.state.encode()),
proof.stateHash,
receiverStateIndex,
proof.witness
),
"Transition: receiver does not exist"
);
// check if receiver is empty
if (proof.stateHash == Types.ZERO_BYTES32)
return (bytes32(0), Types.Result.BadFromIndex);
// receiver is non-empty, the disputer now has to justify the preimage of the state
require(
proof.stateHash == keccak256(proof.state.encode()),
"stateHash mismatch"
);

(Types.UserState memory newReceiver, Types.Result result) =
validateAndApplyReceiver(tokenID, amount, proof.state);
if (result != Types.Result.Ok) return (bytes32(0), result);
Expand Down
11 changes: 10 additions & 1 deletion contracts/libs/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ pragma solidity ^0.6.12;
library Types {
// prettier-ignore
uint256 public constant ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
bytes32 public constant ZERO_BYTES32 =
0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563;

struct SignatureProof {
Types.UserState[] states;
bytes32[][] stateWitnesses;
Expand Down Expand Up @@ -225,6 +228,7 @@ library Types {

struct StateMerkleProof {
UserState state;
bytes32 stateHash;
bytes32[] witness;
}

Expand All @@ -239,6 +243,9 @@ library Types {
bytes32[] witness;
}

/**
* @notice Results of a validation check on a transaction or commit
*/
enum Result {
Ok,
InvalidTokenAmount,
Expand All @@ -250,6 +257,8 @@ library Types {
BadWithdrawRoot,
BadCompression,
TooManyTx,
BadPrecompileCall
BadPrecompileCall,
BadFromIndex,
BadToIndex
}
}
18 changes: 12 additions & 6 deletions contracts/rollup/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ contract Rollup is BatchManager, EIP712, IEIP712 {
string public constant DOMAIN_NAME = "Hubble";
string public constant DOMAIN_VERSION = "1";

bytes32 public constant ZERO_BYTES32 =
0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563;
/**
* @dev If this is not being externally consumed, it can be removed.
*/
bytes32 public immutable ZERO_BYTES32;

// External contracts
BLSAccountRegistry public immutable accountRegistry;
Expand Down Expand Up @@ -69,6 +71,8 @@ contract Rollup is BatchManager, EIP712, IEIP712 {
)
EIP712(DOMAIN_NAME, DOMAIN_VERSION)
{
ZERO_BYTES32 = Types.ZERO_BYTES32;

accountRegistry = _accountRegistry;
transfer = _transfer;
massMigration = _massMigration;
Expand All @@ -80,11 +84,11 @@ contract Rollup is BatchManager, EIP712, IEIP712 {
);

bytes32 genesisCommitment =
keccak256(abi.encode(genesisStateRoot, ZERO_BYTES32));
keccak256(abi.encode(genesisStateRoot, Types.ZERO_BYTES32));

// Same effect as `MerkleTree.merklize`
bytes32 commitmentRoot =
keccak256(abi.encode(genesisCommitment, ZERO_BYTES32));
keccak256(abi.encode(genesisCommitment, Types.ZERO_BYTES32));
batches[nextBatchID] = Types.Batch({
commitmentRoot: commitmentRoot,
meta: Types.encodeMeta(
Expand Down Expand Up @@ -355,13 +359,15 @@ contract Rollup is BatchManager, EIP712, IEIP712 {
vacant.witness
);
bytes32 depositCommitment =
keccak256(abi.encode(newRoot, ZERO_BYTES32));
keccak256(abi.encode(newRoot, Types.ZERO_BYTES32));
// Same effect as `MerkleTree.merklize`
bytes32 root = keccak256(abi.encode(depositCommitment, ZERO_BYTES32));
bytes32 root =
keccak256(abi.encode(depositCommitment, Types.ZERO_BYTES32));
// AccountRoot doesn't matter for deposit, add dummy value
submitBatch(root, 1, bytes32(0), Types.Usage.Deposit);
}

// TODO Add note about proofs beng dif in this one than C2T and MM?
function disputeTransitionTransfer(
uint256 batchID,
Types.CommitmentInclusionProof memory previous,
Expand Down
Loading

0 comments on commit 8898997

Please sign in to comment.