For the complete documentation index, see llms.txt. This page is also available as Markdown.

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: 0 for 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:

3. Validate the amount

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's balance_decimals (8), rescaled from the token's own decimals. The on-chain 70507040000000000 at 18 decimals arrives as 7050704 at 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

Symptom
Cause
What to do

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 Contract

Last updated