Templar Protocol User Guide
This is a comprehensive user guide for the Templar Protocol smart contracts.
For definitions of key terms and concepts, refer to the Glossary.
Quick Navigation
- Smart Contract Addresses - Official contract addresses and verification
- Protocol Governance - Administrative controls and upgrade mechanisms
- Oracle System - Price feed infrastructure and monitoring
- Security Reporting - Security practices and vulnerability reporting
- Monitoring and Risk Management - Protocol health monitoring systems
- Testing and Coverage - Comprehensive test suite documentation
Market Operations
- Market Overview - Core market functionality
- Supply Assets - How to supply assets to earn yield
- Borrow Assets - How to borrow against collateral
- Liquidations - Liquidation mechanisms and procedures
Additional Resources
- Implementation Notes - Technical implementation details
Smart Contracts
Market
A single Templar market represents a pair of collateral and borrow assets, such as BTC/USDC for Bitcoin-collateralized USDC loans.
Suppliers may deposit borrow assets into the market, and their funds will earn yield from the protocol fees paid by borrowers. Borrowers may borrow available supply assets from the market, paying a variable interest rate based on the supply utilization rate.
Markets support NEAR fungible asset contracts implementing the NEP-141 standard or the NEP-245 standard. The borrow and collateral assets do not need to implement the same standard.
Storage Management
Before interacting with a market (supplying, borrowing, depositing collateral, etc.), accounts must first register with the market contract by making a storage deposit. This is required because the market contract implements NEP-145 (Storage Management) to cover the storage costs of maintaining user positions on-chain.
Making a Storage Deposit
To register with a market and deposit the required storage cost:
near contract call-function as-transaction \
<market-id> storage_deposit \
json-args '{}' \
prepaid-gas '10.0 Tgas' \
attached-deposit '0.00125 NEAR' \
sign-as <account-id>
The minimum required deposit can be obtained by calling the storage_balance_bounds function:
near contract call-function as-read-only \
<market-id> storage_balance_bounds \
json-args '{}' \
network-config mainnet \
now
Note: This storage deposit step is handled automatically in the Templar frontend application, but must be done manually when interacting directly with the market contracts.
Interactions
Accounts can interact with markets in seven primary ways:
- Deposit supply
- Withdraw supply
- Deposit collateral
- Withdraw collateral
- Borrow supply
- Repay supply
- Liquidate borrow position
Configuration
A market's configuration is immutable after deployment. It can be obtained from the market contract by calling the get_configuration function.
Example
near contract \
call-function as-read-only ibtc-usdc.v1.tmplr.near get_configuration \
json-args {} \
network-config mainnet \
now
Output
{
"borrow_asset": {
"Nep141": "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1"
},
"borrow_asset_maximum_usage_ratio": "0.99000000000000000000000000000000000001",
"borrow_interest_rate_strategy": {
"Piecewise": {
"base": "0",
"optimal": "0.90000000000000000000000000000000000001",
"rate_1": "0.08888888888888888888888888888888888889",
"rate_2": "2.40000000000000000000000000000000000001"
}
},
"borrow_maximum_duration_ms": null,
"borrow_mcr_liquidation": "1.19999999999999999999999999999999999999",
"borrow_mcr_maintenance": "1.25",
"borrow_origination_fee": {
"Proportional": "0.00099999999999999999999999999999999999"
},
"borrow_range": {
"maximum": null,
"minimum": "1"
},
"collateral_asset": {
"Nep245": {
"contract_id": "intents.near",
"token_id": "nep141:btc.omft.near"
}
},
"liquidation_maximum_spread": "0.05000000000000000000000000000000000001",
"price_oracle_configuration": {
"account_id": "pyth-oracle.near",
"borrow_asset_decimals": 6,
"borrow_asset_price_id": "eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
"collateral_asset_decimals": 8,
"collateral_asset_price_id": "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43",
"price_maximum_age_s": 60
},
"protocol_account_id": "revenue.tmplr.near",
"supply_range": {
"maximum": null,
"minimum": "40000"
},
"supply_withdrawal_fee": {
"behavior": "Fixed",
"duration": "0",
"fee": {
"Flat": "0"
}
},
"supply_withdrawal_range": {
"maximum": null,
"minimum": "40000"
},
"time_chunk_configuration": {
"BlockTimestampMs": {
"divisor": "600000"
}
},
"yield_weights": {
"static": {
"revenue.tmplr.near": 1,
"rewards.tmplr.near": 1
},
"supply": 1
}
}
Snapshots
Interest and yield on borrow and supply positions are calculated using a snapshot system.
After a "time chunk" (e.g. 1 hour) elapses, the contract takes a snapshot, recording such things as the total supply deposit, amount borrowed, timestamp, etc.
Whenever a borrow or supply position update requires, interest/yield calculations are triggered. (They can also be triggered explicitly using harvest_yield and apply_interest.) These calculations iterate from the snapshot at which the record was last updated until the most-recently-finalized snapshot unless a snapshot limit is provided.
Supply
Accounts may deposit assets to the market's supply to earn yield.
Deposit
To add funds to a market's supply, send the to the contract, specifying "Supply" as the transfer msg.
For example:
near contract call-function as-transaction \
<borrow-asset-contract-id> ft_transfer_call \
json-args '{
"receiver_id": "<market-id>",
"amount": "<amount>",
"msg": "\"Supply\""
}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '1 yoctoNEAR' \
sign-as <account-id>
Withdraw
Since borrowers borrow the assets that suppliers have supplied, when a supplier wishes to withdraw their supply, there might not be enough available to withdraw at that time. However, through fees, interest, etc., as time passes, borrow assets should become available to withdraw again.
Because the market may not have sufficient borrow asset liquidity when a supplier wishes to withdraw, the market uses a queue-based withdrawal system.
In order to withdraw supply from the market, a supplier must first enter the supply withdrawal queue with their withdrawal request:
near contract call-function as-transaction \
<market-id> create_supply_withdrawal_request \
json-args '{"amount": "<amount>"}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR' \
sign-as <account-id>
Now the account has a position in the queue. Should the account wish to update the amount of the request, it can call create_supply_withdrawal_request again, however, this will also reset its position to the end of the queue.
A supply withdrawal request can be cancelled via cancel_supply_withdrawal_request.
In order for an account's supply withdrawal request to be fulfilled, all of the requests that are ahead of it in the queue must be fulfilled first.
To execute the next withdrawal request, use the execute_next_supply_withdrawal_request function:
near contract call-function as-transaction \
<market-id> execute_next_supply_withdrawal_request \
json-args '{}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR' \
sign-as <account-id>
This function is not permissioned; anyone may call it to advance the withdrawal queue.
Borrow
Accounts may borrow assets from the market's supply.
Borrow positions must be collateralized with a minimum amount of collateral asset determined by the market's configuration.
Deposit collateral
To add collateral to an account's position, transfer-call the market tokens with a msg of "Collateralize":
near contract call-function as-transaction \
<collateral-asset-contract-id> ft_transfer_call \
json-args '{
"receiver_id": "<market-id>",
"amount": "<amount>",
"msg": "\"Collateralize\""
}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '1 yoctoNEAR' \
sign-as <account-id>
Withdraw collateral
The collateral withdrawal process is relatively straightforward as compared to the supply withdrawal process: simply call withdraw_collateral, passing the amount of collateral asset tokens you wish to withdraw:
near contract call-function as-transaction \
<market-id> withdraw_collateral \
json-args '{ "amount": "<amount>" }' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR' \
sign-as <account-id>
While this process is simple, collateral can only be withdraw so long as the value of the remaining collateral continues to satisfy the market's borrow_mcr_maintenance requirement.
Borrow
Once an account's position is collateralized, borrow asset can be withdrawn.
near contract call-function as-transaction \
<market-id> borrow \
json-args '{ "amount": "<amount>" }' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR' \
sign-as <account-id>
As long as the collateralization requirements are met, the borrow amount (minus fees) will be sent to the predecessor account.
Repay
As long as an account has a liability (principal + interest/fees), some or all of their collateral will be locked so that it cannot be withdrawn.
To unlock the collateral, the account must repay its liability to the market.
To perform a repayment, transfer-call tokens to the market with a msg of "Repay":
near contract call-function as-transaction \
<borrow-asset-contract-id> ft_transfer_call \
json-args '{
"receiver_id": "<market-id>",
"amount": "<amount>",
"msg": "\"Repay\""
}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '1 yoctoNEAR' \
sign-as <account-id>
Liquidate
Liquidation is the process by which the asset collateralizing certain positions may be reappropriated e.g. to recover assets for an undercollateralized position.
A liquidator is a third party willing to send a quantity of a market's borrow asset (usually a stablecoin) to the market in exchange for the amount of collateral asset supporting a specific account's position. As compensation for this service, the liquidator receives an exchange rate that is slightly better than the current rate. This difference in rates is called the "liquidator spread," and the maximum liquidator spread is configurable on a per-market basis.
- The liquidator MUST ensure that its account is able to receive the collateral tokens. Usually this means opting-in to storage management (if the collateral token in question implements that standard). If the collateral transfer fails, the liquidator will not be refunded!
- It is the responsibility of the liquidator to calculate the optimal amount of tokens to attach to a liquidation call. The market will either completely accept or completely reject the liquidation attempt—no refunds!
A liquidator will follow this high-level workflow:
- The liquidator obtains a list of accounts borrowing from the market by calling
list_borrow_positions. - The liquidator checks the status of each account by calling
get_borrow_status. - If an account's status is
Liquidation, that means the liquidator can obtain a spread by sending an amount of borrow asset to the market. The maximum spread isliquidation_maximum_spreadin the market configuration. - To perform the liquidation, the liquidator transfer-calls the appropriate amount of borrow asset to the market. That is to say, the liquidator calls
ft_transfer_call/mt_transfer_callon the borrow asset's smart contract, specifying the market as the receiver. Themsgparameter indicates 1) that the transfer is for a liquidation, and 2) which account is to be liquidated.
Thus, the arguments to a liquidation call might look something like this:
{
"amount": "<amount>",
"msg": {
"Liquidate": {
"account_id": "<account-to-liquidate>"
}
},
"receiver_id": "<market-id>"
}
Example
near contract call-function as-transaction \
<borrow-asset-contract-id> ft_transfer_call \
json-args '{
"receiver_id": "<market-id>",
"amount": "<amount>",
"msg": "{ \"Liquidate\": { \"account_id\": \"<account-to-liquidate>\" } }"
}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '1 yoctoNEAR' \
sign-as <account-id>
Registry
The registry is a contract that maintains a list of contract versions, deploys new contracts, and maintains a list of those deployments.
Market contracts are deployed through a registry, and thus appear as its subaccounts.
The account ID of the mainnet market registry is v1.tmplr.near.
Interactions
List available versions
near contract call-function as-read-only \
v1.tmplr.near list_versions \
json-args '{"offset":0,"count":100}' \
network-config mainnet \
now
Output:
[
"v1.0.0",
"v1.1.0"
]
List deployments
near contract call-function as-read-only \
v1.tmplr.near list_deployments \
json-args '{"offset":0,"count":100}' \
network-config mainnet \
now
Output:
[
"ibtc-usdc.v1.tmplr.near",
"stnear-usdc.v1.tmplr.near",
"ibtc-iethusdc.v1.tmplr.near",
"iethwbtc-iethusdc.v1.tmplr.near",
"ibtc-usdc-1.v1.tmplr.near",
"stnear-usdc-1.v1.tmplr.near"
]
LST Oracle
The LST oracle adapter enhances base oracle functionality by supporting a broader range of asset classes. The primary transformation supported by the LST oracle adapter is price normalization of a liquid staking token (LST).
Price normalization requires retrieving the price of the underlying asset and the conversion rate between the LST and the underlying asset and combining them to produce a price for the LST asset itself.
Example: stNEAR Price Calculation
Examine the transformer specification:
near contract call-function as-read-only \
lst.oracle.tmplr.near get_transformer \
json-args '{"price_identifier":"c23cb2430c81d475fbd1c235324d4987f2dd01431bf7ab3e7b9d69b9f6701470"}' \
network-config mainnet \
now
Output:
{
"action": {
"NormalizeNativeLstPrice": {
"decimals": 24
}
},
"call": {
"account_id": "meta-pool.near",
"args": "bnVsbA==",
"gas": "3000000000000",
"method_name": "get_st_near_price"
},
"price_id": "c415de8d2eba7db216527dff4b60e8f3a5311c740dadb233e13e12547e226750"
}
This specification describes the following flow:
- Retrieve the NEAR price from the Pyth oracle (asset ID
c415de8d2eba7db216527dff4b60e8f3a5311c740dadb233e13e12547e226750). - Retrieve the stNEAR redemption rate from the staking contract (
meta-pool.near->get_st_near_price({})). - Calculate
price_stnear = price_near * redemption_rate / 10^24.
Smart Contract Deployments
This page provides information about Templar Protocol smart contracts and how to interact with them.
Deployments
- Registry:
v1.tmplr.near - LST Oracle Adapter:
lst.oracle.tmplr.near
Markets
Market contracts are deployed dynamically through the registry. Each market represents a single asset pair (COLLATERAL → BORROW).
A selection of available markets is shown below:
| Account ID | Collateral Asset | Borrow Asset |
|---|---|---|
ibtc-iethusdc.v1.tmplr.near | Native BTC (via NEAR Intents) | USDC on Ethereum (via NEAR Intents) |
iethwbtc-iethusdc.v1.tmplr.near | wBTC on Ethererum (via NEAR Intents) | USDC on Ethereum (via NEAR Intents) |
ibtc-usdc-1.v1.tmplr.near | Native BTC (via NEAR Intents) | USDC on NEAR |
stnear-usdc-1.v1.tmplr.near | stNEAR on NEAR | USDC on NEAR |
ixlm-ixlmusdc.v1.tmplr.near | Native XLM (via NEAR Intents) | USDC on XLM (via NEAR Intents) |
Contract Verification
All smart contracts use reproducible builds. To verify deployed code:
near contract verify deployed-at <contract-id> mainnet now
Example output:
INFO The code obtained from the contract account ID and the code calculated from the repository are the same.
| Contract code hash: DaudmUa3nAym9dfQkn8mpNPZxkphSRGwEaTMgtymVhFE
| Contract version: 1.0.0
| Standards used by the contract: [nep330:1.2.0]
| View the contract's source code on: https://github.com/Templar-Protocol/contracts/tree/1d736e62a86424dd947284cbd8e83bef803fa9fb
| Build Environment: sourcescan/cargo-near:0.13.4-rust-1.85.0@sha256:a9d8bee7b134856cc8baa142494a177f2ba9ecfededfcdd38f634e14cca8aae2
| Build Command: cargo near build non-reproducible-wasm --locked
Oracles
Templar Protocol relies on external price oracles to determine asset valuations when calculating collateralization ratios and performing liquidations.
Pyth Network is the primary oracle provider (documentation).
Pyth is a pull oracle, meaning that the price feeds are updated as-needed instead of continuously. As such, interactions with Templar markets should always be preceded by a call to the appropriate oracle contract to update the necessary asset prices using a proof provided by Pyth.
More information about how to perform this update on NEAR can be found on Pyth's documentation site.
Oracle Addresses
| Network | Account ID |
|---|---|
| Testnet | pyth-oracle.testnet |
| Mainnet | pyth-oracle.near |
Price Identifiers
Price identifiers for Pyth Network assets can be found on their documentation site.
LST Oracle Adapter
For Liquid Staking Tokens (LSTs), Templar uses a custom oracle adapter (lst.oracle.tmplr.near) to derive the LST price from the underlying asset price(s).
Price Feed Configuration
Each market is configured with the following fields:
#![allow(unused)] fn main() { pub struct PriceOracleConfiguration { /// Account ID of the oracle contract. pub account_id: AccountId, /// Price identifier of the collateral asset in the oracle contract. pub collateral_asset_price_id: PriceIdentifier, /// Collateral asset decimals, to convert the oracle price. pub collateral_asset_decimals: i32, /// Price identifier of the borrow asset in the oracle contract. pub borrow_asset_price_id: PriceIdentifier, /// Borrow asset decimals, to convert the oracle price. pub borrow_asset_decimals: i32, /// Maximum price age to accept from the oracle, after which the price /// will be considered stale and rejected. pub price_maximum_age_s: u32, } }
Update Frequency and Freshness
- Update Frequency: As-needed (pull model)
- On-Chain Updates: Pulled on-demand by protocol operations
- Price Staleness: Configurable maximum age per market (typically 60 seconds)
Price Validation
Markets validate price freshness before use. If prices are stale, users must push fresh price data to the oracle contracts
- Operations that require prices (borrow, liquidate) will fail.
- Users must push updates for fresh price data.
There is currently no backup oracle available.
Oracle Security Measures
- Confidence Intervals: Pyth prices include confidence bands. The lower bound is used for collateral valuations, and the upper bound for liability valuations.
- Multiple Data Sources: Pyth aggregates from multiple price providers.
- Time-Weighted Averages: Market contracts use the exponentially-weighted moving average (EMA) price information.
- Maximum Age Limits: Markets reject stale price data using a configurable expiration duration.
Oracle Failure Scenarios
Temporary Outage
- The vast majority of operations will cease to function until fresh price data are available.
- Users can still withdraw collateral from positions with zero liability.
- No borrows or liquidations are supported until fresh price data are available.
Price Manipulation Attack
- Markets will reject stale prices automatically.
- Defensive asset valuations will protect markets from insolvency in most cases.
- The required maintenance MCR will protect borrowers from unexpected liquidation in most cases.
Protocol Governance
This document outlines the current administrative structure and governance controls of Templar Protocol.
Registry Contract
The registry contract is immutable once deployed and locked. It designates an owner account, which has permission to add new contract code versions and to deploy new contracts. There is no upgrade mechanism.
Market Contracts
Market contracts are immutable once deployed and locked. The configuration is immutable after deployment. New market versions can be deployed to new account IDs via a registry, but old versions cannot be overwritten. There is no upgrade mechanism. When a new version of the market contract is available, it will be uploaded to the registry contract. New markets can then be deployed using the updated code. However, old markets will not be upgraded, and funds will not be automatically migrated, so users will need to migrate their positions individually.
Market contracts have no administrative functions:
- Operate autonomously based on initial configuration.
- No ability to pause, upgrade, or modify market parameters.
Emergency Procedures
Markets are immutable once they are deployed. If a bug is discovered, a patched version of the code will be uploaded and affected markets will have new versions deployed. However, users will need to migrate their funds individually. To facilitate this process swiftly and securely, users are encouraged to monitor all official communication channels for announcements.
Transparency and Monitoring
Templar markets are open-source, and the source code currently available on GitHub. All completed audits will be made available as soon as possible. See the current list of audits.
Monitoring and Risk Management
Templar Protocol uses available tools and established practices for monitoring protocol health and managing risks.
Protocol Monitoring Tools
Available Monitoring
Bot Infrastructure
The protocol includes operational bots for automated tasks:
-
Liquidation Bot: Monitors positions and executes liquidations
- Configurable intervals and concurrency
- Market registry monitoring
- Oracle price feed integration
- Automated liquidation execution
-
Accumulator Bot: Handles interest accumulation
- Periodic interest calculations
- Multi-market support
- Configurable execution parameters
Gas Usage Monitoring
Gas analysis tools provide performance insights:
./script/ci/gas-report.sh
This generates detailed reports on:
- Function execution costs
- Snapshot iteration limits
- Performance bottlenecks
Manual Monitoring Procedures
Protocol Health Checks
Regular checks can be performed using:
-
Market Status: Query market configurations and states
# Get market configuration near contract call-function as-read-only <market-address> get_configuration json-args {} network-config mainnet now # Check current market snapshot near contract call-function as-read-only <market-address> get_current_snapshot json-args {} network-config mainnet now # Get borrow asset metrics near contract call-function as-read-only <market-address> get_borrow_asset_metrics json-args {} network-config mainnet now # List all deployed markets from registry near contract call-function as-read-only v1.tmplr.near list_deployments json-args '{"offset": 0, "count": 100}' network-config mainnet now -
Oracle Health: Verify price feed freshness and accuracy
# Check oracle prices near contract call-function as-read-only pyth-oracle.near get_price json-args '{"price_identifier": "<asset-price-id>"}' network-config mainnet now # Check LST oracle adapter near contract call-function as-read-only lst.oracle.tmplr.near get_price_data json-args '{}' network-config mainnet nowPrice Feed Status: Monitor price feed health at Pyth Network Price Feeds
Market Data Analysis
Using available view functions:
-
Supply Positions: Monitor individual and aggregate supply positions
# Get supply positions near contract call-function as-read-only <market-address> list_supply_positions json-args '{"offset": 0, "count": 100}' network-config mainnet now -
Withdrawal Queue: Check pending withdrawal requests
# Check withdrawal queue status near contract call-function as-read-only <market-address> get_supply_withdrawal_queue_status json-args {} network-config mainnet now -
Historical Snapshots: Analyze market history
# Get finalized snapshots for historical analysis near contract call-function as-read-only <market-address> list_finalized_snapshots json-args '{"offset": 0, "count": 10}' network-config mainnet now -
Total Value Locked: Monitor TVL at DefiLlama - Templar Protocol
-
Utilization Rate: Calculate from borrow asset metrics
# Get borrow asset metrics to calculate utilization (borrowed / available) near contract call-function as-read-only <market-address> get_borrow_asset_metrics json-args {} network-config mainnet now -
Current Interest Rate: Monitor current rate for supply positions
# Get current yield rate for suppliers near contract call-function as-read-only <market-address> get_last_yield_rate json-args {} network-config mainnet nowNote: Historical interest rate analysis requires an indexer for time-series data
Risk Management
Economic Risk Assessment
Available Analysis Tools
- Market Configuration Review: Analyze MCR ratios and interest rate models TODO: Get parameters from each market deployed
- Oracle Price Monitoring: Track price volatility and feed reliability
- Individual feeds: Pyth Network Price Feeds
- Overall status: Pyth Network Status
- Liquidation Efficiency: Monitor liquidation success rates TODO: Get data from liquidator
- Position Analysis: Assess individual and aggregate position health
- Individual positions: My Account
- Aggregate analysis: TODO: Create from contract data
Risk Mitigation Strategies
- Conservative Parameters: Well-tested collateralization ratios
- Oracle Integration: Multiple validation layers for price feeds
- Liquidation Incentives: Economic incentives for timely liquidations
- Interest Rate Models: Dynamic models responding to market conditions
Operational Monitoring
For operational monitoring procedures, refer to:
- Smart Contract Health: See Protocol Health Checks for contract monitoring procedures
- Gas Efficiency: See Gas Usage Monitoring for performance analysis tools
- Network Dependencies: Monitor external service health using the links below:
- NEAR Network Performance: NEAR Status
- Oracle Provider Status: Pyth Network Status
Criminal Activity Monitoring
SEVERE Account Labels
- SEVERE Account Detection: Telegram notification of SEVERE accounts interacting with Templar contracts
- Monitoring Repository: Details available at templar-monitoring
Testing & Code Coverage
Test Execution
Invoke the test suite with this script:
./script/test.sh
Local Testing
Running Tests with Coverage
# Install coverage tool
cargo install cargo-llvm-cov
# Prepare test contracts
./script/prebuild-test-contracts.sh
# Generate coverage report
cargo llvm-cov --html --output-dir coverage-report
# Generate coverage report (ignore test failures)
cargo llvm-cov --html --output-dir coverage-report --ignore-run-fail
# View HTML report
open coverage-report/html/index.html
Test Categories
- Unit tests: Module-level functionality
- Integration tests: Cross-module interactions
- Contract tests: Smart contract behavior
- End-to-end tests: Full workflow validation
Performance Testing
Gas Usage Analysis
Gas usage analysis is available through existing tools:
./script/ci/gas-report.sh
This generates a gas report for market operations, including average gas costs for individual operations and snapshot iteration limits.
Glossary
This glossary provides definitions for key terms used throughout the Templar Protocol documentation and smart contracts.
A
APY (Annual Percentage Yield): The total return on an investment over one year, including compound interest. In Templar, this represents the effective yearly return for suppliers or the cost for borrowers.
Asset Pair: The combination of collateral asset and borrow asset that defines a market (e.g., BTC/USDC means Bitcoin collateral, USDC borrowing).
B
Borrow Asset: The token that users can borrow from the market. Typically a stablecoin like USDC, but can be any supported token.
Borrow Position: A user's borrowing account containing collateral deposits, borrowed amounts, accumulated interest, and current status.
Borrower: A user who deposits collateral and borrows assets from the market, paying interest on the borrowed amount.
C
Collateral Asset: The token deposited by borrowers to secure their loans. Must be worth more than the borrowed amount due to over-collateralization requirements.
Collateralization Ratio (CR): The ratio of collateral value to borrowed value. A 150% ratio means $150 of collateral backs $100 of debt.
Compounding: The process of automatically reinvesting earned yield to generate additional returns over time.
D
Debt: The total amount owed by a borrower, including principal plus accumulated interest and fees.
E
EMA: Exponentially-weighted moving average. A time-series smoothing technique that favors recency.
F
FMV (Fair Market Value): The current market price of an asset as determined by oracle price feeds.
G
Gas: The computational cost for executing transactions on the NEAR blockchain.
H
Harvest Yield: The action of claiming accumulated yield from a supply position. Can be withdrawn or compounded.
I
Interest Accumulation: The process of calculating and adding accrued interest to a borrower's total liability.
L
Lending: The general practice of providing assets to borrowers in exchange for interest payments. In Templar, suppliers lend to the market pool.
Liability: The total debt owed by a borrower, including principal, accumulated interest, and fees.
Liquidation: The forced sale of a borrower's collateral when their position becomes undercollateralized or expires.
Liquidator: A third party who performs liquidations by repaying part of a borrower's debt in exchange for discounted collateral.
Liquidator Spread: The discount liquidators receive when purchasing collateral, serving as incentive for providing the liquidation service.
Liquidity: The availability of assets in the market for borrowing or withdrawal. When liquidity is low, withdrawal requests may need to wait in the queue.
Liquidity Pool: The combined supply of assets deposited by all suppliers in a market, available for borrowers to access.
M
Market: A smart contract managing lending and borrowing for a specific asset pair (e.g., BTC/USDC market).
Maximum Usage Ratio: The maximum percentage of supplied assets that can be borrowed from a market, preventing over-utilization and maintaining liquidity reserves.
MCR (Minimum Collateralization Ratio): The minimum ratio of collateral value to borrowed value required to maintain a position. Different MCR levels trigger maintenance requirements or liquidation.
MCR Liquidation: The minimum collateralization ratio below which a position becomes eligible for liquidation.
MCR Maintenance: The minimum collateralization ratio required for new borrows or collateral withdrawals.
N
NEAR Intents: A NEAR Protocol feature that allows users to express desired outcomes (intents) that can be fulfilled by solvers, enabling more flexible and efficient transaction execution. See the official NEAR Intents documentation.
NEP-141: The NEAR Protocol standard for fungible tokens, similar to Ethereum's ERC-20. See the official NEP-141 specification.
NEP-245: The NEAR Protocol standard for multi-token contracts, similar to Ethereum's ERC-1155. See the official NEP-245 specification.
O
Oracle: A service providing real-time price data for assets, essential for calculating collateralization ratios and liquidations.
Origination Fee: A fee charged when creating a new borrow position, can be flat amount or percentage-based.
Over-collateralization: The requirement for borrowers to deposit collateral worth more than the borrowed amount, providing a safety buffer against price volatility.
P
Partial Liquidation: Liquidating only enough collateral to bring a position back to the maintenance MCR, rather than liquidating the entire position.
Principal: The original amount borrowed or supplied, excluding accumulated interest and fees.
Protocol Revenue: Fees collected by the protocol from borrowers and suppliers, distributed to suppliers and other accounts according to configured yield weights.
Pyth Network: A decentralized oracle network providing high-frequency price feeds for various assets.
R
Registry: A smart contract that manages deployment and versioning of market contracts within the Templar Protocol.
Repay: The action of returning borrowed assets plus interest to reduce or eliminate a borrower's debt.
S
Snapshot: A point-in-time record of market state including interest rates, asset amounts, and yield distribution.
Stablecoin: A cryptocurrency designed to maintain stable value, typically pegged to a fiat currency like USD. Commonly used as borrow assets in lending protocols.
Static Yield: A fixed allocation of market revenue to specific accounts, independent of their supply activity. Defined in the market's yield_weights configuration, static yield is distributed proportionally to designated accounts and can be withdrawn using the withdraw_static_yield function.
Supply: The total amount of assets deposited by suppliers that are available for borrowing in a market.
Supplier: A user who deposits assets into the market to earn yield from borrower interest payments.
Supply Withdrawal Fee: A fee charged when suppliers withdraw their assets from the market, configured per market to manage liquidity.
T
Time Chunk: A configurable time period (based on blocks, epochs, or timestamps) that determines when new snapshots are created.
Transfer Call: A token transfer that includes data, allowing the receiving contract to execute logic based on the transfer.
U
Undercollateralized: A borrow position where the collateral value falls below the required minimum ratio, making it eligible for liquidation.
Utilization Rate: The percentage of supplied assets currently borrowed. Calculated as: borrowed_amount / total_supplied_amount.
W
Withdrawal Queue: A first-in-first-out system for processing supply withdrawals when market liquidity is insufficient.
Y
Yield: The return earned by suppliers on their deposited assets, generated from borrower interest payments and fees.
Security Reporting
Templar Protocol takes security seriously and encourages responsible disclosure of security vulnerabilities.
All smart contracts are open-source and use reproducible builds for maximum transparency.
Bug Bounty
Templar has partnered with Immunefi to reward up to $100k for in-scope smart contract vulnerabilities.
To report smart contract vulnerabilities, please participate in our Immunefi bug bounty.
Security Contact
For security vulnerabilities and sensitive issues, please email security@templarprotocol.com.
Security Alerts
Important security notices will be posted on the official Discord server, Telegram channel, and X (Twitter) account.
Audit Information
Audit reports are available on GitHub.
Responsible Disclosure
If you have discovered a security issue, please follow these steps:
- Report: Send vulnerability details to Immunefi bug bounty for smart contract vulnerabilities or security@templarprotocol.com for other security issues.
- Investigation: Security team will assess the report.
- Resolution: Fix development and deployment.
- Public Disclosure: Coordinated disclosure after fix.
Security reports should include:
- A clear description of the vulnerability.
- Steps to reproduce the issue.
Notes
Sending funds to the market contract
When sending funds to a contract, you must call the asset contract's *_transfer_call function with the market as the receiver_id. So, for a token contract that implements the NEP-141 (Fungible Token) standard, you must call ft_transfer_call, specifying the market account ID as the receiver_id argument. For a token contract that implements the NEP-245 (Multi Token) standard, you must call mt_transfer_call.
If the funds are not sent using a *_transfer_call function, the contract will not be able to respond to the transfer: the funds will not be tracked by the contract, they will not be added to the supply, and the funds cannot be returned or withdrawn.
Contract interaction syntax
Contract interactions will be shown using near-cli-rs syntax. It can be installed via:
cargo install near-cli-rs
Example
near contract call-function as-transaction \
ibtc-usdc.v1.tmplr.near borrow \
json-args '{ "amount": "1000" }' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR' \
sign-as account.near \
network-config mainnet \
sign-with-keychain \
send
This command calls the function borrow on the contract ibtc-usdc.v1.tmplr.near with the arguments payload:
{
"amount": "1000"
}
Large numbers are serialized as strings instead of numerical literals to ensure that the precision limitations of JSON parsers do not affect the values. (See "Notes on Serialization" on docs.near.org.)
The command attaches 100 teragas units and 0 NEAR to the call, signs the transaction as account.near using a key saved to the local keychain, and sends the transaction to NEAR mainnet.
Please refer to the near-cli-rs user guide for more details.