How Deposits Work
When you deposit tokens (e.g., USDC) into an account, you receive account shares in return. These shares represent your proportional ownership of the account’s assets and appreciate in value as the account earns yield. There are two ways to deposit:KYT Accounts
TheAttestation struct is passed as the last parameter before any permit fields:
What You’ll Need
ABI Reference
You need the DistributorCodeDepositor ABI, the ERC-20 ABI, and the Accountant ABI. Copy these into your project as a JSON file or inline constant.DistributorCodeDepositor ABI
Bothdeposit() and depositWithPermit() include the _attestation tuple parameter for KYT compliance.
ERC-20 ABI (for approvals and allowance checks)
Accountant ABI (for slippage calculation)
Contract Method Reference
deposit
deposit(depositAsset, depositAmount, minimumMint, to, distributorCode, _attestation)
Attestation fields:
depositWithPermit
depositWithPermit(depositAsset, depositAmount, minimumMint, to, distributorCode, _attestation, deadline, v, r, s)
Same parameters as deposit() (including the _attestation tuple), plus the permit fields appended after the attestation:
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 account’s Accountant contract publishes the exchange rate between the deposit token and account shares. Use it to calculate a safe minimumMint.
Contract call
rateInQuote represents the amount of the deposit asset per 1e18 account shares (i.e., per one full share). Pass the deposit token address as the quote parameter.
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) / rateInQuote) × (10000 − SLIPPAGE_BPS) / 100004
Execute the deposit (transaction)
Call The return value is the number of account 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 account shares — all in a single transaction.
depositWithPermit() on the DistributorCodeDepositor with the permit signature. Note the _attestation tuple is placed before the permit parameters.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.Transaction reverts without attestation parameter
Transaction reverts without attestation parameter
The
DistributorCodeDepositorV1 contract requires the _attestation tuple
parameter. If you omit it or use an older ABI without the attestation field,
the transaction will revert. Ensure you’re using the ABI from this guide and
passing the attestation struct (empty values are fine for now). Contact the
Paxos Labs team to implement your compliance
policy.Next Steps
- Direct Withdrawals — Submit a withdrawal order
- Direct Cancellations — Cancel a pending withdrawal
- Account Queries & Monitoring — Read APY, TVL, check balances, and monitor withdrawal status
- SDK Deposits Guide — Use the Amplify SDK instead