Building on Avalanche? Ava Labs can cover up to 75% of your audit, and we take 10% off our quote. Avalanche audits: up to 75% covered. See how

Work & reportsReport

NEAR IntentsNEAR Intents Security Review

Guvenkaya reviewed the NEAR Intents smart contracts, including the intent engine, payload verification and cryptography crates.

NEAR Intents logo

Date of engagement: 12th February 2025 - 5th March 2025

  • Timur GüvenkayaPrincipal advisor
  • Michal BajorSpecialist

Engagement Dashboard

Audit results

Guvenkaya conducted a security assessment of the NEAR Intents from 12th February 2025 to 5th March 2025. NEAR Intents are a new type of transaction that allow information, requests, assets, and actions to be exchanged between AI agents, services, and end users. During this engagement, a total of 4 findings were reported. 1 of the findings was medium and the remaining were either low or informational severity. The NEAR Intents team has not fixed the issues yet.

Engagement record

Client
NEAR Intents
System
NEAR Intents smart contracts
Review period
12th February 2025 - 5th March 2025
Reviewed baseline
6da9e2b3ab598f277d45fb356aee01a5d80ac0a6
Paths in scope
103
Principal advisor
Timur Güvenkaya
Specialist
Michal Bajor

Timeline

  1. Review start12th February 2025
  2. Draft report5th March 2025

Findings by severity

  • Critical 0
  • High 0
  • Medium 1
  • Low 1
  • Informational 2

Finding status at final report

4Raised
1Scheduled
3Not Fixed

Remediation complexity

4Simple

Impact

1Severe
3Negligible

Likelihood

1Possible
3Rare

Advisory and Client

The advisory

Guvenkaya specializes in security for digital assets and financial infrastructure, from smart contracts and protocols to applications, infrastructure, custody and cryptography.

Our team, including the sitting Heads of Security at Gauntlet and Agora, brings experience from Kraken, OpenZeppelin, Binance, ZKsync, Nillion, Invicti and EY. Across the team: 200+ security reviews, $30B+ in volume secured, 13 published cryptography research papers, and credentials including OSCP, OSWE and CISM.

  • Every reviewer has a public bio and is named before you sign. We match expertise to your system, with a principal leading scoping and checking findings.

The client

NEAR Intents is a cross-chain liquidity protocol for swaps, payments and asset onboarding. Users specify the assets and outcome they want, while the system coordinates routing and execution across supported blockchains. Wallets, applications and agents can integrate these capabilities into their own products.

Applications obtain quotes from competing solvers. Signed intents express the authorized asset movements, which the Verifier contract validates and executes on NEAR. Developers can integrate through a widget or API; the 1Click API handles quote requests, intent creation and execution tracking, reducing the need to build separate integrations for each supported chain and asset pair.

  • Cross-chain swaps let users exchange an asset on one network for an asset on another.
  • Cross-pay lets a sender use one token while the recipient receives a preferred asset on another supported chain.
  • Asset onboarding lets a wallet or application accept deposits from a user's existing chain through the same network.

Scope and Review Boundaries

Review depths

Deep
Line-by-line review with explicit attack hypotheses, adversarial reasoning about state transitions, and reproduction attempts for each hypothesis that survived reading.
Supporting
The code was read for its effect on a reviewed flow. Behaviour outside that effect was not assessed.
Targeted
Entry points were exercised or triaged against the flow's security properties rather than read in full.

This is the code we read, and how closely. 103 paths are in scope. Each path links to the file at the reviewed commit.

PathReview depthScope note
admin-utils/src/lib.rsDeepAdmin Utils Lib
admin-utils/src/full_access_keys.rsDeepFull Access Keys
bitmap/src/lib.rsDeepBitmap Lib
borsh-utils/src/lib.rsDeepBorsh Utils Lib
borsh-utils/src/base64.rsDeepBase64
borsh-utils/src/string.rsDeepString
controller/src/lib.rsDeepController Lib
core/src/lib.rsDeepCore Lib
core/src/accounts.rsDeepAccounts
core/src/deadline.rsDeepDeadline
core/src/engine/mod.rsDeepEngine Mod
core/src/engine/inspector.rsDeepEngine Inspector
core/src/engine/state/mod.rsDeepState Mod
core/src/engine/state/cached.rsDeepState Cached
core/src/engine/state/deltas.rsDeepState Deltas
core/src/error.rsDeepError
core/src/events.rsDeepEvents
core/src/fees.rsDeepFees
core/src/intents/mod.rsDeepIntents Mod
core/src/intents/account.rsDeepIntent Account
core/src/intents/token_diff.rsDeepToken Diff
core/src/intents/tokens.rsDeepTokens (Intents)
core/src/nonce.rsDeepNonce
core/src/payload/mod.rsDeepPayload Mod
core/src/payload/erc191.rsDeepERC191 Payload
core/src/payload/multi.rsDeepMulti Payload
core/src/payload/nep413.rsDeepNEP413 Payload
core/src/payload/raw.rsDeepRaw Payload
core/src/payload/webauthn.rsDeepWebAuthn Payload
core/src/tokens.rsDeepTokens (Core)
crypto/src/lib.rsDeepCrypto Lib
crypto/src/curve/mod.rsDeepCurve Mod
crypto/src/curve/ed25519.rsDeepED25519
crypto/src/curve/p256.rsDeepP256
crypto/src/curve/secp256k1.rsDeepSecp256k1
crypto/src/payload.rsDeepPayload (Crypto)
crypto/src/public_key.rsDeepPublic Key
crypto/src/serde/mod.rsDeepSerde Mod
crypto/src/serde/curve.rsDeepSerde Curve
crypto/src/signature.rsDeepSignature
defuse/src/lib.rsDeepDefuse Lib
defuse/src/accounts.rsDeepAccounts (Defuse)
defuse/src/contract/mod.rsDeepContract Mod
defuse/src/contract/abi.rsDeepABI
defuse/src/contract/accounts/mod.rsDeepAccounts Mod
defuse/src/contract/accounts/account.rsDeepAccount
defuse/src/contract/accounts/state.rsDeepState (Accounts)
defuse/src/contract/admin.rsDeepAdmin
defuse/src/contract/config.rsDeepConfig
defuse/src/contract/events.rsDeepEvents (Contract)
defuse/src/contract/fees.rsDeepFees (Contract)
defuse/src/contract/intents/mod.rsDeepIntents Mod (Contract)
defuse/src/contract/intents/execute.rsDeepExecute
defuse/src/contract/intents/relayer.rsDeepRelayer
defuse/src/contract/intents/simulate.rsDeepSimulate
defuse/src/contract/intents/state.rsDeepState (Intents)
defuse/src/contract/state.rsDeepState (Contract)
defuse/src/contract/tokens/mod.rsDeepTokens Mod (Contract)
defuse/src/contract/tokens/nep141/mod.rsDeepNEP141 Mod
defuse/src/contract/tokens/nep141/deposit.rsDeepNEP141 Deposit
defuse/src/contract/tokens/nep141/native.rsDeepNEP141 Native
defuse/src/contract/tokens/nep141/withdraw.rsDeepNEP141 Withdraw
defuse/src/contract/tokens/nep171/mod.rsDeepNEP171 Mod
defuse/src/contract/tokens/nep171/deposit.rsDeepNEP171 Deposit
defuse/src/contract/tokens/nep171/withdraw.rsDeepNEP171 Withdraw
defuse/src/contract/tokens/nep245/mod.rsDeepNEP245 Mod
defuse/src/contract/tokens/nep245/core.rsDeepNEP245 Core
defuse/src/contract/tokens/nep245/deposit.rsDeepNEP245 Deposit
defuse/src/contract/tokens/nep245/resolver.rsDeepNEP245 Resolver
defuse/src/contract/tokens/nep245/withdraw.rsDeepNEP245 Withdraw
defuse/src/contract/upgrade.rsDeepUpgrade
defuse/src/fees.rsDeepFees (Defuse)
defuse/src/intents.rsDeepIntents (Defuse)
defuse/src/tokens/mod.rsDeepTokens Mod (Defuse)
defuse/src/tokens/nep141.rsDeepNEP141 (Defuse)
defuse/src/tokens/nep171.rsDeepNEP171 (Defuse)
defuse/src/tokens/nep245.rsDeepNEP245 (Defuse)
erc191/src/lib.rsDeepERC191 Lib
map-utils/src/lib.rsDeepMap Utils Lib
map-utils/src/btree_map.rsDeepBTree Map
map-utils/src/cleanup.rsDeepCleanup
map-utils/src/hash_map.rsDeepHash Map
map-utils/src/iter.rsDeepIter
map-utils/src/near.rsDeepNear (Map Utils)
near-utils/src/lib.rsDeepNear Utils Lib
near-utils/src/cache.rsDeepCache
near-utils/src/gas.rsDeepGas
near-utils/src/panic.rsDeepPanic
near-utils/src/prefix.rsDeepPrefix
nep245/src/lib.rsDeepNEP245 Lib
nep245/src/core.rsDeepCore (NEP245)
nep245/src/events.rsDeepEvents (NEP245)
nep245/src/receiver.rsDeepReceiver
nep245/src/resolver.rsDeepResolver (NEP245)
nep245/src/token.rsDeepToken
nep413/src/lib.rsDeepNEP413 Lib
nep461/src/lib.rsDeepNEP461 Lib
num-utils/src/lib.rsDeepNum Utils Lib
serde-utils/src/lib.rsDeepSerde Utils Lib
serde-utils/src/base58.rsDeepBase58
serde-utils/src/base64.rsDeepBase64 (Serde)
webauthn/src/lib.rsDeepWebAuthn Lib
wnear/src/lib.rsDeepWNEAR Lib

Out of scope

The audit will include reviewing the code for security vulnerabilities. The audit does not include a review of the tests and dependencies.

Assessment Framework

Guvenkaya rates findings by likelihood and impact so remediation can be prioritized by technical risk, business context, and the decision the engagement is meant to support.

Rating chain applied to every finding

  1. 01 Likelihood Likely, possible or rare
  2. 02 Impact Severe, moderate or negligible
  3. 03 Severity Derived from the matrix below
  4. 04 Remediation complexity Simple, moderate or difficult
  5. 05 Status Not fixed, fixed, acknowledged or scheduled

Impact

ImpactWhat it means here
SevereExploitation could result in critical loss or compromise, such as full system control, substantial financial loss, or severe reputational damage.
ModerateExploitation may lead to limited data loss, partial compromise, moderate financial impact, or noticeable degradation of services.
NegligibleExploitation has minimal impact, such as minor data exposure without significant consequences or slight inconvenience without substantial disruption.

Likelihood

LikelihoodWhat it means here
LikelyThe vulnerability is easily discoverable and not overly complex to exploit.
PossibleThe vulnerability presents some challenges either in discovery or in the complexity of the attack.
RareThe vulnerability is either very difficult to discover or complex to exploit, or both.

This matrix provides a nuanced view, taking into account both the ease of discovering a vulnerability and the complexity involved in exploiting it.

Attack Complexity \ Discovery EaseObviousConcealedHidden
ComplexPossibleRareRare
ModerateLikelyPossibleRare
StraightforwardLikelyPossiblePossible

Severity

SeverityWhat it means here
CriticalAssigned to vulnerabilities with severe impact and a likely likelihood of exploitation.
HighFor vulnerabilities with either severe impact but only a possible likelihood, or moderate impact with a likely likelihood.
MediumUsed for vulnerabilities with severe impact but a rare likelihood, moderate impact with a possible likelihood, or negligible impact with a likely likelihood.
LowFor vulnerabilities with moderate impact and rare likelihood, or negligible impact with a possible likelihood.
InformationalThe lowest severity rating, typically for vulnerabilities with negligible impact and a rare likelihood of exploitation.
Likelihood \ ImpactSevereModerateNegligible
LikelyCriticalHighMedium
PossibleHighMediumLow
RareMediumLowInformational

Remediation complexity

This measures how difficult it is to remediate a finding once it has been identified.

Remediation complexityWhat it means here
SimplePatches or fixes are readily available and easily implemented.
ModerateRequires some time and resources to remediate, but well within the capabilities of most organizations.
DifficultRemediation requires significant resources, specialized skills, or substantial changes to systems or architecture.

Finding status

This tracks the client's response to each finding and whether remediation has been completed, accepted, or scheduled.

StatusWhat it means here
Not FixedIndicates that the vulnerability has been identified but no remedial action has been taken yet. This status is crucial for newly discovered vulnerabilities or those awaiting prioritization.
FixedThis status is applied when the vulnerability has been successfully remediated. It implies that appropriate measures, such as patching, configuration changes, or architectural modifications, have been implemented to resolve the issue.
AcknowledgedThis status is used for vulnerabilities that have been recognized, but for various reasons (such as risk acceptance, cost, or other business decisions), have not been fixed. It indicates that the risk posed by the vulnerability is known and has been consciously accepted.
ScheduledThis status indicates that the vulnerability has been acknowledged and a plan is in place to fix it in the future. It signifies that while remediation hasn't yet occurred, the issue has been prioritized and is part of the planned development roadmap.

Findings Summary

4All findings
0 Critical
0 High
1 Medium
1 Low
2 Informational

Findings register

FindingImpactLikelihoodSeverityRemediation complexityStatus
GUV-1: Potential Funds Stealing From Users Via Repeating Failed IntentsSevereRareMediumSimpleScheduled
GUV-2: Possible DoS Of Public Keys Viewing Per UserNegligiblePossibleLowSimpleNot Fixed
GUV-3: Arbitrary Public Key Setting In Privileged FunctionsNegligibleRareInformationalSimpleNot Fixed
GUV-4: Missing Event Emission For Critical Access Control OperationsNegligibleRareInformationalSimpleNot Fixed

Detailed Findings

GUV-1: Potential Funds Stealing From Users Via Repeating Failed Intents

Severity
Medium
Impact
Severe
Likelihood
Rare
Remediation Complexity
Simple
Status
Scheduled

Description

Depending on the intent structure, it's possible to maliciously fail a transaction and then repeat specific intents, which could lead to:

  • Stealing tokens
  • Making solvers lose money or perform unauthorized operations

Mainnet deadlines are permissive, ranging from 20 seconds to 10 minutes. This provides ample time to fail a transaction and repeat failed intents. A transaction can be failed by:

  • Invalidating the nonce after signing in a separate transaction.
  • Adding an additional intent to your intent array that transfers funds out and fails your token diff

Malicious actor can:

  • Repeat selected intents.
  • Repeat selected intents and, to maintain TokenDiff balance, resign your controlled intents with new values.
  • Observe failed intents on the blockchain and reconstruct them like building blocks (while deadlines remain valid).

The risk is low when TokenDiff intent is used, as mainnet calculations are typically precise, making it difficult to modify the intent structure while maintaining zero delta and gaining benefits. The vulnerability is particularly dangerous in P2P transfer scenarios where TokenDiff intent isn't used, allowing for immediate exploitation with high success rates.

Impact

Funds can be stolen in scenarios where TokenDiff intent isn't used.

Recommendation

This behavior should be documented to emphasize that TokenDiff is the preferred method, while Transfer should be discouraged for facilitating swaps. Users must understand they are responsible for reviewing and approving what they sign.

Remediation

The NEAR Intents team has acknowledged the issue and will fix it soon by documenting this scenario.

GUV-2: Possible DoS Of Public Keys Viewing Per User

Severity
Low
Impact
Negligible
Likelihood
Possible
Remediation Complexity
Simple
Status
Not Fixed

Description

It was observed that since user can have unlimited public keys, it is possible for a malicious user to cause a DoS of public_keys_of method when their account is used. That’s because public_keys_of iterates over public keys of a provided account and if account has a lot of public keys it can lead to the error due to a gas limit.

defuse/src/contract/accounts/mod.rs
fn public_keys_of(&self, account_id: &AccountId) -> HashSet<PublicKey> {    self.accounts.get(account_id).map_or_else(        || {            PublicKey::from_implicit_account_id(account_id)                .into_iter()                .collect()        },        |account| account.iter_public_keys(account_id).collect(),    )}

Impact

  • Errors in off-chain components, which utilize public_keys_ofmethod.
  • If iter_public_keys is utilized within the smart contract logic somewhere else, depending on a logic it can lead to the DoS on protocol level

Recommendation

It is recommended to limit the number of public keys each account can have

Remediation

The NEAR Intents team has not fixed the issue yet.

GUV-3: Arbitrary Public Key Setting In Privileged Functions

Severity
Informational
Impact
Negligible
Likelihood
Rare
Remediation Complexity
Simple
Status
Not Fixed

Description

The codebase accepts public keys in multiple locations without proper validation. The NEAR SDK's PublicKey type lacks comprehensive validation of public key formats and values. Malicious users could potentially inject invalid or malformed public keys, leading to undefined behavior in cryptographic operations.

PoC

poc
fn test_parse_zero_pubkey() {use near_sdk::PublicKey;let zero_pubkey_str = "ed25519:11111111111111111111111111111111";let result = zero_pubkey_str.parse::&lt;PublicKey&gt;();assert!(result.is_err());}

Impact

  • Potential undefined behavior in cryptographic operations
  • Potential injection of weak public keys that can lead to signature malleability

Recommendation

Implement comprehensive validation for public keys in all relevant functions.

  • Account Public Key Management (add_public_key, remove_public_key)
  • Relayer Keys Management (do_add_relayer_key, delete_relayer_key)
  • Full Access Keys Management (add_full_access_key, delete_key)

Remediation

The NEAR Intents team has not fixed the issue yet.

GUV-4: Missing Event Emission For Critical Access Control Operations

Severity
Informational
Impact
Negligible
Likelihood
Rare
Remediation Complexity
Simple
Status
Not Fixed

Description

The relayer keys operations lacks event emissions for access control operations in delete_relayer_key() and do_add_relayer_key() methods. This omission makes it difficult to track and audit changes to the relayer key set off-chain. Events are essential for maintaining transparency and allowing external systems to monitor and react to important state changes in the contract.

Recommendation

Implement event emissions for both adding and removing relayer keys

Remediation

The NEAR Intents team has not fixed the issue yet.

The web version and the PDF (19 pages) are generated from the same source. The report as first delivered is kept in the public reports archive.

Tell us what you need to secure.

Describe your system, main concern, and deadline. We’ll reply with scoping questions and a proposed next step.

Discuss your scope