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

TemplarSingle Chain Smart Contracts Security Review

Guvenkaya reviewed the Templar single-chain lending market smart contracts on NEAR.

Templar logo

Date of engagement: 1st April 2025 - 14th April 2025

  • Michal BajorPrincipal advisor

Engagement Dashboard

Audit results

Guvenkaya conducted a security assessment of the Templar Single Chain NEAR Smart Contracts from 1st April 2025 to 14th April 2025. During this engagement, a total of 3 findings were reported. 1 of the findings was High and the remaining were informational severity. The Templar team has either fixed or acknowledged all the issues.

Engagement record

Client
Templar
System
Templar market contracts on NEAR
Review period
1st April 2025 - 14th April 2025
Reviewed baseline
aeb8a93d8844b6b9bb17187e6d9172b713c611fd
Paths in scope
25
Principal advisor
Michal Bajor

Timeline

  1. Review start1st April 2025
  2. Draft report14th April 2025
  3. Final report17th April 2025

Findings by severity

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

Finding status at final report

3Raised
1Fixed
2Acknowledged

Remediation complexity

2Simple
1Moderate

Impact

1Moderate
2Negligible

Likelihood

1Likely
2Rare

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

Templar is the first Cypher Lending Protocol for Bitcoin. Templar lets you borrow any asset against your Bitcoin without trusting centralized institutions.

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. 25 paths are in scope. Each path links to the file at the reviewed commit.

PathReview depthScope note
common/src/accumulator.rsDeepAccumulator
common/src/asset.rsDeepAsset
common/src/borrow.rsDeepBorrow
common/src/chunked_append_only_list.rsDeepChunked Append Only List
common/src/event.rsDeepEvent
common/src/fee.rsDeepFee
common/src/interest_rate_strategy.rsDeepInterest Rate Strategy
common/src/lib.rsDeepLib
common/src/market/balance_oracle_configuration.rsDeepMarket Balance Oracle Configuration
common/src/market/configuration.rsDeepMarket Configuration
common/src/market/external.rsDeepMarket External
common/src/market/impl.rsDeepMarket Implementation
common/src/market/mod.rsDeepMarket Module
common/src/number.rsDeepNumber
common/src/oracle/mod.rsDeepOracle Module
common/src/oracle/pyth.rsDeepOracle Pyth
common/src/snapshot.rsDeepSnapshot
common/src/static_yield.rsDeepStatic Yield
common/src/supply.rsDeepSupply
common/src/time_chunk.rsDeepTime Chunk
common/src/withdrawal_queue.rsDeepWithdrawal Queue
contract/market/src/lib.rsDeepMarket Contract Lib
contract/market/src/impl_ft_receiver.rsDeepMarket Contract FT Receiver
contract/market/src/impl_helper.rsDeepMarket Contract Helper
contract/market/src/impl_market_external.rsDeepMarket Contract External

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

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

Findings register

FindingImpactLikelihoodSeverityRemediation complexityStatus
GUV-1: Supply Withdrawal Mechanism DoSModerateLikelyHighModerateFixed
GUV-2: Reliance On Bot Oracle UpdatesNegligibleRareInformationalSimpleAcknowledged
GUV-3: Possible Self-liquidiationNegligibleRareInformationalSimpleAcknowledged

Detailed Findings

GUV-1: Supply Withdrawal Mechanism DoS

Severity
High
Impact
Moderate
Likelihood
Likely
Remediation Complexity
Moderate
Status
Fixed

Description

The Supply Withdrawal process operates on a queue mechanism. First user creates a withdrawal request which is added to the queue. Then, separate and permissionless function (execute_next_supply_withdrawal_request) is processing those requests in order of their creation. There is a check in callback that verifies if the token transfer was successful. In case it wasn't, it essentially doesn't modify the queue so that next execute_next_supply_withdrawal_request call will try to process the same request. The assumption being that this transfer fails if Market contract doesn't have enough tokens to transfer. There is another possible case, that a malicious user can use to damage the protocol (and also create a ransom-like situation). NEP141 tokens allow users to unregister (withdraw their storage deposit). When that happens, their balance is completely removed from the token contract and transferring tokens to that user fails. A malicious user can:

  • Supply tokens
  • Unregister from the token contract
  • Create a supply withdrawal request

At that point, when withdrawal queue reaches that malicious user's request - the whole functionality stops functioning as no request can be processed at that time. This is a somewhat recoverable state, if token used for supply is following the default storage implementation, which allows anyone to register anyone else. However, that means someone else would need to cover storage fees for a malicious user in a token contract that this malicious user can then withdraw to himself by unregistering again, which can create a "vicious cycle" and essentially means malicious user would be requesting a ransom to allow supply withdrawal to function.

impl_market_external:execute_next_supply_withdrawal_request:market/src/impl_helper.rs
PromiseOrValue::Promise(                    self.configuration                        .borrow_asset                        .transfer(                            withdrawal_resolution.account_id.clone(),                            withdrawal_resolution.amount_to_account,                        )                        .then(                            self_ext!(Self::GAS_AFTER_EXECUTE_NEXT_WITHDRAWAL) .execute_next_supply_withdrawal_request_01_finalize(withdrawal_resolution),                        ), )}
impl_helper:execute_next_supply_withdrawal_request_01_finalize:market/src/impl_helper.rs
PromiseResult::Failed => {                // Withdrawal failed: unlock the queue so they can try again.                // This occurs when the contract does not control enough of                // the borrow asset to fulfill the withdrawal request. That is                // to say, it has distributed all of the funds to current                // borrows.                 env::log_str("The withdrawal request cannot be fulfilled at this time. Please try again later.");                self.withdrawal_queue.unlock();                if let Some(mut supply_position) =                    self.supply_position_guard(withdrawal_resolution.account_id.clone())                {                    // This should not do very much since we also accumulate                    // yield in the initial function call of execute_next_supply_withdrawal_request()                    let proof = supply_position.accumulate_yield();                    let mut amount = withdrawal_resolution.amount_to_account;                    amount.join(withdrawal_resolution.amount_to_fees);                    supply_position.record_deposit(proof, amount, env::block_timestamp_ms());                } }

Impact

Denial of Service condition on the supply withdrawal functionality, along with potential funds lost for users or protocol operators when trying to mitigate the Denial of Service.

Recommendation

Implement a mechanism that would utilize internal accounting to estimate whether a token transfer failed due to malicious user unregistering or due to missing token supply. Should the situation be determined as a result of malicious user's action, the Withdrawal Request should be removed from the queue.

Remediation

The Templar team has fixed the issue.

GUV-2: Reliance On Bot Oracle Updates

Severity
Informational
Impact
Negligible
Likelihood
Rare
Remediation Complexity
Simple
Status
Acknowledged

Description

The contract uses Pyth Oracle's list_ema_prices_no_older_than function to retrieve the prices. The functionalities using the price data will fail if the Oracle will not be able to provide prices, which will happen if the most recent available price is older than the configured threshold. It must be noted that currently there is a bot service running on mainnet that seems to be updating the prices, however, that might not always be the case. Should the bot be disabled or otherwise stop working, the core functionalities of the contract will not be possible to execute successfuly.

Impact

Possible Denial of Service leading to a potential economic repercussions due to inability to execute actions related to the price data.

Recommendation

It is recommended to implement a fail-safe mechanism that would be able to use Pyth's update_price_feeds endpoint in order to update the prices manually, should the bot stop being reliable.

Remediation

The Templar team has acknowledged the issue by stating that there are already measures implemented preventing that scenario.

GUV-3: Possible Self-liquidiation

Severity
Informational
Impact
Negligible
Likelihood
Rare
Remediation Complexity
Simple
Status
Acknowledged

Description

It was observed that the contract does not implement any mechanism that would prevent users from self-liquidating. Such an action does not directly damage the protocol and requires a liquidable user to win a race with other liquidators. Should this situation happen, this scenario translates to a repayment with a discount rather than a liquidation.

It must be noted that ultimately this scenario is not completely preventable, as users are free to operate using many different AccountIds.

Impact

Cheaper loan repayment.

Recommendation

It is recommended to add a check that would at least prevent a self-liquidation.

Remediation

The Templar team has acknowledged the issue but it won't be fixed.

The web version and the PDF (15 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