Skip to content

Commit

Permalink
Merge the develop branch into the master branch, v1.2.0-rc1
Browse files Browse the repository at this point in the history
This merge contains the following set of changes:
  - Fix issues with stats counters (#76)
  • Loading branch information
akolotov authored Jun 22, 2023
2 parents 74f6c31 + c43967c commit e9fca99
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 20 deletions.
10 changes: 8 additions & 2 deletions src/zkbob/ZkBobPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ abstract contract ZkBobPool is IZkBobPool, EIP1967Admin, Ownable, Parameters, Zk
* Single transact() call performs either deposit, withdrawal or shielded transfer operation.
*/
function transact() external onlyOperator {
address user;
address user = msg.sender;
uint256 txType = _tx_type();
if (txType == 0) {
user = _deposit_spender();
Expand All @@ -200,6 +200,12 @@ abstract contract ZkBobPool is IZkBobPool, EIP1967Admin, Ownable, Parameters, Zk
user = _memo_permit_holder();
}
int256 transfer_token_delta = _transfer_token_amount();
// For private transfers, operator can receive any fee amount. As receiving a fee is basically a withdrawal,
// we should consider operator's tier withdrawal limits respectfully.
// For deposits, fee transfers can be left unbounded, since they are paid from the deposits themselves,
// not from the pool funds.
// For withdrawals, withdrawal amount that is checked against limits for specific user is already inclusive
// of operator's fee, thus there is no need to consider it separately.
(,, uint256 txCount) = _recordOperation(user, transfer_token_delta);

uint256 nullifier = _transfer_nullifier();
Expand Down Expand Up @@ -291,7 +297,7 @@ abstract contract ZkBobPool is IZkBobPool, EIP1967Admin, Ownable, Parameters, Zk
(uint256 total, uint256 totalFee, uint256 hashsum, bytes memory message) =
direct_deposit_queue.collect(_indices, _out_commit);

uint256 txCount = _processDirectDepositBatch(total);
(,, uint256 txCount) = _recordOperation(address(0), int256(total));
uint256 _pool_index = txCount << 7;

// verify that _out_commit corresponds to zero output account + 16 chosen notes + 111 empty notes
Expand Down
12 changes: 7 additions & 5 deletions src/zkbob/utils/ZkBobAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@ contract ZkBobAccounting is KycProvidersManagerStorage {
}

function _processTVLChange(Slot1 memory s1, address _user, int256 _txAmount) internal {
// short path for direct deposits batch processing
if (_user == address(0) && _txAmount > 0) {
slot1.tvl += uint72(uint256(_txAmount));

return;
}

uint16 curDay = uint16(block.timestamp / SLOT_DURATION / DAY_SLOTS);

UserStats memory us = userStats[_user];
Expand Down Expand Up @@ -288,11 +295,6 @@ contract ZkBobAccounting is KycProvidersManagerStorage {
userStats[_user] = us;
}

function _processDirectDepositBatch(uint256 _totalAmount) internal returns (uint256) {
slot1.tvl += uint72(_totalAmount);
return slot0.txCount++;
}

function _resetDailyLimits(uint8 _tier) internal {
delete tiers[_tier].stats;
}
Expand Down
42 changes: 29 additions & 13 deletions test/zkbob/ZkBobPool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ abstract contract AbstractZkBobPoolTest is AbstractForkTest {
bytes memory data1 = _encodePermitDeposit(int256(0.5 ether / D), 0.01 ether / D);
_transact(data1);

bytes memory data2 = _encodeTransfer();
bytes memory data2 = _encodeTransfer(0.01 ether / D);
_transact(data2);

vm.prank(user3);
Expand All @@ -170,7 +170,7 @@ abstract contract AbstractZkBobPoolTest is AbstractForkTest {

assertEq(pool.pool_index(), 128);

bytes memory data2 = _encodeTransfer();
bytes memory data2 = _encodeTransfer(0.01 ether / D);
_transact(data2);

assertEq(pool.pool_index(), 256);
Expand Down Expand Up @@ -256,7 +256,7 @@ abstract contract AbstractZkBobPoolTest is AbstractForkTest {
_transact(data);
}

bytes memory data2 = _encodeTransfer();
bytes memory data2 = _encodeTransfer(0.01 ether / D);
_transact(data2);

vm.prank(user3);
Expand Down Expand Up @@ -559,6 +559,29 @@ abstract contract AbstractZkBobPoolTest is AbstractForkTest {
}
}

function testOperatorCannotAvoidWithdrawalLimit() public {
deal(token, user1, 1_000_000 ether / D);

pool.setLimits(
0, 1_000_000 ether / D, 500_000 ether / D, 500_000 ether / D, 500_000 ether / D, 500_000 ether / D, 0, 0
);
bytes memory data1 = _encodePermitDeposit(int256(250_000 ether / D), 0.01 ether / D);
_transact(data1);
pool.setLimits(
0, 1_000_000 ether / D, 100_000 ether / D, 100_000 ether / D, 10_000 ether / D, 10_000 ether / D, 0, 0
);
bytes memory data2 = _encodeTransfer(200_000 ether / D);
_transactReverted(data2, "ZkBobAccounting: daily withdrawal cap exceeded");

bytes memory data3 = _encodeTransfer(20_000 ether / D);
_transact(data3);

vm.prank(user3);
pool.withdrawFee(user2, user3);
assertEq(IERC20(token).balanceOf(user3), 20_000.01 ether / D);
assertEq(pool.getLimitsFor(user2).dailyWithdrawalCapUsage, 20_000 ether / D / denominator);
}

function _encodeDeposit(int256 _amount, uint256 _fee) internal returns (bytes memory) {
bytes32 nullifier = bytes32(_randFR());
(uint8 v, bytes32 r, bytes32 s) = vm.sign(pk1, ECDSA.toEthSignedMessageHash(nullifier));
Expand Down Expand Up @@ -601,21 +624,14 @@ abstract contract AbstractZkBobPoolTest is AbstractForkTest {
);
}

function _encodeTransfer() internal returns (bytes memory) {
function _encodeTransfer(uint256 _fee) internal returns (bytes memory) {
bytes memory data = abi.encodePacked(
ZkBobPool.transact.selector,
_randFR(),
_randFR(),
uint48(0),
uint112(0),
-int64(uint64(0.01 ether / D / denominator))
ZkBobPool.transact.selector, _randFR(), _randFR(), uint48(0), uint112(0), -int64(uint64(_fee / denominator))
);
for (uint256 i = 0; i < 17; i++) {
data = abi.encodePacked(data, _randFR());
}
return abi.encodePacked(
data, uint16(1), uint16(44), uint64(0.01 ether / D / denominator), bytes4(0x01000000), _randFR()
);
return abi.encodePacked(data, uint16(1), uint16(44), uint64(_fee / denominator), bytes4(0x01000000), _randFR());
}

function _transact(bytes memory _data) internal {
Expand Down

0 comments on commit e9fca99

Please sign in to comment.