Skip to content

Commit

Permalink
Add privileged prover in calldata
Browse files Browse the repository at this point in the history
  • Loading branch information
AllFi committed Mar 26, 2024
1 parent 0333691 commit ccc7c73
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 101 deletions.
15 changes: 8 additions & 7 deletions src/zkbob/ZkBobPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,12 @@ abstract contract ZkBobPool is IZkBobPool, EIP1967Admin, Ownable, Parameters, Ex

uint256 nullifier = _transfer_nullifier();
{
require(msg.sender == _memo_prover_address(), "ZkBobPool: unauthorized");
require(msg.sender == _memo_proxy_address(), "ZkBobPool: unauthorized");
require(nullifiers[nullifier] == 0, "ZkBobPool: doublespend detected");
require(_transfer_index() <= poolIndex, "ZkBobPool: transfer index out of bounds");
require(transfer_verifier.verifyProof(_transfer_pub(), _transfer_proof()), "ZkBobPool: bad transfer proof");

_appendCommitment(_transfer_out_commit(), uint64(_memo_tree_update_fee()), msg.sender);
_appendCommitment(_transfer_out_commit(), uint64(_memo_tree_update_fee()), _memo_prover_address());

nullifiers[nullifier] = uint256(keccak256(abi.encodePacked(_transfer_out_commit(), _transfer_delta())));

Expand Down Expand Up @@ -373,7 +373,8 @@ abstract contract ZkBobPool is IZkBobPool, EIP1967Admin, Ownable, Parameters, Ex
function appendDirectDeposits(
uint256[] calldata _indices,
uint256 _out_commit,
uint256[8] memory _batch_deposit_proof
uint256[8] memory _batch_deposit_proof,
address _prover
)
external
onlyOperator
Expand All @@ -395,7 +396,7 @@ abstract contract ZkBobPool is IZkBobPool, EIP1967Admin, Ownable, Parameters, Ex
require(totalFee >= minTreeUpdateFee, "ZkBobPool: tree update fee is too low");
uint64 ddFee = uint64(totalFee) - minTreeUpdateFee;

_appendCommitment(_out_commit, minTreeUpdateFee, msg.sender);
_appendCommitment(_out_commit, minTreeUpdateFee, _prover);

bytes32 message_hash = keccak256(message);
bytes32 _all_messages_hash = keccak256(abi.encodePacked(all_messages_hash, message_hash));
Expand Down Expand Up @@ -493,12 +494,12 @@ abstract contract ZkBobPool is IZkBobPool, EIP1967Admin, Ownable, Parameters, Ex
}

/**
* @dev Validates either the grace period has passed or the caller
* is the prover who submitted this commitment.
* @dev Validates that the prover is allowed to submit the tree update proof now.
*/
function _validateGracePeriod(uint64 commitmentTimestamp, address privilegedProver) internal view {
require(
block.timestamp > commitmentTimestamp + gracePeriod || msg.sender == privilegedProver,
msg.sender == privilegedProver || privilegedProver == address(0)
|| block.timestamp > commitmentTimestamp + gracePeriod,
"ZkBobPool: prover is not allowed to submit the proof yet"
);
}
Expand Down
27 changes: 17 additions & 10 deletions src/zkbob/utils/CustomABIDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,17 @@ contract CustomABIDecoder {
function _memo_fixed_size() internal pure returns (uint256 r) {
uint256 t = _tx_type();
if (t == 0 || t == 1) {
// prover address + transact fee + tree update fee
// 20 + 8 + 8
r = 36;
// proxy address + prover address + transact fee + tree update fee
// 20 + 20 + 8 + 8
r = 56;
} else if (t == 2) {
// prover address + transact fee + tree update fee + native amount + recipient
// 20 + 8 + 8 + 8 + 20
r = 64;
// proxy address + prover address + transact fee + tree update fee + native amount + recipient
// 20 + 20 + 8 + 8 + 8 + 20
r = 84;
} else if (t == 3) {
// prover address + transact fee + tree update fee + deadline + address
// 20 + 8 + 8 + 8 + 20
r = 64;
// proxy address + prover address + transact fee + tree update fee + deadline + address
// 20 + 20 + 8 + 8 + 8 + 20
r = 84;
} else {
revert();
}
Expand All @@ -145,7 +145,14 @@ contract CustomABIDecoder {
}
}

uint256 constant memo_prover_address_pos = memo_data_pos;
uint256 constant memo_proxy_address_pos = memo_data_pos;
uint256 constant memo_proxy_address_size = 20;

function _memo_proxy_address() internal pure returns (address r) {
r = address(uint160(_loaduint256(memo_proxy_address_pos + memo_proxy_address_size - uint256_size)));
}

uint256 constant memo_prover_address_pos = memo_proxy_address_pos + memo_proxy_address_size;
uint256 constant memo_prover_address_size = 20;

function _memo_prover_address() internal pure returns (address r) {
Expand Down
3 changes: 2 additions & 1 deletion test/interfaces/IZkBobPoolAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ interface IZkBobPoolAdmin {
function appendDirectDeposits(
uint256[] calldata _indices,
uint256 _out_commit,
uint256[8] memory _batch_deposit_proof
uint256[8] memory _batch_deposit_proof,
address _prover
)
external;

Expand Down
6 changes: 3 additions & 3 deletions test/shared/Env.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ address constant bobVanityAddr = address(0xB0B195aEFA3650A6908f15CdaC7D92F8a5791
bytes32 constant bobSalt = bytes32(uint256(285834900769));

uint256 constant forkBlockMainnet = 16200000;
string constant forkRpcUrlMainnet = "https://rpc.ankr.com/eth";
string constant forkRpcUrlMainnet = "https://eth.llamarpc.com";
uint256 constant forkBlockPolygon = 37000000;
string constant forkRpcUrlPolygon = "https://rpc.ankr.com/polygon";
string constant forkRpcUrlPolygon = "https://polygon.llamarpc.com";
uint256 constant forkBlockOptimism = 52000000;
string constant forkRpcUrlOptimism = "https://1rpc.io/op";
string constant forkRpcUrlOptimism = "https://optimism.llamarpc.com";
67 changes: 39 additions & 28 deletions test/zkbob/ZkBobPool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
int256 _amount,
uint256 _transactFee,
uint256 _treeUpdateFee,
address prover
address _proxyAndProver
)
internal
view
Expand Down Expand Up @@ -234,8 +234,9 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
data = abi.encodePacked(
data,
uint16(0),
uint16(84),
prover,
uint16(104),
_proxyAndProver,
_proxyAndProver,
uint64(_transactFee / denominator),
uint64(_treeUpdateFee / denominator),
_memoMessageAndExtraData(bytes2(0))
Expand All @@ -248,7 +249,7 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
uint256 _amount,
uint256 _nativeAmount,
uint256 _energyAmount,
address prover
address _proxyAndProver
)
internal
view
Expand All @@ -267,11 +268,12 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
data = abi.encodePacked(data, _randFR());
}

data = abi.encodePacked(data, uint16(2), uint16(112));
data = abi.encodePacked(data, uint16(2), uint16(132));

return abi.encodePacked(
data,
prover,
_proxyAndProver,
_proxyAndProver,
uint64(0.005 ether / D / denominator),
uint64(0.005 ether / D / denominator),
uint64(_nativeAmount / denominator),
Expand All @@ -283,19 +285,19 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
function _encodeTransfer(
uint256 _transactFee,
uint256 _treeUpdateFee,
address _prover
address _proxyAndProver
)
internal
view
returns (bytes memory)
{
return _encodeTransferWithPrefix(_transactFee, _treeUpdateFee, _prover, bytes2(0));
return _encodeTransferWithPrefix(_transactFee, _treeUpdateFee, _proxyAndProver, bytes2(0));
}

function _encodeTransferWithPrefix(
uint256 _transactFee,
uint256 _treeUpdateFee,
address _prover,
address _proxyAndProver,
bytes2 _prefix
)
internal
Expand All @@ -317,8 +319,9 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
return abi.encodePacked(
data,
uint16(1),
uint16(84),
_prover,
uint16(104),
_proxyAndProver,
_proxyAndProver,
uint64(_transactFee / denominator),
uint64(_treeUpdateFee / denominator),
_memoMessageAndExtraData(_prefix)
Expand Down Expand Up @@ -368,7 +371,20 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
int256 _amount,
uint256 _transactFee,
uint256 _treeUpdateFee,
address prover
address _proxyAndProver
)
internal
returns (bytes memory)
{
return _encodePermitDeposit(_amount, _transactFee, _treeUpdateFee, _proxyAndProver, _proxyAndProver);
}

function _encodePermitDeposit(
int256 _amount,
uint256 _transactFee,
uint256 _treeUpdateFee,
address _proxy,
address _prover
)
internal
returns (bytes memory)
Expand Down Expand Up @@ -413,24 +429,19 @@ abstract contract AbstractZkBobPoolTestBase is AbstractForkTest {
signature = abi.encodePacked(r, uint256(s) + (v == 28 ? (1 << 255) : 0));
}

bytes memory data = abi.encodePacked(
ZkBobPool.transactV2.selector,
uint8(2),
nullifier,
_randFR(),
uint48(0),
uint112(0),
int64(_amount / int256(denominator))
);
bytes memory data = abi.encodePacked(ZkBobPool.transactV2.selector, uint8(2));

data = abi.encodePacked(data, nullifier, _randFR(), uint48(0), uint112(0), int64(_amount / int256(denominator)));
for (uint256 i = 0; i < 8; i++) {
data = abi.encodePacked(data, _randFR());
}

data = abi.encodePacked(data, uint16(3), uint16(112));
data = abi.encodePacked(data, uint16(3), uint16(132));

data = abi.encodePacked(
data,
prover,
_proxy,
_prover,
uint64(_transactFee / denominator),
uint64(_treeUpdateFee / denominator),
uint64(expiry),
Expand Down Expand Up @@ -791,7 +802,7 @@ abstract contract AbstractZkBobPoolTest is AbstractZkBobPoolTestBase {
vm.expectEmit(true, false, false, true);
emit Message(128, bytes32(0), message);
vm.prank(user2);
pool.appendDirectDeposits(indices, outCommitment, _randProof());
pool.appendDirectDeposits(indices, outCommitment, _randProof(), address(0));
}

function testRefundDirectDeposit() public {
Expand Down Expand Up @@ -1004,7 +1015,7 @@ abstract contract AbstractZkBobPoolTest is AbstractZkBobPoolTestBase {

function testTransactMessageEvent() public {
bytes memory data = _encodePermitDeposit(int256(0.5 ether / D), 0.005 ether / D, 0.005 ether / D, user2);
bytes memory message = _slice(data, 423, 36);
bytes memory message = _slice(data, 443, 36);
vm.expectEmit(true, false, false, true);
emit Message(128, bytes32(0), message);
_transact(data);
Expand All @@ -1014,21 +1025,21 @@ abstract contract AbstractZkBobPoolTest is AbstractZkBobPoolTestBase {
IERC20(token).approve(address(pool), 0.11 ether / D);

bytes memory data1 = _encodeDeposit(int256(0.1 ether / D), 0.005 ether / D, 0.005 ether / D, user2);
bytes memory message1 = _slice(data1, 395, 36);
bytes memory message1 = _slice(data1, 415, 36);
vm.expectEmit(true, false, false, true);
emit Message(256, bytes32(0), message1);
_transact(data1);
_proveTreeUpdate();

bytes memory data2 = _encodeTransfer(0.005 ether / D, 0.005 ether / D, user2);
bytes memory message2 = _slice(data2, 395, 36);
bytes memory message2 = _slice(data2, 415, 36);
vm.expectEmit(true, false, false, true);
emit Message(384, bytes32(0), message2);
_transact(data2);
_proveTreeUpdate();

bytes memory data3 = _encodeWithdrawal(user1, 0.1 ether / D, 0, 0, user2);
bytes memory message3 = _slice(data3, 423, 36);
bytes memory message3 = _slice(data3, 443, 36);
vm.expectEmit(true, false, false, true);
emit Message(512, bytes32(0), message3);
_transact(data3);
Expand Down
Loading

0 comments on commit ccc7c73

Please sign in to comment.