Skip to content

Commit

Permalink
support mpc for direct deposits
Browse files Browse the repository at this point in the history
  • Loading branch information
r0wdy1 committed Dec 14, 2023
1 parent 4ea2a15 commit 7ca073d
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 54 deletions.
3 changes: 3 additions & 0 deletions src/interfaces/IOperatorManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
pragma solidity 0.8.15;

interface IOperatorManager {

function operator() external returns (address);

function isOperator(address _addr) external view returns (bool);

function isOperatorFeeReceiver(address _operator, address _addr) external view returns (bool);
Expand Down
8 changes: 8 additions & 0 deletions src/interfaces/IZkBobPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,12 @@ interface IZkBobPool {
function accounting() external view returns (IZkBobAccounting);

function recordDirectDeposit(address _sender, uint256 _amount) external;

function appendDirectDeposits(
uint256 _root_after,
uint256[] calldata _indices,
uint256 _out_commit,
uint256[8] memory _batch_deposit_proof,
uint256[8] memory _tree_proof
) external;
}
67 changes: 29 additions & 38 deletions src/zkbob/manager/MPCWrapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,21 @@ contract MPCWrapper is Ownable, CustomABIDecoder {
signers = _signers;
}

modifier paramsVerified(
uint8 count,
bytes calldata signatures
) {
require(count == signers.length, "MPCWrapper: wrong quorum");
uint256 length = msg.data.length - count * 64 - 1; //
bytes calldata message;
assembly
{
message.offset:= 4 //we don't take the selector
message.length:= length
}
require(checkQuorum(count, signatures,message));
_;
}

modifier calldataVerified() {
(uint8 count, bytes calldata signatures) = _mpc_signatures();
require(count == signers.length, "MPCWrapper: wrong quorum");
require(checkQuorum(count, signatures, _mpc_message()));
bytes32 digest = ECDSA.toEthSignedMessageHash(
keccak256(_mpc_message())
);
require(checkQuorum(count, signatures, digest));
_;
}

function checkQuorum(
uint8 count,
bytes calldata signatures,
bytes calldata message
bytes32 _digest
) internal returns (bool) {
uint256 offset = 0;
assembly {
Expand All @@ -76,17 +65,14 @@ contract MPCWrapper is Ownable, CustomABIDecoder {
vs := calldataload(add(32, offset))
offset := add(offset, 64)
}
address signer = ECDSA.recover(
ECDSA.toEthSignedMessageHash(keccak256(message)),
r,
vs
);
address signer = ECDSA.recover(_digest, r, vs);
if (signer != signers[index]) {
return false;
}
}
return true;
}

function transact() external calldataVerified {
return propagate();
}
Expand All @@ -99,22 +85,27 @@ contract MPCWrapper is Ownable, CustomABIDecoder {
uint256[8] calldata _tree_proof,
uint8 mpc_count,
bytes calldata signatures
)
external
paramsVerified(
mpc_count,
signatures
)

{
require(true);
// IZkBobPool(pool).appendDirectDeposits(
// _root_after,
// _indices,
// _out_commit,
// _batch_deposit_proof,
// _tree_proof
// );
) external {
require(mpc_count == signers.length, "MPCWrapper: wrong quorum");

bytes memory mpc_message = abi.encodePacked(
_root_after,
_indices,
_out_commit,
_batch_deposit_proof,
_tree_proof
);

bytes32 digest = ECDSA.toEthSignedMessageHash(keccak256(mpc_message));

require(checkQuorum(mpc_count, signatures, digest));
IZkBobPool(pool).appendDirectDeposits(
_root_after,
_indices,
_out_commit,
_batch_deposit_proof,
_tree_proof
);
}

function propagate() internal {
Expand Down
2 changes: 1 addition & 1 deletion test/zkbob/ZkBobPool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ abstract contract AbstractZkBobPoolTest is AbstractForkTest {
signers.push(signer2Addr);
MPCWrapper(operatorContract).setSigners(signers);
} else {
operatorManager = new MutableOperatorManager(operatorEOA, user3, "https://example.com");
operatorManager = new MutableOperatorManager(user2, user3, "https://example.com");
}
pool.setOperatorManager(operatorManager);
queue.setOperatorManager(operatorManager);
Expand Down
34 changes: 19 additions & 15 deletions test/zkbob/manager/MPCWrapper.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ contract MPCOperatorManagerTest is
uint64(4.9 ether / D / denominator), // second deposit amount
new bytes(14 * 50)
);
// vm.expectCall(
// verifier,
// abi.encodeWithSelector(
// IBatchDepositVerifier.verifyProof.selector,
// [uint256(keccak256(data)) %
// 21888242871839275222246405745257275088548364400416034343698204186575808495617]
// )
// );
// vm.expectEmit(true, false, false, true);
vm.expectCall(
verifier,
abi.encodeWithSelector(
IBatchDepositVerifier.verifyProof.selector,
[uint256(keccak256(data)) %
21888242871839275222246405745257275088548364400416034343698204186575808495617]
)
);
vm.expectEmit(true, false, false, true);
emit CompleteDirectDepositBatch(indices);
bytes memory message = abi.encodePacked(
bytes4(0x02000001), // uint16(2) in little endian ++ MESSAGE_PREFIX_DIRECT_DEPOSIT_V1
Expand All @@ -116,24 +116,27 @@ contract MPCOperatorManagerTest is
// vm.expectEmit(true, false, false, true);
emit Message(128, bytes32(0), message);
vm.prank(user2);
uint256 root_afer = _randFR();
uint256[8] memory batch_deposit_proof = _randProof();
uint256[8] memory tree_proof = _randProof();
bytes memory mpcMessage = abi.encodePacked(
_randFR(),
root_afer,
indices,
outCommitment,
_randProof(),
_randProof()
batch_deposit_proof,
tree_proof
);

(, uint256 signer1Key) = makeAddrAndKey("signer1");
(, uint256 signer2Key) = makeAddrAndKey("signer2");


MPCWrapper(wrapper).appendDirectDepositsMPC(
_randFR(),
root_afer,
indices,
outCommitment,
_randProof(),
_randProof(),
batch_deposit_proof,
tree_proof,
2,
abi.encodePacked(sign(mpcMessage, signer1Key), sign(mpcMessage, signer2Key))
);
Expand All @@ -144,6 +147,7 @@ contract MPCOperatorManagerTest is
bytes memory data,
uint256 key
) internal returns (bytes memory signatureData) {

bytes32 digest = ECDSA.toEthSignedMessageHash(keccak256(data));
(uint8 v, bytes32 r, bytes32 s) = vm.sign(key, digest);
signatureData = abi.encodePacked(
Expand Down

0 comments on commit 7ca073d

Please sign in to comment.