Deposit
Move funds from an EVM chain into a Native Core balance — the vault call, the activation fee, and how to confirm the credit landed.
Read Deposit & Withdraw first for the shared endpoints, discovery queries, and rate limits.
1. Check whether the account exists
An address that has never held a Native Core balance has no account yet, and its first deposit must pay a one-time activation fee. accountStatus is the authoritative signal.
found: true means the account exists and the deposit carries no fee. found: false means this deposit will create it, and must carry the fee described next.
Treat an unreadable accountStatus as blocking. The vault does not enforce the fee, so a deposit sent while the answer is unknown can land on-chain and then fail validation.
2. Size the activation fee
The fee rides the deposit transaction as msg.value, in the source chain's gas token. No token allowance or second transaction is involved.
The fee is worth 1 USD in the chain's gas token, priced at the time the deposit is validated.
Validation accepts a shortfall of up to 30%, which absorbs the price movement between your quote and settlement.
Overpayment is accepted and never refunded. Quote at your own spot price with a small buffer.
Send
msg.value: 0for every deposit into an account that already exists.
Price it from markPrices — the same oracle the deposit is validated against, so your quote cannot drift out of tolerance the way an external feed can.
Source chain
Gas token
asset_id
Ethereum, Base, Arbitrum
ETH
3
BNB Smart Chain
BNB
4
usd_atoms is a USD price in 8-decimal atoms, and the gas token is 18-decimal on all four chains, so one dollar is 10**26 / usd_atoms wei:
Never guess the fee to zero. Read accountStatus immediately before you build the transaction. A first deposit that underpays past the tolerance is permanent: the funds will not be credited.
3. Validate the amount
Floor the amount to 8 decimal places, and deposit at least 10 USD. The vault enforces neither rule. Break either one and the funds will not be credited.
8-decimal grid. Native credits at 8 decimals (balance_decimals), and settlement refuses any amount that does not convert exactly. Tokens with 8 decimals or fewer need no adjustment: WBTC, cbBTC, and USDC/USDT on Ethereum, Base and Arbitrum cannot carry excess precision.
minDepositDecimalByUnderlying(token) returns the grid (8 on every listed token).
10 USD minimum. The floor is a fixed amount of the deposited token, set per chain and token, not a conversion from the current price. On a stablecoin it is 10 tokens. On a volatile token, quote above 10 USD rather than exactly at it: a rise in that token's price lifts the floor above what 10 USD buys.
4. Approve and deposit
deposit() pulls the ERC20 from the caller, so it needs an allowance first. Amounts are in the token's own decimals.
Pass actionFlag: 0 — the standard deposit path.
Read both pause flags before you build the transaction, so the user sees a reason instead of a revert. isDepositPaused(token) covers a single token, emergencyPaused() the whole vault. Pause is the only amount-independent condition the vault itself gates.
To fund an address other than the caller — a wallet or aggregator depositing on a user's behalf — use depositFor, which credits user instead of msg.sender:
The activation fee follows the credited address, not the caller: read accountStatus for user.
5. Read the deposit nonce from the receipt
The vault assigns each deposit a sequential nonce and emits it in the Deposit event. That nonce is how Native Core identifies the deposit, and the only handle that survives into the credit record.
6. Wait for the credit
Poll deposits and match on the tuple (src_chain_id, src_contract, deposit_nonce). Do not sleep on a fixed timer.
The credit lands about 5 minutes after the deposit transaction, a typical latency rather than a guarantee, because settlement waits for the source transaction to be safely confirmed. Nothing is submitted to Native in the meantime, and closing your process after the deposit transaction lands does not affect the credit.
A matching record means the balance is credited and tradable.
asset_id— which Native asset the ERC20 mapped to, so you never need a token-to-asset table of your own.amount_atoms— the credited amount in that asset'sbalance_decimals(8), rescaled from the token's own decimals. The on-chain70507040000000000at 18 decimals arrives as7050704at 8.tx_hash,block_height— Native Core, not the source chain.
userBalances is the settled-state read once the deposit is done.
Open the credit on the Native explorer to inspect it by hand:
What can go wrong
deposit() reverts UnsupportedUnderlying
Token is not listed on this vault
Read getSupportedUnderlyings() before submitting
deposit() reverts with no data to decode
Allowance or balance too low — most ERC20s revert here without a reason string, so nothing decodes
Re-check the allowance you set in step 4
Mined, still no credit well past 5 minutes
Amount was below the 10 USD minimum, was not on the 8-decimal grid, or a first deposit underpaid the activation fee — read getDepositRecord(nonce) and check amount and msgValue
None of the three is self-recoverable — contact Native with the source tx hash
Mined, no credit yet, account already existed
Still inside the normal settlement delay
Keep polling; report a credit that has not landed well past 5 minutes
429 with RateLimited
More than 1 /info request per second from one IP
Wait the retry after interval in the error, and share one budget across loops
Next steps
WithdrawVault ContractLast updated