Skip to content

Commit

Permalink
Move code from MemoUtils to SequencerABIDecoder
Browse files Browse the repository at this point in the history
  • Loading branch information
AllFi committed Nov 20, 2023
1 parent 34ccc11 commit f597756
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 99 deletions.
57 changes: 0 additions & 57 deletions src/zkbob/sequencer/MemoUtils.sol

This file was deleted.

53 changes: 43 additions & 10 deletions src/zkbob/sequencer/SequencerABIDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma solidity 0.8.15;
import {Parameters} from "../utils/Parameters.sol";

abstract contract SequencerABIDecoder is Parameters {
function _parseCommitData() internal pure returns (
function _parseCommitCalldata() internal pure returns (
uint256 nullifier,
uint256 outCommit,
uint48 transferIndex,
Expand All @@ -22,20 +22,23 @@ abstract contract SequencerABIDecoder is Parameters {
tokenAmount = _transfer_token_amount();
transferProof = _transfer_proof();

uint256 offset = tree_root_after_pos;
txType = uint16(_loaduint256(offset + tx_type_size - uint256_size) & tx_type_mask);
// TODO: add comment
uint256 tx_type_pos = tree_root_after_pos;
txType = uint16(_loaduint256(tx_type_pos + tx_type_size - uint256_size) & tx_type_mask);

offset = offset + tx_type_size;
uint256 memoLength = _loaduint256(offset + memo_data_size_size - uint256_size) & memo_data_size_mask;


offset = offset + memo_data_size_size;
(uint256 memoPos, uint256 memoSize) = _commit_memo_pos_and_size();
assembly {
memo.offset := offset
memo.length := memoLength
memo.offset := memoPos
memo.length := memoSize
}
}

function _commit_memo_pos_and_size() private pure returns (uint256 pos, uint256 size) {
pos = tree_root_after_pos + tx_type_size;
size = _loaduint256(pos + memo_data_size_size - uint256_size) & memo_data_size_mask;
pos = pos + memo_data_size_size;
}

function _sign_r_vs_proxy() internal pure returns (bytes32 r, bytes32 vs) {
uint256 offset = tree_root_after_pos + tx_type_size;
uint256 memoLength = _loaduint256(offset + memo_data_size_size - uint256_size) & memo_data_size_mask;
Expand All @@ -50,4 +53,34 @@ abstract contract SequencerABIDecoder is Parameters {
(bytes32 r, bytes32 vs) = _sign_r_vs_proxy();
return (uint8((uint256(vs) >> 255) + 27), r, vs & S_MASK);
}

function _parseProverAndFees(bytes calldata memo) internal pure returns (address proxyAddress, uint64 proxyFee, uint64 proverFee) {
uint256 offset;
assembly {
offset := memo.offset
}

proxyAddress = address(uint160(_loaduint256(offset + memo_proxy_address_size - uint256_size)));
offset = offset + memo_proxy_address_size;

proxyFee = uint64(_loaduint256(offset + memo_proxy_fee_size - uint256_size));
offset = offset + memo_proxy_fee_size;

proverFee = uint64(_loaduint256(offset + memo_prover_fee_size - uint256_size));
}

function _parseMessagePrefix(bytes calldata memo, uint16 txType) internal pure returns (bytes4 prefix) {
uint256 offset = _memo_fixed_size(txType);
assembly {
prefix := calldataload(add(memo.offset, offset))
}
prefix = prefix & 0x0000ffff;
}

function _parsePermitData(bytes calldata memo) internal pure returns (uint64 expiry, address holder) {
assembly {
expiry := calldataload(add(memo.offset, 0xc))
holder := calldataload(add(memo.offset, 0x20))
}
}
}
13 changes: 6 additions & 7 deletions src/zkbob/sequencer/ZkBobSequencer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ pragma solidity 0.8.15;

import {PriorityQueue, PriorityOperation} from "./PriorityQueue.sol";
import {ZkBobPool} from "../ZkBobPool.sol";
import {MemoUtils} from "./MemoUtils.sol";
import {SequencerABIDecoder} from "./SequencerABIDecoder.sol";
import {ZkBobDirectDepositQueue} from "../ZkBobDirectDepositQueue.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import {IERC20Permit} from "../../interfaces/IERC20Permit.sol";

contract ZkBobSequencer is SequencerABIDecoder, MemoUtils {
contract ZkBobSequencer is SequencerABIDecoder {
using PriorityQueue for PriorityQueue.Queue;
using SafeERC20 for IERC20;

Expand Down Expand Up @@ -53,7 +52,7 @@ contract ZkBobSequencer is SequencerABIDecoder, MemoUtils {
TOKEN_DENOMINATOR = _denominator;
}

function _transferFromByPermit(bytes memory _memo, uint256 _nullifier, int256 _tokenAmount) internal {
function _transferFromByPermit(bytes calldata _memo, uint256 _nullifier, int256 _tokenAmount) internal {

(uint64 expiry, address _user) = _parsePermitData(_memo);

Expand Down Expand Up @@ -82,16 +81,16 @@ contract ZkBobSequencer is SequencerABIDecoder, MemoUtils {
uint256[8] calldata transferProof,
uint16 txType,
bytes calldata memo
) = _parseCommitData();
) = _parseCommitCalldata();

(address proxy, uint64 proxyFee, ) = MemoUtils.parseFees(memo);
(address proxy, uint64 proxyFee, ) = _parseProverAndFees(memo);

require(pendingNullifiers[nullifier] == false, "ZkBobSequencer: nullifier is already pending");
require(_pool.nullifiers(nullifier) == 0, "ZkBobSequencer: nullifier is spent");
require(msg.sender == proxy, "ZkBobSequencer: not authorized");
require(uint96(index) <= _pool.pool_index(), "ZkBobSequencer: index is too high");
require(_pool.transfer_verifier().verifyProof(transfer_pub(index, nullifier, outCommit, transferDelta, memo), transferProof), "ZkBobSequencer: invalid proof");
require(MemoUtils.parseMessagePrefix(memo, txType) == MESSAGE_PREFIX_COMMON_V1, "ZkBobPool: bad message prefix");
require(_parseMessagePrefix(memo, txType) == MESSAGE_PREFIX_COMMON_V1, "ZkBobPool: bad message prefix");

//For permit based deposit we take the Proxy fee in advance
if(txType == PERMIT_DEPOSIT) {
Expand Down Expand Up @@ -134,7 +133,7 @@ contract ZkBobSequencer is SequencerABIDecoder, MemoUtils {
"ZkBobSequencer: invalid commit hash"
);

(address proxy, uint256 proxy_fee, uint256 prover_fee) = MemoUtils.parseFees(memo);
(address proxy, uint256 proxy_fee, uint256 prover_fee) = _parseProverAndFees(memo);
uint256 timestamp = max(op.timestamp, lastQueueUpdateTimestamp);
if (block.timestamp <= timestamp + PROXY_GRACE_PERIOD) {
require(msg.sender == proxy, "ZkBobSequencer: not authorized");
Expand Down
45 changes: 20 additions & 25 deletions src/zkbob/utils/CustomABIDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

pragma solidity 0.8.15;

import "forge-std/console2.sol";

contract CustomABIDecoder {
uint256 constant transfer_nullifier_pos = 4;
uint256 constant transfer_nullifier_size = 32;
Expand All @@ -14,11 +12,6 @@ contract CustomABIDecoder {
r := calldataload(pos)
}
}
function _loadaddress(uint256 pos) internal pure returns (address r) {
assembly {
r := calldataload(pos)
}
}

function _transfer_nullifier() internal pure returns (uint256 r) {
r = _loaduint256(transfer_nullifier_pos);
Expand Down Expand Up @@ -128,8 +121,7 @@ contract CustomABIDecoder {
r = _loaduint256(transfer_index_pos + transfer_delta_size - uint256_size) & transfer_delta_mask;
}

function _memo_fixed_size() internal pure returns (uint256 r) {
uint256 t = _tx_type();
function _memo_fixed_size(uint256 t) internal pure returns (uint256 r) {
if (t == 0 || t == 1) {
// prover + proxy fee + prover fee
// 20 + 8 + 8 = 36
Expand All @@ -148,7 +140,7 @@ contract CustomABIDecoder {
}

function _memo_message() internal pure returns (bytes calldata r) {
uint256 memo_fixed_size = _memo_fixed_size();
uint256 memo_fixed_size = _memo_fixed_size(_tx_type());
uint256 offset = memo_data_pos + memo_fixed_size;
uint256 length = _memo_data_size() - memo_fixed_size;
assembly {
Expand All @@ -157,29 +149,35 @@ contract CustomABIDecoder {
}
}

// uint256 constant memo_fee_pos = memo_data_pos;
uint256 constant memo_fee_size = 8;
uint256 constant memo_fee_mask = (1 << (memo_fee_size * 8)) - 1;

// Sequencer specific data
// proxy address - 20 bytes
// proxy fee - 8 bytes
// prover fee - 8 bytes
uint256 constant memo_sequencer_data_pos = memo_data_pos;
uint256 constant memo_prover_fee_size = memo_fee_size;
uint256 constant memo_proxy_fee_size = memo_fee_size;

uint256 constant memo_proxy_address_pos = memo_data_pos;
uint256 constant memo_proxy_address_size = 20;
uint256 constant memo_sequencer_data_size = memo_proxy_address_size + memo_proxy_fee_size + memo_prover_fee_size ;
uint256 constant memo_tx_type_pos = memo_data_pos;

uint256 constant memo_proxy_address_pos = memo_sequencer_data_pos;


uint256 constant memo_proxy_fee_pos = memo_proxy_address_pos + memo_proxy_address_size;

uint256 constant memo_proxy_fee_size = memo_fee_size;

uint256 constant memo_prover_fee_pos = memo_proxy_fee_pos + memo_proxy_fee_size;
uint256 constant memo_prover_fee_size = memo_fee_size;

uint256 constant memo_sequencer_data_size = memo_proxy_address_size + memo_proxy_fee_size + memo_prover_fee_size ;

function _memo_fee() internal pure returns (uint256 r) {
uint256 t = _tx_type();
r = _loaduint256(
memo_prover_fee_pos + memo_fee_size - uint256_size
memo_prover_fee_pos + memo_prover_fee_size - uint256_size
) & memo_fee_mask;
// TODO: should we claim proxy fee in the sequencer contract for tx type == 0 as welll?
if (t == 0 || t == 1 || t == 2) {
uint256 proxyFee = _loaduint256(
memo_proxy_fee_pos + memo_fee_size - uint256_size
memo_proxy_fee_pos + memo_proxy_fee_size - uint256_size
) & memo_fee_mask;
r += proxyFee;
}
Expand All @@ -191,9 +189,6 @@ contract CustomABIDecoder {
uint256 constant memo_native_amount_size = 8;
uint256 constant memo_native_amount_mask = (1 << (memo_native_amount_size * 8)) - 1;

uint256 constant memo_fee_size = 8;
uint256 constant memo_fee_mask = (1 << (memo_fee_size * 8)) - 1;

function _memo_native_amount() internal pure returns (uint256 r) {
r = _loaduint256(memo_native_amount_pos + memo_native_amount_size - uint256_size) & memo_native_amount_mask;
}
Expand All @@ -206,7 +201,7 @@ contract CustomABIDecoder {
}

// Permittable token deposit specific data
//This is mutualy exclusive with native amount i.e. they both take the same position in transactions of respective type
// This is mutualy exclusive with native amount i.e. they both take the same position in transactions of respective type

uint256 constant memo_permit_deadline_pos = memo_sequencer_data_pos + memo_sequencer_data_size;
uint256 constant memo_permit_deadline_size = 8;
Expand Down

0 comments on commit f597756

Please sign in to comment.