How Deposits Work
When you deposit tokens (e.g., USDC) into a vault, you receive vault shares in return. These shares represent your proportional ownership of the vault’s assets and appreciate in value as the vault earns yield. There are two ways to deposit:What You’ll Need
ABI Reference
You need three ABI snippets. Copy these into your project as a JSON file or inline constant.DistributorCodeDepositor ABI
ERC-20 ABI (for approvals and allowance checks)
Accountant ABI (for slippage calculation)
Contract Method Reference
deposit(depositAsset, depositAmount, minimumMint, to, distributorCode)
depositWithPermit(depositAsset, depositAmount, minimumMint, to, distributorCode, deadline, v, r, s)
Same parameters as deposit(), plus:
Distributor Codes
ThedistributorCode parameter is used for referral attribution. If Paxos Labs has provided you with a distributor code, encode it as bytes (e.g., toHex('your_code') in JavaScript, b'your_code' in Python, []byte("your_code") in Go).
If you don’t have one, pass empty bytes (0x, b"", []byte{}).
Calculating minimumMint (Slippage Protection)
The vault’s Accountant contract publishes the exchange rate between the deposit token and vault shares. Use it to calculate a safe minimumMint.
Contract call
rate represents the amount of the deposit asset per 1e18 vault shares (i.e., per one full share).
Calculation
SLIPPAGE_BPS is your slippage tolerance in basis points (e.g., 50 = 0.5%).
Setting
minimumMint to 0 disables slippage protection entirely. This is
fine for testing but not recommended for production — a front-running bot
could manipulate the rate between your transaction submission and execution.Standard Deposit Walkthrough
The standard flow requires two transactions: an ERC-20 approval followed by the deposit.1
Check existing allowance (read)
Call the deposit token’s If the returned value is ≥ your
allowance() to see if the DistributorCodeDepositor already has sufficient spending permission.depositAmount, skip to Step 3.2
Approve the DistributorCodeDepositor (transaction)
Call Wait for the transaction to be mined before proceeding.
approve() on the deposit token, granting the DistributorCodeDepositor permission to transfer your tokens.3
Calculate minimumMint (read)
Query the exchange rate and compute slippage protection.Then calculate:
minimumMint = ((depositAmount × 1e18) / rate) × (10000 − SLIPPAGE_BPS) / 100004
Execute the deposit (transaction)
Call The return value is the number of vault shares minted.
deposit() on the DistributorCodeDepositor.5
Confirm the transaction
Wait for the transaction receipt. The deposit is complete once the transaction is included in a block. You can verify by calling
BoringVault.balanceOf(yourAddress) to see your new share balance.Example values (1,000 USDC deposit on Ethereum mainnet)
Permit Deposit Walkthrough
For tokens that support EIP-2612 permits, you can combine approval and deposit into a single transaction.1
Get the permit nonce (read)
Query the token’s current nonce for your address.
2
Sign the EIP-712 permit message (off-chain)
Construct and sign an EIP-712 typed data message. This is an off-chain signature — no gas required.EIP-712 Domain (varies by token — this example is for USDC on Ethereum):Sign using your wallet’s
Permit message:
The EIP-712 type structure:
signTypedData (or equivalent EIP-712 signing method). Parse the resulting signature into v, r, s components.3
Calculate minimumMint (read)
Same as the standard flow:
4
Execute depositWithPermit (transaction)
Call The contract verifies the permit signature on-chain, transfers your tokens, and mints vault shares — all in a single transaction.
depositWithPermit() on the DistributorCodeDepositor with the permit signature.Troubleshooting
Transaction reverts with no error message
Transaction reverts with no error message
The most common cause is that
minimumMint is set too high relative to the
current exchange rate. Set it to 0 for testing or recalculate from the
Accountant’s getRateInQuoteSafe().PermitFailedAndAllowanceTooLow
PermitFailedAndAllowanceTooLow
The permit signature is invalid and there’s no existing ERC-20 approval.
Double-check the permit domain parameters (
name, version,
verifyingContract) match the token’s EIP-712 domain. Or switch to the
standard approve + deposit flow.ERC20: insufficient allowance
ERC20: insufficient allowance
You haven’t approved the DistributorCodeDepositor to spend your tokens. Call
approve() on the token contract before calling deposit().ERC20: transfer amount exceeds balance
ERC20: transfer amount exceeds balance
Your wallet doesn’t hold enough of the deposit token. Check your balance
before depositing.
USDT approval fails
USDT approval fails
USDT requires resetting the allowance to
0 before setting a new value if
there’s an existing non-zero allowance. Call approve(spender, 0) first,
then approve(spender, amount). Other tokens (USDC, USDG, pyUSD) allow
overwriting an existing approval directly.Next Steps
- Direct Withdrawals — Submit a withdrawal order
- Direct Cancellations — Cancel a pending withdrawal
- Vault Queries & Monitoring — Read APY, TVL, check balances, and monitor withdrawal status
- SDK Deposits Guide — Use the Amplify SDK instead