Overview
The update_deposit_limit_for_spl_token instruction allows the program authority to modify the maximum deposit amount for a specific SPL token’s merkle tree.
Each SPL token has its own separate merkle tree with its own deposit limit.
Only the program authority can call this instruction.
Function Signature
pub fn update_deposit_limit_for_spl_token (
ctx : Context < UpdateDepositLimitForSplToken >,
new_limit : u64
) -> Result <()>
Source: lib.rs:191-206
Parameters
New maximum deposit amount in the token’s smallest unit. The value depends on the token’s decimals: USDC (6 decimals):
1,000 USDC: 1_000_000_000
10,000 USDC: 10_000_000_000
1,000,000 USDC: 1_000_000_000_000
USDT (6 decimals): SOL-wrapped tokens (9 decimals):
100 tokens: 100_000_000_000
1,000 tokens: 1_000_000_000_000
Accounts
tree_account
AccountLoader<MerkleTreeAccount>
required
The SPL token-specific merkle tree account to update. PDA Seeds: ["merkle_tree", mint.key()]
Mutable : Yes
Authority check : Must be owned by the signer
The SPL token mint account. Used to derive the correct tree PDA.
Mutable : No
Validation : Must be in the allowed tokens list (see supported tokens )
The program authority. Must match the tree’s authority field.
Signer : Yes
Validation : Checked via has_one = authority constraint
Code Example
import * as anchor from "@coral-xyz/anchor" ;
import { Program } from "@coral-xyz/anchor" ;
import { PublicKey } from "@solana/web3.js" ;
const program = anchor . workspace . Zkcash as Program < Zkcash >;
const authority = anchor . web3 . Keypair . generate ();
// USDC Mainnet mint
const usdcMint = new PublicKey ( "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" );
// Derive SPL token tree PDA
const [ splTreePDA ] = PublicKey . findProgramAddressSync (
[ Buffer . from ( "merkle_tree" ), usdcMint . toBuffer ()],
program . programId
);
// Update to 10 million USDC (6 decimals)
const newLimit = new anchor . BN ( 10_000_000_000_000 );
await program . methods
. updateDepositLimitForSplToken ( newLimit )
. accounts ({
treeAccount: splTreePDA ,
mint: usdcMint ,
authority: authority . publicKey
})
. signers ([ authority ])
. rpc ();
console . log ( `USDC deposit limit updated to ${ newLimit . toString () } ` );
Common Use Cases
Increase USDC deposit limit to 1 million: const usdcMint = new PublicKey ( "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" );
const [ splTreePDA ] = PublicKey . findProgramAddressSync (
[ Buffer . from ( "merkle_tree" ), usdcMint . toBuffer ()],
program . programId
);
// 1,000,000 USDC with 6 decimals
const newLimit = new anchor . BN ( 1_000_000_000_000 );
await program . methods
. updateDepositLimitForSplToken ( newLimit )
. accounts ({
treeAccount: splTreePDA ,
mint: usdcMint ,
authority: authority . publicKey
})
. signers ([ authority ])
. rpc ();
Disable Deposits for a Token
Set limit to 0 to prevent new deposits of a specific token: const oreMint = new PublicKey ( "oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp" );
const [ oreTreePDA ] = PublicKey . findProgramAddressSync (
[ Buffer . from ( "merkle_tree" ), oreMint . toBuffer ()],
program . programId
);
// Disable ORE deposits
const newLimit = new anchor . BN ( 0 );
await program . methods
. updateDepositLimitForSplToken ( newLimit )
. accounts ({
treeAccount: oreTreePDA ,
mint: oreMint ,
authority: authority . publicKey
})
. signers ([ authority ])
. rpc ();
Update Multiple Token Limits
Update limits for multiple tokens in sequence: const tokens = [
{ mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" , limit: 1_000_000_000_000 }, // USDC
{ mint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB" , limit: 1_000_000_000_000 }, // USDT
{ mint: "oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp" , limit: 500_000_000_000 } // ORE
];
for ( const token of tokens ) {
const mint = new PublicKey ( token . mint );
const [ treePDA ] = PublicKey . findProgramAddressSync (
[ Buffer . from ( "merkle_tree" ), mint . toBuffer ()],
program . programId
);
await program . methods
. updateDepositLimitForSplToken ( new anchor . BN ( token . limit ))
. accounts ({
treeAccount: treePDA ,
mint: mint ,
authority: authority . publicKey
})
. signers ([ authority ])
. rpc ();
console . log ( `Updated ${ token . mint } : ${ token . limit } ` );
}
State Changes
MerkleTreeAccount (for the specific SPL token)
max_deposit_amount: Updated to new_limit
All other fields remain unchanged. Other tokens’ merkle trees are not affected.
Behavior
Verifies the signer is the tree’s authority
Loads the SPL token-specific tree account (derived from mint address)
Updates the max_deposit_amount field
Emits a program log message with the mint address
The new limit applies immediately to all subsequent deposits of that token
This only affects the specified SPL token. Each token has its own independent deposit limit.
Implementation
pub fn update_deposit_limit_for_spl_token (
ctx : Context < UpdateDepositLimitForSplToken >,
new_limit : u64
) -> Result <()> {
let tree_account = & mut ctx . accounts . tree_account . load_mut () ? ;
tree_account . max_deposit_amount = new_limit ;
msg! (
"Deposit limit updated to: {} for mint: {}" ,
new_limit ,
ctx . accounts . mint . key ()
);
Ok (())
}
Source: lib.rs:191-206
Account Constraints
#[derive( Accounts )]
pub struct UpdateDepositLimitForSplToken <' info > {
#[account(
mut ,
seeds = [ b"merkle_tree" , mint . key() . as_ref()],
bump = tree_account . load () ?. bump,
has_one = authority @ ErrorCode :: Unauthorized
)]
pub tree_account : AccountLoader <' info , MerkleTreeAccount >,
/// SPL Token mint account
pub mint : Account <' info , Mint >,
/// The authority account that can update the deposit limit
pub authority : Signer <' info >,
}
Source: lib.rs:857-872
Errors
Thrown when the signer is not the tree’s authority.
Thrown if the mint is not in the allowed tokens list (on non-localnet environments).
Program Log Output
When successful, the instruction logs:
Deposit limit updated to: {new_limit} for mint: {mint_address}
Example:
Deposit limit updated to: 1000000000000 for mint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
Monitoring
Monitor limit changes for specific tokens:
// Check current limit for USDC
const usdcMint = new PublicKey ( "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" );
const [ usdcTreePDA ] = PublicKey . findProgramAddressSync (
[ Buffer . from ( "merkle_tree" ), usdcMint . toBuffer ()],
program . programId
);
const treeAccount = await program . account . merkleTreeAccount . fetch ( usdcTreePDA );
console . log ( `USDC deposit limit: ${ treeAccount . maxDepositAmount . toString () } ` );
Network Differences
Mainnet/Devnet : Only allowed tokens can have their limits updated
Localnet : Any SPL token mint can be used for testing
See Also