Skip to content

Commit

Permalink
adds state vars to challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
r0wdy1 committed Dec 16, 2023
1 parent 54e6e06 commit d96c009
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 37 deletions.
67 changes: 50 additions & 17 deletions src/zkbob/manager/MPCGuard.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pragma solidity 0.8.15;

import "../../../src/zkbob/ZkBobPool.sol";
import "../../utils/Ownable.sol";
import "../utils/CustomABIDecoder.sol";
Expand Down Expand Up @@ -40,15 +39,30 @@ contract MPCGuard is Ownable, CustomABIDecoder {
guards = _guards;
}

function digest(bytes memory data) internal returns (bytes32) {
return ECDSA.toEthSignedMessageHash(keccak256(data));
}

modifier calldataVerified() {
(uint8 count, bytes calldata signatures) = _mpc_signatures();
require(count == guards.length, "MPCWrapper: wrong quorum");
bytes32 digest = ECDSA.toEthSignedMessageHash(keccak256(_mpc_message()));
require(checkQuorum(signatures, digest));
ZkBobPool poolContract = ZkBobPool(pool);
uint256 currentRoot = poolContract.roots(poolContract.pool_index());
uint256 transferRoot = poolContract.roots(_transfer_index());
require(
checkQuorum(
signatures,
digest(abi.encodePacked(_mpc_message(), transferRoot, currentRoot))
),
"MPCWrapper: wrong quorum"
);
_;
}

function checkQuorum(bytes calldata signatures, bytes32 _digest) internal view returns (bool) {
function checkQuorum(
bytes calldata signatures,
bytes32 _digest
) internal view returns (bool) {
uint256 offset = 0;
assembly {
offset := signatures.offset
Expand Down Expand Up @@ -84,25 +98,32 @@ contract MPCGuard is Ownable, CustomABIDecoder {
uint256[8] calldata _batch_deposit_proof,
uint256[8] memory _tree_proof,
bytes calldata signatures
)
external
onlyOperator
{
require(signatures.length == guards.length * SIGNATURE_SIZE, "MPCWrapper: wrong quorum");
) external onlyOperator {
require(
signatures.length == guards.length * SIGNATURE_SIZE,
"MPCWrapper: wrong quorum"
);

ZkBobPool poolContract = ZkBobPool(pool);

bytes memory mpc_message = abi.encodePacked(
ZkBobPool(pool).appendDirectDeposits.selector,
_root_after,
_indices,
_out_commit,
_batch_deposit_proof,
_tree_proof
_tree_proof,
poolContract.roots(poolContract.pool_index())
);

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

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

function propagate() internal {
Expand All @@ -116,15 +137,27 @@ contract MPCGuard is Ownable, CustomABIDecoder {

// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := call(gas(), contractAddress, 0, 0, _calldatasize, 0, 0)
let result := call(
gas(),
contractAddress,
0,
0,
_calldatasize,
0,
0
)

// Copy the returned data.
returndatacopy(0, 0, returndatasize())

switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
}
14 changes: 14 additions & 0 deletions test/zkbob/ZkBobPool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,20 @@ abstract contract AbstractZkBobPoolTest is AbstractForkTest {
guardians.push(guard1Addr);
guardians.push(guard2Addr);
MPCGuard(operatorContract).setGuards(guardians);
address[] memory users = new address[](2);
users[0] = operatorContract;
users[1] = address(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
accounting.setLimits(
1,
2_000_000 ether / D / denominator,
200_000 ether / D / denominator,
200_000 ether / D / denominator,
20_000 ether / D / denominator,
20_000 ether / D / denominator,
25 ether / D / denominator,
10 ether / D / denominator
);
accounting.setUsersTier(1, users);
} else {
operatorManager = new MutableOperatorManager(user2, user3, "https://example.com");
}
Expand Down
97 changes: 77 additions & 20 deletions test/zkbob/manager/MPCGuard.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import "../../shared/ForkTests.t.sol";

import "../../../src/zkbob/manager/MPCGuard.sol";

contract MPCOperatorManagerTest is AbstractZkBobPoolTest, AbstractPolygonForkTest {

contract MPCOperatorManagerTest is
AbstractZkBobPoolTest,
AbstractPolygonForkTest
{
constructor() {
isMPC = true;
D = 1;
Expand All @@ -31,27 +35,57 @@ contract MPCOperatorManagerTest is AbstractZkBobPoolTest, AbstractPolygonForkTes
}

function testPermitDepositMPC() public {
bytes memory data = withMPC(_encodePermitDeposit(0.1 ether, 0.01 ether)); //752
bytes memory data = withMPC(
_encodePermitDeposit(0.1 ether, 0.01 ether)
); //752
_transactMPC(data);
}

function testTransferMPC() public {
bytes memory data = withMPC(
_encodePermitDeposit(0.1 ether, 0.01 ether)
); //752
_transactMPC(data);

data = withMPC(_encodeTransfer(0.01 ether));

_transactMPC(data);
}

function testWithdrawMPC() public {
bytes memory data = withMPC(_encodeWithdrawal(user1, 0.1 ether, 0.001 ether, 0));

_transactMPC(data);
}

function _transactMPC(bytes memory data) internal {
address operator = makeAddr("operatorEOA");
address wrapper = operatorManager.operator();
vm.prank(operator);
(bool status,) = address(wrapper).call(data);
(bool status, ) = address(wrapper).call(data);
require(status, "transact() reverted");
}

function withMPC(bytes memory data) internal returns (bytes memory) {
(, uint256 guard1Key) = makeAddrAndKey("guard1");
(, uint256 guard2Key) = makeAddrAndKey("guard2");
return abi.encodePacked(

ZkBobPool poolContract = ZkBobPool(address(pool));
uint256 current_root = poolContract.roots(poolContract.pool_index());
uint48 transfer_index = uint48(0);
uint256 transfer_root = poolContract.roots(transfer_index);
bytes memory challenge = abi.encodePacked(
data,
uint8(2), //753
sign(data, guard1Key), //817
sign(data, guard2Key) //881
transfer_root,
current_root
);
(, uint256 guard1Key) = makeAddrAndKey("guard1");
(, uint256 guard2Key) = makeAddrAndKey("guard2");
return
abi.encodePacked(
data,
uint8(2), //753
sign(challenge, guard1Key), //817
sign(challenge, guard2Key) //881
);
}

function testAppendDirectDepositsMPC() public {
Expand All @@ -72,20 +106,23 @@ contract MPCOperatorManagerTest is AbstractZkBobPoolTest, AbstractPolygonForkTes
bytes memory data = abi.encodePacked(
outCommitment,
bytes10(0xc2767ac851b6b1e19eda), // first deposit receiver zk address (42 bytes)
bytes32(0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef),
bytes32(
0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef
),
uint64(9.9 ether / D / denominator), // first deposit amount
bytes10(0xc2767ac851b6b1e19eda), // second deposit receiver zk address (42 bytes)
bytes32(0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef),
bytes32(
0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef
),
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
]
[uint256(keccak256(data)) %
21888242871839275222246405745257275088548364400416034343698204186575808495617]
)
);
vm.expectEmit(true, false, false, true);
Expand All @@ -94,21 +131,32 @@ contract MPCOperatorManagerTest is AbstractZkBobPoolTest, AbstractPolygonForkTes
bytes4(0x02000001), // uint16(2) in little endian ++ MESSAGE_PREFIX_DIRECT_DEPOSIT_V1
uint64(0), // first deposit nonce
bytes10(0xc2767ac851b6b1e19eda), // first deposit receiver zk address (42 bytes)
bytes32(0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef),
bytes32(
0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef
),
uint64(9.9 ether / D / denominator), // first deposit amount
uint64(1), // second deposit nonce
bytes10(0xc2767ac851b6b1e19eda), // second deposit receiver zk address (42 bytes)
bytes32(0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef),
bytes32(
0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef
),
uint64(4.9 ether / D / denominator) // second deposit amount
);
// vm.expectEmit(true, false, false, true);
emit Message(128, bytes32(0), message);

ZkBobPool poolContract = ZkBobPool(address(pool));
uint256 root_afer = _randFR();
uint256[8] memory batch_deposit_proof = _randProof();
uint256[8] memory tree_proof = _randProof();
bytes memory mpcMessage = abi.encodePacked(
ZkBobPool.appendDirectDeposits.selector, root_afer, indices, outCommitment, batch_deposit_proof, tree_proof
ZkBobPool.appendDirectDeposits.selector,
root_afer,
indices,
outCommitment,
batch_deposit_proof,
tree_proof,
poolContract.roots(poolContract.pool_index())
);

(, uint256 guard1Key) = makeAddrAndKey("guard1");
Expand All @@ -121,13 +169,22 @@ contract MPCOperatorManagerTest is AbstractZkBobPoolTest, AbstractPolygonForkTes
outCommitment,
batch_deposit_proof,
tree_proof,
abi.encodePacked(sign(mpcMessage, guard1Key), sign(mpcMessage, guard2Key))
abi.encodePacked(
sign(mpcMessage, guard1Key),
sign(mpcMessage, guard2Key)
)
);
}

function sign(bytes memory data, uint256 key) internal pure returns (bytes memory signatureData) {
function sign(
bytes memory data,
uint256 key
) internal pure returns (bytes memory signatureData) {
bytes32 digest = ECDSA.toEthSignedMessageHash(keccak256(data));
(uint8 v, bytes32 r, bytes32 s) = vm.sign(key, digest);
signatureData = abi.encodePacked(r, uint256(s) + (v == 28 ? (1 << 255) : 0));
signatureData = abi.encodePacked(
r,
uint256(s) + (v == 28 ? (1 << 255) : 0)
);
}
}

0 comments on commit d96c009

Please sign in to comment.