Learn how Tokenized Vaults (NEP-621) are defined on NEAR
A tokenized vault is a smart contract that accepts deposits of an underlying fungible token (FT) and, in exchange, issues shares that represent proportional ownership of the assets held by the vault.The underlying asset can be any NEP-141 compliant token (e.g. a stablecoin or a yield-bearing token). When a user deposits, the vault mints new shares based on the current exchange rate between the vault’s total assets and its total shares in circulation. When a user redeems, the vault burns those shares and returns the equivalent amount of the underlying asset.The shares themselves are also NEP-141 compliant fungible tokens, so they can be transferred between accounts or traded on DEXs, and integrated into broader DeFi use cases such as collateral in lending protocols, liquidity provision, or composable yield strategies.This interface is defined by NEP-621, and is heavily inspired by the ERC-4626 standard widely used on Ethereum. Standardizing the vault interface improves interoperability, reduces integration costs, and encourages consistent, secure vault implementations across the NEAR ecosystem.
NEP-621 defines the interface and the expected behavior of a vault contract, but it does not dictate how the internal logic (yield strategy, fees, accounting) should be implemented.Unlike ERC-4626, deposits and mints on NEAR are handled through the ft_on_transfer callback (as defined by NEP-141), rather than by direct method calls, to fit NEAR’s asynchronous execution model.
Returns the vault’s total managed value, denominated in the underlying asset, represented by all shares in existence.
📖 This is the vault’s total managed value, not just the balance held in the contract. If assets are staked, lent, or deployed elsewhere, this returns the estimated total equivalent value, net of any deposit/withdrawal fees.
These are view-only estimations. They do not update state and ignore user-specific constraints such as limits or fees. They MUST never panic, returning 0 if conversion is not possible.
All limit and preview methods are read-only and MUST never panic, returning 0 when the operation is not currently allowed. Limit methods should return U128::MAX to signal “unlimited”.
Following the NEP-141 standard, assets are sent to the vault via ft_transfer_call on the underlying asset’s contract, which invokes ft_on_transfer on the vault. Both the ERC-4626 deposit and mint operations are handled through this single entrypoint.
Upon a successful deposit, the vault MUST emit a VaultDeposit event and should also emit an FtMint event for the issued shares.The msg parameter carries the deposit options. While implementers are free to define their own schema, the suggested convention is a JSON-encoded message:
pub struct DepositMessage { /// Minimum shares that must be received for the deposit to succeed (slippage control). min_shares: Option<U128>, /// Maximum shares that can be minted, used for `mint` operations. max_shares: Option<U128>, /// Account that should receive the minted shares. receiver_id: Option<AccountId>, /// Optional memo for logging or off-chain indexing. memo: Option<String>, /// If `true`, the transfer is treated as a donation and no shares are minted. donate: Option<bool>,}
As required by NEP-141, ft_on_transfer must return the number of tokens to refund to the sender: 0 if all tokens were accepted, or a non-zero value otherwise.
Burns shares from the caller and returns the equivalent amount of underlying assets. If receiver_id is omitted, assets are sent to the caller. Set min_amount_out to 0 to ignore slippage, or to a reasonable value to protect against it.
Withdraws exactly asset_amount of underlying tokens, burning the required number of shares. If receiver_id is omitted, assets are sent to the caller. Provide max_shares_deducted to protect against slippage.
Vaults emit standardized events so wallets, indexers, and other DeFi applications can track deposits and withdrawals.
/// Emitted when a deposit is received by the vault and shares are minted to `owner_id`.pub struct VaultDeposit { /// Account that sends the deposit (payer of the assets). pub sender_id: AccountId, /// Account that receives the minted shares. pub owner_id: AccountId, /// Amount of underlying assets deposited into the vault. pub asset_amount: U128, /// Amount of shares minted and issued to `owner_id`. pub shares: U128, /// Optional memo provided by the sender for off-chain use. pub memo: Option<String>,}/// Emitted when shares are redeemed: the vault burns shares from `owner_id`/// and transfers the equivalent assets to `receiver_id`.pub struct VaultWithdraw { /// Account that owns the shares being redeemed (burned). pub owner_id: AccountId, /// Account receiving the underlying assets. pub receiver_id: AccountId, /// Amount of shares redeemed (burned from the vault). pub shares: U128, /// Amount of underlying assets withdrawn from the vault. pub asset_amount: U128, /// Optional memo provided by the redeemer for off-chain use. pub memo: Option<String>,}
Because transactions on NEAR are non-atomic, a vault should emit VaultWithdraw in one of two ways:
Emit VaultWithdraw when the fee is deducted, and emit a compensating VaultDeposit if the withdrawal later fails; or
Emit VaultWithdraw only if the withdrawal succeeds.
In the reference implementation, an FtBurn event is emitted when withdraw is called. On success, a VaultWithdraw event is emitted in the resolve_withdraw callback; on failure, an FtMint event restores the user’s balance.
When implementing a vault, keep the following risks in mind:
Exchange rate manipulation (inflation attacks): if the vault has a permissionless donation mechanism, an attacker can donate assets to inflate the share price and steal value from later depositors. Mitigate by seeding a non-trivial initial deposit and/or using a virtual decimal offset on issued shares (demonstrated in the reference implementation).
Cross-contract calls:redeem and withdraw perform asynchronous FT transfers, opening the door to reentrancy. Use proper state management, callback security, and rollback mechanisms for failed operations.
Rounding direction: always round in favor of the vault — round down when issuing shares or transferring assets out, round up when calculating shares/assets required for a given amount. This prevents value extraction through repeated micro-transactions.
Oracle and external price dependencies: stale oracle data creates temporal windows for exploitation. Include staleness checks, prevent operations during oracle updates, and consider fallback pricing for oracle failures.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"NEAR Docs","colors":{"primary":"#1fb858","light":"#1fb858","dark":"#1fb858"},"logo":{"light":"https://mintcdn.com/neardocs/qO2GD-gji1aakHqN/assets/logo.svg?fit=max\u0026auto=format\u0026n=qO2GD-gji1aakHqN\u0026q=85\u0026s=fe9551b1c3085e39a97965b2886dad4a","dark":"https://mintcdn.com/neardocs/qO2GD-gji1aakHqN/assets/logo_rev.svg?fit=max\u0026auto=format\u0026n=qO2GD-gji1aakHqN\u0026q=85\u0026s=1455d1ccc3385495e8b52e6657ce8c84"},"favicon":"https://mintcdn.com/neardocs/qO2GD-gji1aakHqN/assets/favicon.svg?fit=max\u0026auto=format\u0026n=qO2GD-gji1aakHqN\u0026q=85\u0026s=ef64e8324f93ca4f703d8ebad5e32c53","api":{"openapi":"openapi.json","playground":{"display":"interactive"},"examples":{"defaults":"all","languages":["bash","javascript","python"]}},"appearance":{"default":"system","strict":false},"navbar":{"links":[{"icon":"wallet","href":"https://wallet.near.org/","label":"Wallets"},{"icon":"search","href":"https://explorer.near.org/","label":"Explorers"},{"icon":"layout-grid","href":"https://nearcatalog.xyz/","label":"NEAR Catalog"}]},"search":{"prompt":"Search docs..."},"seo":{"metatags":{"google-site-verification":"x36GvqeIYFjDAl2NNFM-83XykcMYMLRY6f9lgUZbDpA"}},"fonts":{"family":"Inter"},"icons":{"library":"lucide"},"styling":{"eyebrows":"breadcrumbs","codeblocks":{"theme":{"light":"github-light","dark":"github-dark"}},"latex":true},"integrations":{"ga4":{"measurementId":"G-TMG0M3DPNW"}},"contextual":{"options":["copy","claude","cursor"],"display":"header"},"interaction":{"drilldown":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"neardocs","hasAudioNarration":false,"actualSubdomain":"neardocs","customDomains":["docs.near.org"],"gitSource":{"type":"github","owner":"near","repo":"docs","deployBranch":"master","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6adf8fac54a8cd69daa376f4","collectionId":"6082491f-4a49-43d4-8390-e1aeb4fc09f1","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6adf8fac54a8cd69daa376f4"},"feedback":{"thumbs":true},"entitlements":{},"buildId":"6adf8fac54a8cd69daa376f4","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"default","tag":"RPC","count":46},{"language":"default","tag":"Smart Contracts","count":44},{"language":"default","tag":"Protocol","count":30},{"language":"default","tag":"Building Smart Contracts","count":30},{"language":"default","tag":"Tokens \u0026 Primitives","count":21},{"language":"default","tag":"Tutorials","count":21},{"language":"default","tag":"Concepts","count":19},{"language":"default","tag":"Home","count":17},{"language":"default","tag":"Multi-Chain","count":15},{"language":"default","tag":"Web3 Apps","count":15}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"styles.css","content":":root{--explain-card-bg:#f1f5f9;--explain-card-active-bg:#eef2ff;--explain-card-border:#c7d2fe}.dark{--explain-card-bg:#161b22;--explain-card-active-bg:#21262d;--explain-card-border:transparent}"},{"filePath":"custom.css","content":".home-code code{max-height:300px;overflow-y:auto}"}],"page":{"pagePath":"primitives/tokenized-vaults","slug":"/primitives/tokenized-vaults","pageMetadata":{"title":"Tokenized Vaults","icon":"trending-up","description":"Learn how Tokenized Vaults (NEP-621) are defined on NEAR","href":"/primitives/tokenized-vaults"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Learn how Tokenized Vaults (NEP-621) are defined on NEAR\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,blockquote:`blockquote`,code:`code`,em:`em`,hr:`hr`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Tip}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`A tokenized vault is a smart contract that accepts deposits of an underlying `,_jsx(_components.a,{href:`/ft/standard`,children:`fungible token (FT)`}),` and, in exchange, issues shares that represent proportional ownership of the assets held by the vault.`]}),`\n`,_jsxs(_components.p,{children:[`The underlying asset can be any `,_jsx(_components.a,{href:`https://github.com/near/NEPs/tree/master/neps/nep-0141.md`,children:`NEP-141`}),` compliant token (e.g. a stablecoin or a yield-bearing token). When a user deposits, the vault mints new shares based on the current exchange rate between the vault’s total assets and its total shares in circulation. When a user redeems, the vault burns those shares and returns the equivalent amount of the underlying asset.`]}),`\n`,_jsx(_components.p,{children:`The shares themselves are also NEP-141 compliant fungible tokens, so they can be transferred between accounts or traded on DEXs, and integrated into broader DeFi use cases such as collateral in lending protocols, liquidity provision, or composable yield strategies.`}),`\n`,_jsxs(_components.p,{children:[`This interface is defined by `,_jsx(_components.a,{href:`https://github.com/near/NEPs/tree/master/neps/nep-0621.md`,children:`NEP-621`}),`, and is heavily inspired by the `,_jsx(_components.a,{href:`https://eips.ethereum.org/EIPS/eip-4626`,children:`ERC-4626`}),` standard widely used on Ethereum. Standardizing the vault interface improves interoperability, reduces integration costs, and encourages consistent, secure vault implementations across the NEAR ecosystem.`]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`NEP-621 defines the interface and the expected behavior of a vault contract, but it does not dictate how the internal logic (yield strategy, fees, accounting) should be implemented.`}),_jsxs(_components.p,{children:[`Unlike ERC-4626, deposits and mints on NEAR are handled through the `,_jsx(_components.code,{children:`ft_on_transfer`}),` callback (as defined by NEP-141), rather than by direct method calls, to fit NEAR’s asynchronous execution model.`]})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`nep-621-vault-interface`,children:`NEP-621 (Vault Interface)`}),`\n`,_jsxs(_components.p,{children:[`A vault contract MUST implement the `,_jsx(_components.code,{children:`VaultCore`}),` trait, which extends:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/ft/standard#nep-141-fungible-token-interface`,children:_jsx(_components.code,{children:`FungibleTokenCore`})}),` — to provide NEP-141 functionality for the shares.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`FungibleTokenReceiver`}),` — to receive the underlying NEP-141 asset.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`In other words, a vault is itself a fungible token (the shares) that can also receive another fungible token (the underlying asset).`}),`\n`,_jsx(Heading,{level:`3`,id:`asset-information`,children:`Asset Information`}),`\n`,_jsxs(Heading,{level:`4`,id:`asset_contract_id-read-only`,children:[_jsx(_components.code,{children:`asset_contract_id`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsx(_components.p,{children:`Returns the account ID of the underlying asset’s NEP-141 contract. Should be stored as an immutable configuration value.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`asset_contract_id`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`total_asset_amount-read-only`,children:[_jsx(_components.code,{children:`total_asset_amount`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsx(_components.p,{children:`Returns the vault’s total managed value, denominated in the underlying asset, represented by all shares in existence.`}),`\n`,_jsxs(_components.blockquote,{children:[`\n`,_jsxs(_components.p,{children:[`📖 This is the vault’s total managed value, `,_jsx(_components.em,{children:`not`}),` just the balance held in the contract. If assets are staked, lent, or deployed elsewhere, this returns the estimated total equivalent value, net of any deposit/withdrawal fees.`]}),`\n`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`total_asset_amount`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(): string`})]}),`\n`]})})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`3`,id:`conversion-helpers`,children:`Conversion Helpers`}),`\n`,_jsxs(_components.p,{children:[`These are view-only estimations. They do not update state and ignore user-specific constraints such as limits or fees. They MUST never panic, returning `,_jsx(_components.code,{children:`0`}),` if conversion is not possible.`]}),`\n`,_jsxs(Heading,{level:`4`,id:`convert_to_shares-read-only`,children:[_jsx(_components.code,{children:`convert_to_shares`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsx(_components.p,{children:`Converts an amount of underlying assets to the equivalent number of shares.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`convert_to_shares`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(asset_amount: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`convert_to_asset_amount-read-only`,children:[_jsx(_components.code,{children:`convert_to_asset_amount`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsx(_components.p,{children:`Converts an amount of shares to the equivalent amount of underlying assets.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`convert_to_asset_amount`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(shares: string): string`})]}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`convert_*`}),` for generic price quotes, and the `,_jsx(_components.code,{children:`preview_*`}),` methods below when you need an estimate that also accounts for per-user limits and fees.`]})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`3`,id:`deposit-\u0026-redemption-limits`,children:`Deposit \u0026 Redemption Limits`}),`\n`,_jsxs(_components.p,{children:[`All limit and preview methods are read-only and MUST never panic, returning `,_jsx(_components.code,{children:`0`}),` when the operation is not currently allowed. Limit methods should return `,_jsx(_components.code,{children:`U128::MAX`}),` to signal “unlimited”.`]}),`\n`,_jsxs(Heading,{level:`4`,id:`max_deposit_amount-read-only`,children:[_jsx(_components.code,{children:`max_deposit_amount`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Maximum amount of underlying assets that `,_jsx(_components.code,{children:`receiver_id`}),` can deposit.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`max_deposit_amount`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(receiver_id: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`preview_deposit_shares-read-only`,children:[_jsx(_components.code,{children:`preview_deposit_shares`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Simulates depositing exactly `,_jsx(_components.code,{children:`asset_amount`}),` and returns the number of shares that would be minted, accounting for per-user deposit limits and fees.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`preview_deposit_shares`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(asset_amount: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`max_mint_shares-read-only`,children:[_jsx(_components.code,{children:`max_mint_shares`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Maximum number of shares that `,_jsx(_components.code,{children:`receiver_id`}),` can mint.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`max_mint_shares`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(receiver_id: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`preview_asset_amount_required_to_mint_shares-read-only`,children:[_jsx(_components.code,{children:`preview_asset_amount_required_to_mint_shares`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Simulates minting exactly `,_jsx(_components.code,{children:`shares`}),` and returns the amount of underlying assets required.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`preview_asset_amount_required_to_mint_shares`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(shares: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`max_redeem_shares-read-only`,children:[_jsx(_components.code,{children:`max_redeem_shares`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Maximum number of shares that `,_jsx(_components.code,{children:`owner_id`}),` can redeem (considering balance, withdrawal restrictions, and lock-ups).`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`max_redeem_shares`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(owner_id: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`preview_redeem_amount-read-only`,children:[_jsx(_components.code,{children:`preview_redeem_amount`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Simulates redeeming `,_jsx(_components.code,{children:`shares`}),` and returns the amount of assets that would be received, factoring in the owner’s balance, withdrawal limits, and fees.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`preview_redeem_amount`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(shares: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`max_withdraw_amount-read-only`,children:[_jsx(_components.code,{children:`max_withdraw_amount`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Maximum amount of assets that `,_jsx(_components.code,{children:`owner_id`}),` can withdraw.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`max_withdraw_amount`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(owner_id: string): string`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`4`,id:`preview_shares_deducted_for_withdraw-read-only`,children:[_jsx(_components.code,{children:`preview_shares_deducted_for_withdraw`}),` (`,_jsx(_components.em,{children:`read-only`}),`)`]}),`\n`,_jsxs(_components.p,{children:[`Simulates withdrawing exactly `,_jsx(_components.code,{children:`asset_amount`}),` and returns the number of shares that would be burned.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`preview_shares_deducted_for_withdraw`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(asset_amount: string): string`})]}),`\n`]})})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`3`,id:`deposit-\u0026-mint`,children:`Deposit \u0026 Mint`}),`\n`,_jsxs(_components.p,{children:[`Following the NEP-141 standard, assets are sent to the vault via `,_jsx(_components.a,{href:`/ft/standard#ft_transfer_call`,children:_jsx(_components.code,{children:`ft_transfer_call`})}),` on the underlying asset’s contract, which invokes `,_jsx(_components.code,{children:`ft_on_transfer`}),` on the vault. Both the ERC-4626 `,_jsx(_components.code,{children:`deposit`}),` and `,_jsx(_components.code,{children:`mint`}),` operations are handled through this single entrypoint.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`ft_on_transfer`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(sender_id: string, amount: string, msg: string): string`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Upon a successful deposit, the vault MUST emit a `,_jsx(_components.a,{href:`#events`,children:_jsx(_components.code,{children:`VaultDeposit`})}),` event and should also emit an `,_jsx(_components.code,{children:`FtMint`}),` event for the issued shares.`]}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`msg`}),` parameter carries the deposit options. While implementers are free to define their own schema, the suggested convention is a JSON-encoded message:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`rust`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`rust`,children:_jsxs(_components.code,{language:`rust`,numberOfLines:`12`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`pub`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` struct`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` DepositMessage`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Minimum shares that must be received for the deposit to succeed (slippage control).`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` min_shares`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Option`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`U128`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`>,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:\" /// Maximum shares that can be minted, used for `mint` operations.\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` max_shares`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Option`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`U128`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`>,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Account that should receive the minted shares.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` receiver_id`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Option`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`AccountId`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`>,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Optional memo for logging or off-chain indexing.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` memo`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Option`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`String`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`>,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:\" /// If `true`, the transfer is treated as a donation and no shares are minted.\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` donate`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Option`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`bool`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`>,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`As required by NEP-141, `,_jsx(_components.code,{children:`ft_on_transfer`}),` must return the number of tokens to refund to the sender: `,_jsx(_components.code,{children:`0`}),` if all tokens were accepted, or a non-zero value otherwise.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`3`,id:`redemption-\u0026-withdrawal`,children:`Redemption \u0026 Withdrawal`}),`\n`,_jsx(Heading,{level:`4`,id:`redeem`,children:_jsx(_components.code,{children:`redeem`})}),`\n`,_jsxs(_components.p,{children:[`Burns `,_jsx(_components.code,{children:`shares`}),` from the caller and returns the equivalent amount of underlying assets. If `,_jsx(_components.code,{children:`receiver_id`}),` is omitted, assets are sent to the caller. Set `,_jsx(_components.code,{children:`min_amount_out`}),` to `,_jsx(_components.code,{children:`0`}),` to ignore slippage, or to a reasonable value to protect against it.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`redeem`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(shares: string, min_amount_out: string, receiver_id: string`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`?`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`)`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` string`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`4`,id:`withdraw`,children:_jsx(_components.code,{children:`withdraw`})}),`\n`,_jsxs(_components.p,{children:[`Withdraws exactly `,_jsx(_components.code,{children:`asset_amount`}),` of underlying tokens, burning the required number of shares. If `,_jsx(_components.code,{children:`receiver_id`}),` is omitted, assets are sent to the caller. Provide `,_jsx(_components.code,{children:`max_shares_deducted`}),` to protect against slippage.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`withdraw`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(asset_amount: string, max_shares_deducted: string`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`?`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`, receiver_id`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` string`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`?`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`)`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` string`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Upon a successful withdrawal, the vault MUST emit a `,_jsx(_components.a,{href:`#events`,children:_jsx(_components.code,{children:`VaultWithdraw`})}),` event.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`events`,children:`Events`}),`\n`,_jsx(_components.p,{children:`Vaults emit standardized events so wallets, indexers, and other DeFi applications can track deposits and withdrawals.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`28`,language:`rust`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`rust`,children:_jsxs(_components.code,{language:`rust`,numberOfLines:`28`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:\"/// Emitted when a deposit is received by the vault and shares are minted to `owner_id`.\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`pub`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` struct`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` VaultDeposit`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Account that sends the deposit (payer of the assets).`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` sender_id`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` AccountId`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Account that receives the minted shares.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` owner_id`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` AccountId`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Amount of underlying assets deposited into the vault.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` asset_amount`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` U128`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:\" /// Amount of shares minted and issued to `owner_id`.\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` shares`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` U128`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Optional memo provided by the sender for off-chain use.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` memo`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Option`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`String`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`>,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:\"/// Emitted when shares are redeemed: the vault burns shares from `owner_id`\"})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:\"/// and transfers the equivalent assets to `receiver_id`.\"})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`pub`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` struct`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` VaultWithdraw`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Account that owns the shares being redeemed (burned).`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` owner_id`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` AccountId`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Account receiving the underlying assets.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` receiver_id`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` AccountId`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Amount of shares redeemed (burned from the vault).`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` shares`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` U128`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Amount of underlying assets withdrawn from the vault.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` asset_amount`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` U128`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:` /// Optional memo provided by the redeemer for off-chain use.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` pub`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` memo`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`:`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` Option`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`String`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`>,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Because transactions on NEAR are non-atomic, a vault should emit `,_jsx(_components.code,{children:`VaultWithdraw`}),` in one of two ways:`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Emit `,_jsx(_components.code,{children:`VaultWithdraw`}),` when the fee is deducted, and emit a compensating `,_jsx(_components.code,{children:`VaultDeposit`}),` if the withdrawal later fails; or`]}),`\n`,_jsxs(_components.li,{children:[`Emit `,_jsx(_components.code,{children:`VaultWithdraw`}),` only if the withdrawal succeeds.`]}),`\n`]}),`\n`,_jsxs(_components.blockquote,{children:[`\n`,_jsxs(_components.p,{children:[`In the `,_jsx(_components.a,{href:`https://github.com/Meteor-Wallet/tokenized-vault-nep-implementation`,children:`reference implementation`}),`, an `,_jsx(_components.code,{children:`FtBurn`}),` event is emitted when `,_jsx(_components.code,{children:`withdraw`}),` is called. On success, a `,_jsx(_components.code,{children:`VaultWithdraw`}),` event is emitted in the `,_jsx(_components.code,{children:`resolve_withdraw`}),` callback; on failure, an `,_jsx(_components.code,{children:`FtMint`}),` event restores the user’s balance.`]}),`\n`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`security-considerations`,children:`Security Considerations`}),`\n`,_jsx(_components.p,{children:`When implementing a vault, keep the following risks in mind:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Exchange rate manipulation (inflation attacks):`}),` if the vault has a permissionless donation mechanism, an attacker can donate assets to inflate the share price and steal value from later depositors. Mitigate by seeding a non-trivial initial deposit and/or using a virtual decimal offset on issued shares (demonstrated in the `,_jsx(_components.a,{href:`https://github.com/Meteor-Wallet/tokenized-vault-nep-implementation`,children:`reference implementation`}),`).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Cross-contract calls:`}),` `,_jsx(_components.code,{children:`redeem`}),` and `,_jsx(_components.code,{children:`withdraw`}),` perform asynchronous FT transfers, opening the door to reentrancy. Use proper state management, callback security, and rollback mechanisms for failed operations.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Rounding direction:`}),` always round in favor of the vault — round `,_jsx(_components.em,{children:`down`}),` when issuing shares or transferring assets out, round `,_jsx(_components.em,{children:`up`}),` when calculating shares/assets required for a given amount. This prevents value extraction through repeated micro-transactions.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Oracle and external price dependencies:`}),` stale oracle data creates temporal windows for exploitation. Include staleness checks, prevent operations during oracle updates, and consider fallback pricing for oracle failures.`]}),`\n`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`reference-implementation`,children:`Reference Implementation`}),`\n`,_jsxs(_components.p,{children:[`A reference implementation is available at `,_jsx(_components.a,{href:`https://github.com/Meteor-Wallet/tokenized-vault-nep-implementation`,children:`Meteor-Wallet/tokenized-vault-nep-implementation`}),`.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":{"theme":{"light":"github-light","dark":"github-dark"}},"config":{},"pageMetadata":{"title":"Tokenized Vaults","icon":"trending-up","description":"Learn how Tokenized Vaults (NEP-621) are defined on NEAR","href":"/primitives/tokenized-vaults"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"NEP-621 (Vault Interface)","slug":"nep-621-vault-interface","depth":2,"children":[{"title":"Asset Information","slug":"asset-information","depth":3,"children":[]},{"title":"asset_contract_id (read-only)","slug":"asset_contract_id-read-only","depth":4,"children":[]},{"title":"total_asset_amount (read-only)","slug":"total_asset_amount-read-only","depth":4,"children":[]},{"title":"Conversion Helpers","slug":"conversion-helpers","depth":3,"children":[]},{"title":"convert_to_shares (read-only)","slug":"convert_to_shares-read-only","depth":4,"children":[]},{"title":"convert_to_asset_amount (read-only)","slug":"convert_to_asset_amount-read-only","depth":4,"children":[]},{"title":"Deposit \u0026 Redemption Limits","slug":"deposit-\u0026-redemption-limits","depth":3,"children":[]},{"title":"max_deposit_amount (read-only)","slug":"max_deposit_amount-read-only","depth":4,"children":[]},{"title":"preview_deposit_shares (read-only)","slug":"preview_deposit_shares-read-only","depth":4,"children":[]},{"title":"max_mint_shares (read-only)","slug":"max_mint_shares-read-only","depth":4,"children":[]},{"title":"preview_asset_amount_required_to_mint_shares (read-only)","slug":"preview_asset_amount_required_to_mint_shares-read-only","depth":4,"children":[]},{"title":"max_redeem_shares (read-only)","slug":"max_redeem_shares-read-only","depth":4,"children":[]},{"title":"preview_redeem_amount (read-only)","slug":"preview_redeem_amount-read-only","depth":4,"children":[]},{"title":"max_withdraw_amount (read-only)","slug":"max_withdraw_amount-read-only","depth":4,"children":[]},{"title":"preview_shares_deducted_for_withdraw (read-only)","slug":"preview_shares_deducted_for_withdraw-read-only","depth":4,"children":[]},{"title":"Deposit \u0026 Mint","slug":"deposit-\u0026-mint","depth":3,"children":[]},{"title":"Redemption \u0026 Withdrawal","slug":"redemption-\u0026-withdrawal","depth":3,"children":[]},{"title":"redeem","slug":"redeem","depth":4,"children":[]},{"title":"withdraw","slug":"withdraw","depth":4,"children":[]}]},{"title":"Events","slug":"events","depth":2,"children":[]},{"title":"Security Considerations","slug":"security-considerations","depth":2,"children":[]},{"title":"Reference Implementation","slug":"reference-implementation","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/neardocs/86bd1b8645a68f87/gleap.js","/_mintlify/custom/neardocs/12aaa8206e84cdb3/scripts/patch-openapi.js"],"subdomain":"neardocs","siteName":"NEAR Docs","title":"Tokenized Vaults - NEAR Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-08-07T12:21:20.601Z","originalFileLocation":"primitives/tokenized-vaults.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Learn how Tokenized Vaults (NEP-621) are defined on NEAR\">\u003cmeta data-mint-head name=\"application-name\" content=\"NEAR Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Tokenized Vaults - NEAR Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Learn how Tokenized Vaults (NEP-621) are defined on NEAR\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"NEAR Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.near.org/primitives/tokenized-vaults\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://neardocs.mintlify.app/_mintlify/api/og/v2?division=DeFi\u0026amp;title=Tokenized+Vaults\u0026amp;description=Learn+how+Tokenized+Vaults+%28NEP-621%29+are+defined+on+NEAR\u0026amp;theme=df941d03d19b89657352cf9a\u0026amp;signature=26fa9c6ac366d95fb9677058587fd9d07b11d1215668e2d32ab153920ae03bb1\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Tokenized Vaults - NEAR Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Learn how Tokenized Vaults (NEP-621) are defined on NEAR\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://neardocs.mintlify.app/_mintlify/api/og/v2?division=DeFi\u0026amp;title=Tokenized+Vaults\u0026amp;description=Learn+how+Tokenized+Vaults+%28NEP-621%29+are+defined+on+NEAR\u0026amp;theme=df941d03d19b89657352cf9a\u0026amp;signature=26fa9c6ac366d95fb9677058587fd9d07b11d1215668e2d32ab153920ae03bb1\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/neardocs/jx3X3HW4FX2vbKtn/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"NEAR Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#1fb858\">\u003cmeta data-mint-head name=\"google-site-verification\" content=\"x36GvqeIYFjDAl2NNFM-83XykcMYMLRY6f9lgUZbDpA\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.near.org/primitives/tokenized-vaults\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/primitives/tokenized-vaults.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.near.org/#organization\",\"name\":\"NEAR Docs\",\"url\":\"https://docs.near.org\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/neardocs/qO2GD-gji1aakHqN/assets/logo.svg?fit=max\u0026auto=format\u0026n=qO2GD-gji1aakHqN\u0026q=85\u0026s=fe9551b1c3085e39a97965b2886dad4a\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.near.org#website\",\"name\":\"NEAR Docs\",\"url\":\"https://docs.near.org\",\"publisher\":{\"@id\":\"https://docs.near.org/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.near.org/primitives/tokenized-vaults#webpage\",\"url\":\"https://docs.near.org/primitives/tokenized-vaults\",\"name\":\"Tokenized Vaults\",\"description\":\"Learn how Tokenized Vaults (NEP-621) are defined on NEAR\",\"dateModified\":\"2026-08-07T12:21:20.601Z\",\"isPartOf\":{\"@id\":\"https://docs.near.org#website\"},\"breadcrumb\":{\"@id\":\"https://docs.near.org/primitives/tokenized-vaults#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.near.org/primitives/tokenized-vaults#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"DeFi\",\"item\":\"https://docs.near.org/primitives/oracles\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tokenized Vaults\",\"item\":\"https://docs.near.org/primitives/tokenized-vaults\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.near.org/primitives/tokenized-vaults#article\",\"headline\":\"Tokenized Vaults\",\"name\":\"Tokenized Vaults\",\"description\":\"Learn how Tokenized Vaults (NEP-621) are defined on NEAR\",\"url\":\"https://docs.near.org/primitives/tokenized-vaults\",\"mainEntityOfPage\":{\"@id\":\"https://docs.near.org/primitives/tokenized-vaults#webpage\"},\"dateModified\":\"2026-08-07T12:21:20.601Z\",\"publisher\":{\"@id\":\"https://docs.near.org/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.near.org#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"NEAR Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"NEAR Docs","nav":{"global":null,"tabs":[{"tab":"Home","icon":"house","pages":[{"title":"Home","href":""}]},{"tab":"Protocol","icon":"layers","pages":[{"title":"Protocol","href":"/protocol/network/architecture"}]},{"tab":"Smart Contracts","icon":"file-badge","pages":[{"title":"Smart Contracts","href":"/smart-contracts/what-is"}]},{"tab":"Web3 Apps","icon":"terminal","pages":[{"title":"Web3 Apps","href":"/web3-apps/what-is"}]},{"tab":"Multi-Chain","icon":"link-2","pages":[{"title":"Multi-Chain","href":"/chain-abstraction/what-is"}]},{"tab":"Tokens \u0026 Primitives","icon":"coins","groups":[{"group":" ","pages":[{"title":"What are Primitives?","sidebarTitle":"Introduction","icon":"info","href":"/primitives/what-is"}]},{"group":"Fungible Tokens (FT)","pages":[{"title":"The Standard","icon":"circle-dollar-sign","href":"/primitives/ft/standard"},{"title":"Using FTs","icon":"circle-dollar-sign","href":"/primitives/ft/ft"},{"title":"Creating a FT Contract","icon":"circle-dollar-sign","href":"/primitives/ft/sdk-contract-tools"}]},{"group":"Non-Fungible Tokens (NFT)","pages":[{"title":"The Standard","icon":"image","href":"/primitives/nft/standard"},{"title":"Using NFTs","icon":"image","href":"/primitives/nft/nft"},{"title":"Creating a NFT Contract","icon":"image","href":"/primitives/nft/sdk-contract-tools"}]},{"group":"Linkdrops","pages":[{"title":"The Standard","icon":"link","href":"/primitives/linkdrop/standard"},{"title":"Using Linkdrops","icon":"link","href":"/primitives/linkdrop/linkdrop"}]},{"group":"Governance","pages":[{"title":"Decentralized Autonomous Organizations","icon":"landmark","href":"/primitives/dao"}]},{"group":"DeFi","pages":[{"title":"Oracles","icon":"trending-up","href":"/primitives/oracles"},{"title":"Decentralized Exchanges (DEX)","icon":"trending-up","description":"Learn how to interact with decentralized exchanges on NEAR Protocol, including token swapping, liquidity pools, and integration with Ref Finance DEX.","href":"/primitives/dex"},{"title":"Tokenized Vaults","icon":"trending-up","href":"/primitives/tokenized-vaults"}]},{"group":"Off-chain Compute","pages":[{"title":"Off-chain Compute","description":"Learn how NEAR smart contracts can delegate heavy or impossible-on-chain work to verifiable off-chain computation running inside Trusted Execution Environments (TEEs).","href":"/primitives/off-chain-compute/what-is"},{"title":"OutLayer","href":"/primitives/off-chain-compute/outlayer"}]},{"group":"Identity","pages":[{"title":"Decentralized Identifiers (DIDs)","icon":"fingerprint","href":"/primitives/didnear"}]},{"group":"Social","pages":[{"title":"Social","icon":"users","href":"/primitives/social"}]},{"group":"Lockup Contracts","pages":[{"title":"Introduction","icon":"clock","href":"/primitives/lockup/introduction"},{"title":"Lockup Contracts","icon":"clock","href":"/primitives/lockup/lockup"}]},{"group":"Liquid Staking","pages":[{"title":"Using Liquid Staking","icon":"droplets","href":"/primitives/liquid-staking/liquid-staking"},{"title":"Deploying Your Own Contract","icon":"droplets","href":"/primitives/liquid-staking/deploy-your-own-contract"}]}]},{"tab":"Data Infra","icon":"database","pages":[{"title":"Data Infra","href":"/data-infrastructure/what-is"}]},{"tab":"Integrations","icon":"plug","pages":[{"title":"Integrations","href":"/integrations/exchange-integration"}]},{"tab":"RPC","icon":"server","pages":[{"title":"RPC","href":"/api/rpc/introduction"}]}]},"title":"Tokenized Vaults - NEAR Docs","buildId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","deploymentId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","dynamics":[],"chunks":[]}