zkBob Direct Deposits
A decentralised way of depositing to a zkBob account without using zk core components
Examples are performed with BOB on Polygon. However, the BOB pool is now a USDC pool on Polygon. You can also follow the instructions to deposit USDC or ETH on Optimism.
While there is a test application on Sepolia and Goerli, we strongly recommend using the application in production on Optimism or Polygon.
If you need some live tokens to get started, please contact us through a supported channel (for hackathons use the official the hackathon Discord sponsor-zkbob channel) and we will send BOB!
Production UI on Polygon/Optimism: https://app.zkbob.com
Testnet UI on Sepolia/Goerli: https://staging--zkbob.netlify.app/
Find our new Client Library SDK for integration methods and examples.
See the FAQs at the end for commonly asked questions.
Direct Deposits Introduction
zkBob supports 5 different operations:
Deposit - Add funds to your zkAccount.
Withdraw - Withdraw tokens from your private account to a public
0x
address.Private transfer - Make an anonymous transfer from one user to another with their zkAddress.
Private multi-transfer - Make an anonymous atomic batch transfer to multiple zkAddresses.
Direct deposit - Send tokens directly to someone’s zkAddress from outside the zkBob application.
The first 4 operations can only be performed by end users via zkBob clients, such as the zkBob UI.
However, with direct deposits, private deposits can be performed while abstracting away zk complexity. Depositors only need to know the private zkAddress of the receiver. This makes it very easy to integrate it into various automated web3 workflows.
Direct deposits allow any user, smart contract, or third party protocol to deposit any amount* (within accepted limits) of pool token into the queue, which is then processed by the zkBob relayer in a trustless manner. The only function of the relayer is to include deposits in the state tree, providing a safe mechanism for deposits.
The relayer can process multiple direct deposits at once, however, users may need to wait some time - possibly up to a few hours - until the deposit is reflected in the zkBob account. More on transaction types here.
For now, pending or cancelled direct deposits are not shown in the zkBob UI. Users will only see already processed deposits.
Direct deposits
Direct deposits allow end users, intermediary protocols and smart contracts to make private transfers directly to the receiver zk address. Any EVM-based workflow containing one or more stablecoin transfers might be easily integrated with zkBob direct deposits on the smart contract level, with very little modification required on the UI side.
Examples where zkBob direct deposits can be integrated:
Swap and cross-chain bridge aggregators
Payroll and funds streaming protocols
Donation / fundraising / tipping applications
Vendor purchases
Open-source wallets and browser extensions
Direct deposits integration
Direct deposits can be easily integrated on the smart contract level using the simple interface (available at GitHub).
Creating a zkAddress for the receiver
The most convenient way for users to generate a receiving zkAddress is to use the zkBob UI. Open an account and generate an address: Generate a Receiving Address
zkAddresses can be formatted in different ways for direct deposit submission.
Submitting a direct deposit
Direct deposits are submitted directly to the direct deposits queue contract (e.g. 0x318e2C1f5f6Ac4fDD5979E73D498342B255fC869 on Optimism, see Deployed Contracts for addresses on other networks), using one of three approaches:
Common
approve
+directDeposit
approach, suitable for a majority of use-cases. Available for all supported tokens.Shortcut approach using
transferAndCall
, suitable for simple workflows. Available only for BOB token.Shortcut
directNativeDeposit
approach, suitable for depositing native ETH. Available only for ETH deposits in the ETH pool.
The ERC677 transferAndCall
approach is more gas efficient. However, it does not return the depositId
. If you need to implement any post-submission logic in your application on the smart contract level and you need a depositId
, please use the 1st approach.
Calling either of these methods requires 3 input arguments:
fallbackReceiver
- regular user public0x
address, which will receive the funds in the unlikely scenario that the deposit is rejection by the system (DO NOT set this address to zero or address that does not belong to the intended receiver)amount
- direct deposit amount. A small flat fee is subtracted from each deposit to account for relayer expenses.zkAddress
- private zk address of the intended receiver, see info below for the supported address formats
Polygon USDC Example
Optimism BOB Example
Optimism ETH Example
Calls to either of the deposit methods can revert with corresponding revert reasons in case of the following scenarios:
Insufficient token allowance for
directDeposit
call.Zero
fallbackReceiver
parameter.Insufficient deposit amount to cover the implied deposit fee.
Deposit amount exceeding the single deposit limit for a particular user.
Sum of daily direct deposits exceeding daily deposit limit for a particular user.
Invalid zkAddress format/length/checksum.
The most straightforward way to test direct deposit submission is through the Blockscout UI: https://optimism.blockscout.com/address/0x318e2C1f5f6Ac4fDD5979E73D498342B255fC869?tab=write_proxy
Submitting a direct deposit in most scenarios will require the end user to pay transaction fees in MATIC or ETH, which is not the same for regular zkBob operations.
Checking deposit status
Submitted direct deposits are not executed immediately and instead are placed into the queue with Pending
status to be later processed by the zkBob relayer.
In case your workflow requires any post-execution logic, you can request the actual deposit status from the pool contract.
Refund pending direct deposit
In the unlikely event the deposit is rejected by the system due to compliance or AML reasons, a previously submitted direct deposit can be refunded back to the specified fallback receiver address 1 day following the deposit submission.
Request extra system information
zkAddress format
zkBob smart contracts supports 3 different zkAddress formats. These are identical to one to another with the exception of a small difference in their processing.
zkAddress consists of two main parts - a diversifier and a public key. More information here - Address derivation.
zkBob smart contracts support multiple address formats, which contain a different encoding of the two parts.
The most convenient way to generate a receiving zkAddress is to use the zkBob UI to open an account and an address - Generate a Receiving Address
zkBob UI format (recommended for Optimism):
Example:
QsnTijXekjRm9hKcq5kLNPsa6P4HtMRrc3RxVx3jsLHeo2AiysYxVJP86mz6t7k
(simply remove thezkbob_polygon:
human readable prefix)Base58 encoding of the following string:
bytes10(diversifier_le) ++ bytes32(pk_le) ++ bytes4(checksum)
Length of up to 63 base58 symbols
Base58 decoding is done on the smart contract level at the moment of deposit submission and is gas intensive (~610k gas)
Pre-decoded zkBob UI format (recommended for Polygon / Optimism):
Example:
0xda9ee1b1b651c87a76c2efe3e4b9b0a0e53e5b66ed19ad100afe5289ea732bfd5ac002969523f26e6f2ff9ddd34b
Same format as in the zkBob UI, but omitting the base58 encoding -
bytes10(diversifier_le) ++ bytes32(pk_le) ++ bytes4(checksum)
Much more gas efficient decoding than the previous format (~3,400 gas)
Raw format:
Example:
0xc2767ac851b6b1e19eda2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef
Raw format without checksum -
bytes10(diversifier_be) ++ bytes32(pk_be)
Most gas efficient decoding (~1,100 gas)
Addresses without checksums can be error-prone and are generally not recommended for usage
Note the difference in endianness between encodings. Addresses coming from zkBob UI use little endian for zk address encoding.
Sending direct deposit to the incorrectly serialized address might result in the loss of funds.
Checksum
zkBob address checksum is first 4 bytes of keccak256(bytes3(pool_id) ++ keccak256(bytes10(diversifier_le) ++ bytes32(pk_le)))
Solidity Library
zkBob smart contracts use the following Solidity library for address parsing - GitHub
Use it to test off-chain zkAddress validation logic, or call read-only parseZkAddress
function to convert zkBob UI address format to raw format
Direct deposit limits
All submitted direct deposits are subject to per-user limits at the time of their submission. Submission of direct deposits exceeding configured limits will revert.
Default direct deposits limits for all users:
Max amount of a single deposit - 1,000 BOB / 1,000 USDC / 5 ETH
Max daily sum of all single user deposits - 10,000 BOB / 10,000 USDC / 5 ETH
Limits can be adjusted in the future. Please refer to the up-to-date limit values displayed in the UI, or obtained through the smart contract interface.
Direct deposit fee
Apart from associated gas costs for the deposit transaction submission, which is paid by the user, each direct deposit submission also costs 0.1 BOB / 0.1 USDC / 0.0002 ETH to process.
Fees can be adjusted in the future. Please refer to the up-to-date fee values displayed in the UI, or obtained through the smart contract interface.
FAQs
zkBob is on Polygon/Optimism, does that mean my app also needs to be deployed there?
We have production ready zkBob deployments on Polygon and Optimism, ideally your app should be deployed on either of those chains. Potentially direct deposits could be available on other chains as well, if properly integrated into one of the cross-chain bridges.
For testing purposes, we also support staging zkBob deployments on Sepolia and Goerli testnet. These are open for public use.
Read more about all relevant contract addresses for all networks zkBob is present at in Deployed Contracts
How to get testnet tokens in Goerli/Sepolia?
There are BOB/USDC faucet contracts available in both Goerli/Sepolia (Deployed Contracts), which allow anyone to get up to 10k BOB/USDC per transaction using the Blockscout UI.
Does a direct deposit operation require MATIC/ETH?
Yes, a native token (like MATIC or ETH) is required to pay the gas fees for a direct deposit transaction. In addition, a fee of 0.10 BOB / 0.0002 ETH will be charged for each direct deposit tx. For regular deposits, transfers or withdrawals within the zkBob application, MATIC/ETH is not required.
How do I get started?
If you need BOB to get started (hackathon participants), please send us a message in the Discord sponsor-zkbob channel and we will send you some. We are also available for any questions there. If you are a developer, you can contact us via the zkBob discord.
What is the address of the zkBob UI?
Polygon / Optimism instance: https://app.zkbob.com
Testnet (Sepolia/Goerli) instance: https://staging--zkbob.netlify.app/
Last updated