# What?

What is The Risk Protocol and what are we building.

{% hint style="info" %}
Last updated on 17/08/2026
{% endhint %}

## Building the Missing Risk Layer of Crypto

The Risk Protocol (“TRP”) is building foundational *decentralized crypto risk infrastructure* and pioneering ‘**RiskFi**'—a novel vertical within DeFi that *turns risk itself into a programmable, tradeable financial primitive*

Investing and trading in crypto entail various kinds of risks—volatility, liquidity, smart contract risk, regulatory risk, counterparty risk, etc. Our core purpose is to drive the evolution of decentralized finance by allowing traders to *price*, *tokenize*, *hedge,* and *trade* these various risk exposures.  We do this by providing next-generation risk products designed not just to harness risk but also to exploit the unique alpha opportunities unlocked by these new primitives. These risk products are useful to both short-term traders and longer-term investors, for those who want to hedge risk and those who want to speculate on it.&#x20;

> #### *<mark style="color:blue;">"Risk is one resource crypto has in abundance—yet it remains largely unharvested. The Risk Protocol lets users turn that risk to their advantage, transforming it from a problem into an asset. The Risk Protocol converts crypto’s greatest challenge into a new frontier of opportunity"</mark>*

## The Volatility Dilemma

Cryptocurrency markets are famously volatile. While volatility can offer outsized gains, it also undermines the use of crypto as a stable store of value, collateral, or medium of exchange. Prices swing wildly, making it difficult for investors and everyday users to hold crypto confidently without fear of sharp drawdowns. Lacking a native risk-management layer, many investors flee to stablecoins (mostly backed by fiat) to escape volatility, ironically tethering themselves to fiat currencies. This reliance on USD-pegged assets runs counter to crypto’s ethos of decentralization and financial sovereignty. In short, *crypto has a risk problem—*&#x65;normous inherent volatility, but no dedicated, on-chain tools to see, trade, or hedge that volatility itself. This, then, is the first crypto risk we address— **volatility**.

## Risk Tokenization

With Risk Tokenization, our initial product, we provide a crypto-native way to hedge or speculate on crypto volatility. We can split any cryptocurrency into different **SMART Tokens** that offer traders different *risk profiles of that cryptocurrency, with no margin calls or funding rates*. These SMART Tokens give traders and investors a choice of which risk profile of the underlying crypto they wish to own at any point in time. As market conditions and trader sentiment shift, we anticipate traders and investors switching between these SMART tokens to express their market expectations. As illustrated in the figure below, picking the right SMART token across market cycles can lead to massive outperformance relative to simply holding the underlying cryptocurrency.&#x20;

#### **Dynamically Shifting Between RiskON BTC & RiskOFF BTC**

<figure><img src="/files/DwNzl9Sp99klG3qNDfmT" alt=""><figcaption></figcaption></figure>


# Why?

Why are we tokenizing risk and why should traders care

## Gigantic Untapped Market&#x20;

In TradFi, a very significant and robust risk ecosystem exists to manage and trade risk—volatility & variance products, structured products, credit risk, interest rate products, FX & commodities risk, liquidity & funding products, tail risk products, etc.—amounting to trillions of dollars in products. There is over **$18 trillion** in notional net risk exposures outstanding in TradFi, enabling investors to trade and hedge volatility and other risks. In contrast, the crypto equivalent is virtually non-existent today. TRP aims to **unlock this untapped market (estimated at \~$350B+) by proposing a crypto-native solution to harvest risk** without relying on fiat or off-chain assets. Rather than offloading risk to USD (via stablecoins), *TRP embraces crypto’s risks and tokenizes it*. The core idea is simple yet powerful: *if risk is abundant in crypto, why not make it tradable?* By turning risk into a tradable asset, TRP enables users to dial risk up or down according to their risk appetites and fill a critical infrastructure gap, much like how lending protocols added a credit layer in earlier DeFi waves.

## The New Meta

As financial markets mature, they inevitably evolve toward trading risk. In crypto, that means **'RiskFi'** —the ability to *price, tokenize, and trade risk exposures on-chain—*&#x69;s conservatively worth over **$350B**. The Risk Protocol is pioneering this sector through novel risk primitives such as **Risk Tokenization**, **Risk Prediction Markets**, and **Risk Intelligence**. These new risk primitives open alpha opportunities that simply don’t exist anywhere else in crypto. &#x20;

We are initially focused on Risk Tokenization and Risk Intelligence. Following launch, we plan to introduce additional risk products on a regular cadence, as outlined in our roadmap.

## Why Should Traders Care

1. ***TURBOCHARGE RETURNS***: Picking the right token for the market environment will yield significant outperformance relative to simply holding the underlying asset.
2. ***UNIQUE ALPHA***: SMART Tokens unlock alpha streams unavailable in perps or spot.
3. ***NO MARGIN CALLS, NO LIQUIDATIONS***: SMART Tokens are appropriately collateralized from the outset. No constant monitoring required—you can set it and forget it.
4. ***SIMPLICITY***: No Greeks. No spreadsheets. SMART Tokens wrap complex risk exposures into a single, intuitive token so you can act on your market view without having to understand derivatives or the mechanics behind them. Focus on the outcome, and let the complexity run under the hood.
5. ***FRONT-RUN THE FUTURE***: "RiskFi" is crypto’s next frontier—an untapped market of inefficiencies and edge. Get in early and position ahead of the curve.
6. ***HEDGE RISK, TRADE RISK***: Manage drawdowns, leverage upside, or bet on tail events—hedge when you need safety, hunt when you want edge.
7. ***PERPETUAL***: With SMART Tokens, there’s no need to roll over expiring derivative positions. You get automatically rebalanced at zero cost.


# How?

How do we tokenize risk

**SMART Tokens** are the core primitive that enables risk-tokenization. We have launched initially with a specific type of SMART Token called **RiskON** & **RiskOFF**. When you deposit an asset as collateral with The Risk Protocol, that asset is split into two complementary tokens—for example, depositing 1 ETH yields 1 RiskON ETH and 1 RiskOFF ETH. These two tokens together always represent the underlying asset’s value, but each one is programmed with a different risk/return profile. They are two halves of the same whole, but with dramatically different behavior. RiskOFF offers stability and downside protection, while RiskON provides leveraged exposure. This is programmable money taken a step further. Our SMART tokens package sophisticated exposures into single tokens so that you can focus on *outcomes*, not *mechanics*.&#x20;

#### Splitting an Asset Into RiskON & RiskOFF&#x20;

<figure><img src="/files/sVJTnONKp81Ht2QziNxJ" alt=""><figcaption></figcaption></figure>

### Example

Let’s use an example to make this more tangible. Let’s say an investor owns 1 BTC but is uncomfortable with the daily volatility. The investor comes up to TRP, deposits 1 BTC as collateral, and mints 2 new SMART Tokens—RiskON BTC and RiskOFF BTC. RiskON and RiskOFF are designed to have an aggregate value equivalent to the value of the underlying cryptocurrency at all times. The design segregates the risk of owning the underlying cryptocurrency into a *low-risk token* (RiskOFF) and a *levered token* (RiskON). RiskOFF’s returns will generally have less risk in terms of both beta and standard deviation of returns than the underlying cryptocurrency, while RiskON will generally have a beta and standard deviation of returns that exceed those of the underlying cryptocurrency.

How do RiskON and RiskOFF get this profile? By holding synthetic options. RiskOFF is long a down-and-out barrier put that provides a floor, and it is short a call that caps its upside. As a result, it floats within a band and has dramatically lower volatility than the underlying cryptocurrency. Where did it get this exposure from? By contracting with the 2nd SMART token—RiskON. RiskON is the counterparty to all the options that RiskOFF owns. The simple contract between RiskON and RiskOFF is that in return for providing the downside protection to RiskOFF, RiskON gets RiskOFF’s share of the upside beyond the cap. Both initially start out with equal ownership of the underlying collateral and have equal values at the outset. Over time, however, as the underlying BTC moves, their values diverge. If BTC runs up, RiskON will outperform BTC because of the leverage it is getting from RiskOFF, and similarly, in a declining market, RiskOFF will outperform BTC because of the downside protection it is getting from RiskON.

What we have effectively done is that from one asset, we have synthetically extracted 2 different “*risk flavors*” of that asset, designed to appeal to investors/traders with different risk appetites. Investors who want some leverage without margin calls or liquidations will swap out of the RiskOFF token in the secondary market and keep the RiskON. Conversely, if the investor wants risk-reduced exposure to the underlying, they will hold RiskOFF.&#x20;

Further details on our SMART Tokens can be found in subsequent sections of the documentation.


# About

Core Contributors, RiskFI & The Risk Protocol Vision

## Core Contributors

*Risk Protocol Atelier* is the core contributor group building the foundational risk layer of crypto. We are a methodically assembled [team](https://www.riskprotocol.io/team) that blends **deep crypto-native experience** with **decades of institutional finance expertise**. Our contributors bring specialized backgrounds in *DeFi and CeFi protocol design, quantitative trading, risk management, derivatives structuring and valuation, volatility modeling and research, and crypto GTM strategy.*

Our founder, [KG](https://www.linkedin.com/in/karamvirgosal/), spent many years in institutional finance before turning his focus to crypto in 2020. He was drawn by a *striking imbalance*: crypto had pioneered entirely new forms of market infrastructure, yet remained underdeveloped in one of finance’s most essential pillars—risk. The Risk Protocol was **created to close that gap and bring institutional-grade risk engineering to crypto**.

Our [CMO](https://www.linkedin.com/in/swarooppoudel/) previously led community, marketing, business development, and developer relations at a major crypto network, and **grew its user base to more than 55 million** and its active developer ecosystem to *several hundred builders*.

Our Head of Risk served as a senior portfolio manager and head of derivatives at one of the **world’s largest quantitative investment firms**.

Our Head of Research is a leading econometrician who has worked extensively—and co-authored papers—with **Nobel Prize–winning economists** recognized for their breakthroughs in *volatility research*.

Together, we are building the risk ecosystem and infrastructure that the next generation of crypto demands and deserves.

## RiskFi

RiskFi represents a *new category within DeFi* in which risk—volatility, liquidity stress, tail events, stablecoin depeg risk, funding-rate risk, and more—becomes an *explicit, on-chain asset*. Instead of burying risk inside complex instruments, RiskFi *isolates and tokenizes* it, enabling transparent markets where users can directly speculate on, hedge, transfer, or acquire specific risk exposures.

RiskFi fills a structural gap in the crypto financial stack. While trading and payments infrastructure has advanced rapidly (AMMs, perps, intent-based systems, etc.), robust and transparent *risk markets have lagged behind*.&#x20;

> #### *<mark style="color:blue;">"By making risk measurable, composable, and liquid, RiskFi unlocks new forms of trading opportunities, hedging, and risk-aware yield generation. It lays the foundation for a mature crypto financial system—one where risk is traded with the same granularity and transparency as any other digital asset."</mark>*

We estimate that RiskFi represents a conservatively sized **$350B+ market opportunity.**

## The Risk Protocol

The Risk Protocol is pioneering RiskFi through several first-of-their-kind primitives:

* **SMART Tokens:** isolating and packaging specific risk exposures into tradeable SMART tokens.
* **Risk Prediction Markets:** enabling users to trade directional and non-directional risk events with precision.
* **Risk Intelligence:** delivering next-generation risk analytics, indices, and real-time signals for the entire ecosystem.

These primitives open alpha opportunities and risk expressions that simply do not exist elsewhere in crypto.

<figure><img src="/files/0wCqaYxwpJfubUCByzUH" alt=""><figcaption></figcaption></figure>


# Getting Started

If you are new to The Risk Protocol, begin with our [Litepaper](/protocol-papers-and-user-guides/litepaper), which lays out the concepts behind risk-tokenization in simple, intuitive language. Once the ideas click, move on to our [dApp User Guide](https://docs.riskprotocol.io/protocol-papers-and-user-guides/dapp-user-guide) for a step-by-step walk-through of the dApp—connecting your wallet, minting SMART Tokens, swapping, providing liquidity, and redeeming.&#x20;

The TRP Testnet runs on **Arbitrum Sepolia**, so you will need ETH on Arbitrum Sepolia to pay gas fees. Getting it is free and takes two steps. The easiest way to do it is to first [get Sepolia ETH](https://docs.riskprotocol.io/overview/getting-started#get-sepolia-eth) on Ethereum Sepolia from one of the faucets below, then [bridge it to Arbitrum Sepolia](https://docs.riskprotocol.io/overview/getting-started#bridge-to-arbitrum-sepolia) using the official Arbitrum Bridge.

You will also need test funds to simulate underlying cryptocurrencies within the testnet environment. As shown in the dApp User Guide, you can receive test BTC and test ETH by simply clicking on 'Get Testnet Funds' from the wallet dropdown menu (shown below).

<div align="center"><figure><img src="/files/wnkGWclANNUmjmNWa7Uq" alt="" width="375"><figcaption><p>Getting Test Funds</p></figcaption></figure></div>

With this context, you are equipped to navigate the protocol confidently and begin your journey on the risk layer.&#x20;

GOOD LUCK AND BON VOYAGE!

## Get Sepolia ETH

Your journey starts on Ethereum Sepolia, where the faucets are most generous. Below are recommended faucets to get started. Requirements vary—some need a Google account or mainnet ETH balance, while others work with just a wallet address.

#### Google Faucet

Link: <https://cloud.google.com/application/web3/faucet/ethereum/sepolia>

| Amount   | Frequency      | Requirements   |
| -------- | -------------- | -------------- |
| 0.05 ETH | Every 24 hours | Google account |

This is the simplest option for most users. Sign in with your Google account, enter your wallet address, and receive Sepolia ETH within seconds.

#### PoW Faucet

Link: <https://sepolia-faucet.pk910.de>

| Amount         | Frequency | Requirements |
| -------------- | --------- | ------------ |
| 0.05 – 2.5 ETH | Unlimited | None         |

You can mine Sepolia ETH directly in your browser. No login or mainnet balance is required—just enter your wallet address and start mining. The longer you mine, the more you earn (up to 2.5 ETH per session), and the minimum claim is 0.05 ETH. This is the best option for users who need larger amounts for extensive testing.

#### Alchemy Faucet

Link: <https://www.alchemy.com/faucets/ethereum-sepolia>

| Amount  | Frequency      | Requirements                           |
| ------- | -------------- | -------------------------------------- |
| 0.1 ETH | Every 24 hours | Alchemy account + 0.001 ETH on mainnet |

The drip is higher than most, but you must hold a small ETH balance on mainnet. Create a free Alchemy account to access it.

#### QuickNode Faucet

Link: <https://faucet.quicknode.com/ethereum/sepolia>

| Amount         | Frequency      | Requirements                             |
| -------------- | -------------- | ---------------------------------------- |
| 0.05 – 0.1 ETH | Every 12 hours | QuickNode account + 0.001 ETH on mainnet |

The refresh rate is faster than most faucets, and the amount varies based on your account tier and mainnet balance.

#### Chainlink Faucet

Link: <https://faucets.chain.link/sepolia>

| Amount            | Frequency      | Requirements                                            |
| ----------------- | -------------- | ------------------------------------------------------- |
| 0.5 ETH + 25 LINK | Every 24 hours | Wallet connection + at least 1 LINK on mainnet to claim |

This is the most generous faucet. Connect your wallet (MetaMask, WalletConnect, or Coinbase Wallet) and claim. It also provides testnet LINK tokens.

#### Metana Faucet

Link: <https://faucet.metana.io>

| Amount   | Frequency      | Requirements                                |
| -------- | -------------- | ------------------------------------------- |
| 0.06 ETH | Every 24 hours | Captcha + valid email/phone number to claim |

No account or mainnet balance is needed. Complete a simple CAPTCHA and receive Sepolia ETH within minutes. It is a good backup option when other faucets are congested.

{% hint style="info" %}
New to crypto? Start with the Google Faucet or PoW Faucet—they have the lowest barrier to entry.
{% endhint %}

## Bridge to Arbitrum Sepolia

Once you hold Sepolia ETH, the official Arbitrum Bridge moves it from Ethereum Sepolia (Layer 1) onto Arbitrum Sepolia, where the TRP Testnet lives. You keep the same wallet address on both sides.\
\
**Link**: [bridge.arbitrum.io](https://bridge.arbitrum.io)

<figure><img src="/files/6jXADmvGB0EPFg8g9dvu" alt="" width="563"><figcaption></figcaption></figure>

1. Connect your wallet.
2. Confirm the source is Ethereum Sepolia and the destination is Arbitrum Sepolia, select **ETH**, and enter an amount.
3. Press **Move funds** and confirm the transaction in your wallet.
4. Funds arrive on Arbitrum Sepolia in roughly **10 minutes**. Once they land, you are ready to follow the [dApp User Guide](https://docs.riskprotocol.io/protocol-papers-and-user-guides/dapp-user-guide).

### Backup: Arbitrum Sepolia Faucets

A few faucets pay out directly on Arbitrum Sepolia, with no bridging involved. Their drips are smaller, and most require a mainnet balance, so treat them as a backup if the Layer 1 faucets run dry.

**Chainlink Faucet (Arbitrum Sepolia)**

Link: <https://faucets.chain.link/arbitrum-sepolia>

| Amount  | Frequency      | Requirements                             |
| ------- | -------------- | ---------------------------------------- |
| 0.1 ETH | Every 24 hours | Wallet connection + 0.001 ETH on mainnet |

**Alchemy Faucet (Arbitrum Sepolia)**

Link: <https://www.alchemy.com/faucets/arbitrum-sepolia>

| Amount | Frequency      | Requirements                           |
| ------ | -------------- | -------------------------------------- |
| Varies | Every 24 hours | Alchemy account + 0.001 ETH on mainnet |

**QuickNode Faucet (Arbitrum Sepolia)**

Link: <https://faucet.quicknode.com/arbitrum/sepolia>

| Amount | Frequency      | Requirements                             |
| ------ | -------------- | ---------------------------------------- |
| Varies | Every 12 hours | QuickNode account + 0.001 ETH on mainnet |

## Chains & Contracts

The Risk Protocol currently supports Arbitrum Sepolia. Below are the smart contract addresses for each deployment, starting with the chain you will actually use.

### BTC on Arbitrum Sepolia

The rebalance period is 30 days.

* **riskBTC**
  * Address: [0x5B4f5ed0e961e518845FA960aBE677bb5C677Bf3](https://sepolia.arbiscan.io/address/0x5B4f5ed0e961e518845FA960aBE677bb5C677Bf3)
* **tokenFactory**
  * Address: [0xB7CC8A123432851cbA4D6Aa2B958B0Bb6Da5a670](https://sepolia.arbiscan.io/address/0xB7CC8A123432851cbA4D6Aa2B958B0Bb6Da5a670)
* **riskON**
  * Address: [0xB7C718A75b6f758c117Cf652D8888b7Cc4a1454a](https://sepolia.arbiscan.io/address/0xB7C718A75b6f758c117Cf652D8888b7Cc4a1454a)
* **riskOFF**
  * Address: [0xb7CC3A7df75fA6Cf93e43fe26De0C82D698a1847](https://sepolia.arbiscan.io/address/0xb7CC3A7df75fA6Cf93e43fe26De0C82D698a1847)
* **Orchestrator**
  * Address: [0xB7C5C4215FbcA7AE6cA99E3345cd196c482deE5f](https://sepolia.arbiscan.io/address/0xB7C5C4215FbcA7AE6cA99E3345cd196c482deE5f)
* **AtomicTx**
  * Address: [0xB7cEc365c1B346849422433030e730ce1092d264](https://sepolia.arbiscan.io/address/0xB7cEc365c1B346849422433030e730ce1092d264)
* **wrapped riskON**
  * Address: [0xB7C7E2E541d8b91060a2E7D819B93751BFA33f79](https://sepolia.arbiscan.io/address/0xB7C7E2E541d8b91060a2E7D819B93751BFA33f79)
* **wrapped riskOFF**
  * Address: [0xB7c03521c75B359aEaDA37364563CEEfA2ed3D2C](https://sepolia.arbiscan.io/address/0xB7c03521c75B359aEaDA37364563CEEfA2ed3D2C)

### ETH on Arbitrum Sepolia

The rebalance period is 30 days.

* **riskETH**
  * Address: [0x17d908c2Fb7a29e53191E948Fc26516acF91b091](https://sepolia.arbiscan.io/address/0x17d908c2Fb7a29e53191E948Fc26516acF91b091)
* **tokenFactory**
  * Address: [0xE7114A0FB0aC2C528590f07f7b8426269e6525B3](https://sepolia.arbiscan.io/address/0xE7114A0FB0aC2C528590f07f7b8426269e6525B3)
* **riskON**
  * Address: [0xE711372E52Dbc8E9ED49376546dF38068204ef75](https://sepolia.arbiscan.io/address/0xE711372E52Dbc8E9ED49376546dF38068204ef75)
* **riskOFF**
  * Address: [0xe711527510e9696D679Df0b6A46731944308aCB8](https://sepolia.arbiscan.io/address/0xe711527510e9696D679Df0b6A46731944308aCB8)
* **Orchestrator**
  * Address: [0xe711120E2FB49847946cb611336b86F369c875b1](https://sepolia.arbiscan.io/address/0xe711120E2FB49847946cb611336b86F369c875b1)
* **AtomicTx**
  * Address: [0xE711f68BbA5D11C419f62fbC9A741406D42913AB](https://sepolia.arbiscan.io/address/0xE711f68BbA5D11C419f62fbC9A741406D42913AB)
* **wrapped riskON**
  * Address: [0xe711C292AE7418AD1810178aeB8634804D3ea8fd](https://sepolia.arbiscan.io/address/0xe711C292AE7418AD1810178aeB8634804D3ea8fd)
* **wrapped riskOFF**
  * Address: [0xE711E7148A8BE465B1e1175ED484aF7d6F777172](https://sepolia.arbiscan.io/address/0xE711E7148A8BE465B1e1175ED484aF7d6F777172)

***

### BTC on GIWA Sepolia

The rebalance period is 30 days.

* **riskBTC**
  * Address: [0x1DBf0a0b676580C8b22fd233aBf7ADAb2b3830a7](https://sepolia-explorer.giwa.io/address/0x1DBf0a0b676580C8b22fd233aBf7ADAb2b3830a7)
* **tokenFactory**
  * Address: [0xB7CC8A123432851cbA4D6Aa2B958B0Bb6Da5a670](https://sepolia-explorer.giwa.io/address/0xB7CC8A123432851cbA4D6Aa2B958B0Bb6Da5a670)
* **riskON**
  * Address: [0xB7C718A75b6f758c117Cf652D8888b7Cc4a1454a](https://sepolia-explorer.giwa.io/address/0xB7C718A75b6f758c117Cf652D8888b7Cc4a1454a)
* **riskOFF**
  * Address: [0xb7CC3A7df75fA6Cf93e43fe26De0C82D698a1847](https://sepolia-explorer.giwa.io/address/0xb7CC3A7df75fA6Cf93e43fe26De0C82D698a1847)
* **Orchestrator**
  * Address: [0xB7C5C4215FbcA7AE6cA99E3345cd196c482deE5f](https://sepolia-explorer.giwa.io/address/0xB7C5C4215FbcA7AE6cA99E3345cd196c482deE5f)
* **AtomicTx**
  * Address: [0xB7cEc365c1B346849422433030e730ce1092d264](https://sepolia-explorer.giwa.io/address/0xB7cEc365c1B346849422433030e730ce1092d264)
* **wrapped riskON**
  * Address: [0xB7C7E2E541d8b91060a2E7D819B93751BFA33f79](https://sepolia-explorer.giwa.io/address/0xB7C7E2E541d8b91060a2E7D819B93751BFA33f79)
* **wrapped riskOFF**
  * Address: [0xB7c03521c75B359aEaDA37364563CEEfA2ed3D2C](https://sepolia-explorer.giwa.io/address/0xB7c03521c75B359aEaDA37364563CEEfA2ed3D2C)

### ETH on GIWA Sepolia

The rebalance period is 30 days.

* **riskETH**
  * Address: [0x8af61F025562cE808c3066dC990450Ea546246fA](https://sepolia-explorer.giwa.io/address/0x8af61F025562cE808c3066dC990450Ea546246fA)
* **tokenFactory**
  * Address: [0xE7114A0FB0aC2C528590f07f7b8426269e6525B3](https://sepolia-explorer.giwa.io/address/0xE7114A0FB0aC2C528590f07f7b8426269e6525B3)
* **riskON**
  * Address: [0xE711372E52Dbc8E9ED49376546dF38068204ef75](https://sepolia-explorer.giwa.io/address/0xE711372E52Dbc8E9ED49376546dF38068204ef75)
* **riskOFF**
  * Address: [0xe711527510e9696D679Df0b6A46731944308aCB8](https://sepolia-explorer.giwa.io/address/0xe711527510e9696D679Df0b6A46731944308aCB8)
* **Orchestrator**
  * Address: [0xe711120E2FB49847946cb611336b86F369c875b1](https://sepolia-explorer.giwa.io/address/0xe711120E2FB49847946cb611336b86F369c875b1)
* **AtomicTx**
  * Address: [0xE711f68BbA5D11C419f62fbC9A741406D42913AB](https://sepolia-explorer.giwa.io/address/0xE711f68BbA5D11C419f62fbC9A741406D42913AB)
* **wrapped riskON**
  * Address: [0xe711C292AE7418AD1810178aeB8634804D3ea8fd](https://sepolia-explorer.giwa.io/address/0xe711C292AE7418AD1810178aeB8634804D3ea8fd)
* **wrapped riskOFF**
  * Address: [0xE711E7148A8BE465B1e1175ED484aF7d6F777172](https://sepolia-explorer.giwa.io/address/0xE711E7148A8BE465B1e1175ED484aF7d6F777172)

***

### BTC on Sepolia

The rebalance period is 30 days.

* **riskBTC**
  * Address: [0x8af61F025562cE808c3066dC990450Ea546246fA](https://sepolia.etherscan.io/address/0x8af61F025562cE808c3066dC990450Ea546246fA)
* **tokenFactory**
  * Address: [0xb7c05a53452e5737b94c3aF1b1c11aA4Af8a720f](https://sepolia.etherscan.io/address/0xb7c05a53452e5737b94c3aF1b1c11aA4Af8a720f)
* **riskON**
  * Address: [0xB7C23FEbf4da54eDFC1176742fF74404625443e5](https://sepolia.etherscan.io/address/0xB7C23FEbf4da54eDFC1176742fF74404625443e5)
* **riskOFF**
  * Address: [0xB7cd729e60ccB8D1C752CD825C7925FBC5a992C8](https://sepolia.etherscan.io/address/0xB7cd729e60ccB8D1C752CD825C7925FBC5a992C8)
* **Orchestrator**
  * Address: [0xB7C2f12B6fcee437390E5382d0b0f3dC6AF2E820](https://sepolia.etherscan.io/address/0xB7C2f12B6fcee437390E5382d0b0f3dC6AF2E820)
* **AtomicTx**
  * Address: [0xB7c2F6CE8c85916Ea5A58acBfB6775C1dea97bAb](https://sepolia.etherscan.io/address/0xB7c2F6CE8c85916Ea5A58acBfB6775C1dea97bAb)
* **wrapped riskON**
  * Address: [0xB7c3839205E665f5aa399d0729da70Dfb3b16384](https://sepolia.etherscan.io/address/0xB7c3839205E665f5aa399d0729da70Dfb3b16384)
* **wrapped riskOFF**
  * Address: [0xb7Cc7bD3c80f8De9F9d571C7D9805c9DED88BeEB](https://sepolia.etherscan.io/address/0xb7Cc7bD3c80f8De9F9d571C7D9805c9DED88BeEB)

### ETH on Sepolia

The rebalance period is 30 days.

* **riskETH**
  * Address: [0x7D51fD334CFc1A0C258C4422b011EbbB9093B11b](https://sepolia.etherscan.io/address/0x7D51fD334CFc1A0C258C4422b011EbbB9093B11b)
* **tokenFactory**
  * Address: [0xe711Bf108EBb4A1690165ca72DB5E2a6151CEe2D](https://sepolia.etherscan.io/address/0xe711Bf108EBb4A1690165ca72DB5E2a6151CEe2D)
* **riskON**
  * Address: [0xE71174De21406E17d5Be051686b090EfE90BB602](https://sepolia.etherscan.io/address/0xE71174De21406E17d5Be051686b090EfE90BB602)
* **riskOFF**
  * Address: [0xe711b751805BA06F3c63dDA0686C0e74c1A218A7](https://sepolia.etherscan.io/address/0xe711b751805BA06F3c63dDA0686C0e74c1A218A7)
* **Orchestrator**
  * Address: [0xe711d780FA97328a11AF495b2Bfd414Ad9F2d0D1](https://sepolia.etherscan.io/address/0xe711d780FA97328a11AF495b2Bfd414Ad9F2d0D1)
* **AtomicTx**
  * Address: [0xe7110Dc48e2Ac9f9d920830660A26725F310D863](https://sepolia.etherscan.io/address/0xe7110Dc48e2Ac9f9d920830660A26725F310D863)
* **wrapped riskON**
  * Address: [0xE71148adAd487b6560aE795bcA47191064D35B9a](https://sepolia.etherscan.io/address/0xE71148adAd487b6560aE795bcA47191064D35B9a)
* **wrapped riskOFF**
  * Address: [0xE71134F03716Dc7479831C5083377dedAF39B133](https://sepolia.etherscan.io/address/0xE71134F03716Dc7479831C5083377dedAF39B133)


# Litepaper

> #### <mark style="color:blue;">"</mark>*<mark style="color:blue;">Risk is one resource crypto has in abundance—yet it remains largely unharvested. The Risk Protocol lets users turn that risk to their advantage, transforming it from a problem into an asset. The Risk Protocol converts crypto’s greatest challenge into a new frontier of opportunity."</mark>*

## 1.  Building the Missing Risk Layer of Crypto

The Risk Protocol (“TRP”) is building foundational decentralized crypto risk infrastructure and pioneering “**RiskFi**”—a novel vertical within DeFi that turns risk itself into a programmable, tradable, financial primitive.

Investing and trading in crypto entail various kinds of risks—volatility, liquidity, smart contract, regulatory, counterparty, etc. Our core purpose is to drive the evolution of decentralized finance by enabling traders to *price, tokenize, hedge*, and *trade* these various risk exposures. We achieve this by providing next-generation risk products that are designed not only to *harness risk* but also to *exploit the unique alpha opportunities* unlocked by these new primitives. These risk products are useful for both short-term traders and long-term investors, serving those who want to speculate on the risk and those who want to hedge it.

In TradFi, a robust risk ecosystem exists to manage and trade risk, including volatility and variance products, structured products, credit risk solutions, interest rate products, FX & commodities risk, tail risk products, etc. There is over **$18T** in notional net risk exposures outstanding in TradFi, enabling investors to trade and hedge volatility and other risks. In contrast, the crypto equivalent is *virtually non-existent* today. TRP aims to unlock this untapped market (estimated at approximately **$350 billion+**) by proposing a *crypto-native solution to harvest risk, without relying on fiat or off-chain assets*. Rather than offloading risk to USD (via stablecoins), TRP *embraces crypto’s risks and tokenizes it*. The core idea is simple yet powerful: *if risk is abundant in crypto, why not make it tradable?* By turning risk into a tradable asset, TRP enables users to adjust their risk exposure according to their risk appetite, filling a critical infrastructure gap, much like when lending protocols added a credit layer in earlier DeFi waves.

### The Volatility Dilemma

Cryptocurrency markets are famously volatile. While volatility can offer outsized gains, it also undermines the use of crypto as a stable store of value, collateral, or medium of exchange. Prices swing wildly, making it difficult for investors and everyday users to hold crypto confidently without fear of sharp drawdowns. Lacking a native risk-management layer, many investors flee to stablecoins (mostly backed by fiat) to escape volatility, ironically tethering themselves to fiat currencies. This reliance on USD-pegged assets runs counter to the ethos of decentralization and financial sovereignty of DeFi. Crypto, at least in its current form, essentially has a volatility risk problem—enormous inherent volatility, but no dedicated, on-chain tools to see, trade, or hedge that volatility itself. *This, then, is the first crypto risk we address–volatility.*

## 2.  Risk Tokenization&#x20;

**With Risk Tokenization, our initial product, we provide a crypto-native way to hedge or speculate on crypto** [**volatility**](#user-content-fn-1)[^1]. We take the sophisticated machinery of derivatives and wrap it into simple tokens that anyone can use. For those familiar with DeFi yield protocols, you can think of TRP as *doing for risk what Pendle does for yield—splitting an asset in a way that isolates a specific financial element (here, volatility risk) and making it tradable*.&#x20;

To tokenize volatility, TRP uses a novel mechanism called SMART—short for “*Split Mechanism for Asset Risk-Tokenisation*.” This mechanism enables any crypto asset to be split into two tokens with distinct risk profiles. Think of it like a *risk dial*: turn it one way to dampen volatility, or the other way to amplify it. TRP packages this into user-friendly products. With a couple of clicks, an investor can reduce their exposure to wild price swings without selling their crypto, or conversely, obtain a leveraged position without risking liquidation[^2]. There are no complex options trades to manage, no margin calls, and no surprise liquidations—everything is fully collateralized and executed in an abstracted, non-custodial manner by smart contracts.

**Risk Tokenization empowers users to benefit from volatility: to tame it when they need safety, or exploit it when they seek alpha**. By transforming volatility into a tradable asset, TRP is opening the door to a new world of trading opportunities and risk management tools previously inaccessible to everyday crypto participants.

### 2. a)  Splitting an Asset into RiskON & RiskOFF

[SMART Tokens](https://app.riskprotocol.io/) are the core primitive that enables risk tokenization. We launch initially with a specific type of SMART Token called **RiskON/RiskOFF**. When you deposit an asset as collateral with The Risk Protocol, that asset is split into two complementary tokens—for example, by depositing 1 BTC, you mint 1 RiskON BTC and 1 RiskOFF BTC. The aggregate value of these two SMART Tokens always represents the underlying asset’s value (in this example, the underlying 1 BTC). Still, each one is programmed with a different risk/return profile. They are two halves of the same whole, but with dramatically different behavior. *RiskOFF offers stability and downside protection, while RiskON provides leveraged exposure.*

**RiskOFF is the low-risk half**. It has a claim on 50% of the underlying (the 1 BTC) and is designed to track the underlying asset’s price, but within a limited range[^3]. It does that by having a *built-in floor on losses and a cap on gains*. For example, RiskOFF BTC is defined to never drop more than -5% (the “floor”) in a given period and to forgo any upside beyond \~+8% (the “cap”). It achieves this by holding a long down-and-out put option (which provides downside protection if the asset price crashes past the floor) and by simultaneously being short a call option (which gives up any upside beyond the cap). In essence, RiskOFF sacrifices extreme upside in exchange for a safety net on the downside. The result is a token that is significantly less volatile than its underlying asset.

**RiskON is the high-risk half**. It’s the mirror image of RiskOFF—effectively a leveraged exposure to the underlying asset. RiskON takes on the volatility that RiskOFF sheds. The simple contract between RiskON & RiskOFF is that by agreeing to bear the downside beyond RiskOFF’s floor, RiskON earns the right to all upside beyond RiskOFF’s cap. This makes RiskON a super-charged version of the underlying asset. If the asset’s price rallies strongly, RiskON will outperform the asset (since it gets an extra slice of upside). Conversely, if the price plunges, RiskON will underperform and absorb more losses, even approaching zero in extreme cases—that is the trade-off for its leveraged upside.

Within the cap and the floor, both RiskON & RiskOFF behave the same as the underlying asset (because each has a 50% claim on the underlying and all the options are out of the money).

At the inception of any epoch, both RiskON and RiskOFF start with equal value (each has a 50% share of the underlying asset plus options that are initially set up as a [costless collar](https://www.investopedia.com/terms/z/zerocostcollar.asp)). They are designed so that, initially, a user is economically agnostic about which token they hold—neither token has an advantage. From that point on, however, their values diverge as the price of the underlying asset changes.

How can two tokens cover each other’s risk like this? The magic lies in *synthetic options* and smart contract design. TRP doesn’t purchase options from an exchange or work with any OTC desk—no external liquidity is needed to price the options. Instead, the two tokens are counterparties to each other. It’s an internal risk swap: RiskOFF’s contract with RiskON guarantees RiskOFF a certain payoff (the put option’s protection) and, in exchange, obligates RiskOFF to give up some payoff to RiskON (the call option’s upside share). Because these derivatives are synthetic and perfectly offset within the pair, the system remains *self-contained* and *delta-neutral*. Depositing 1 BTC as collateral allows a user to mint 1 RiskON + 1 RiskOFF. A user can redeem the 1 BTC at any point by burning 1 RiskON and 1 RiskOFF. This 1:1 equivalency ensures that *TRP itself takes no directional exposure and never risks its solvency*.&#x20;

Key features of SMART Tokens include:

* **Intuitive Risk Profiles:** Each SMART Token offers a pre-packaged risk/return payoff (e.g., “capped upside, buffered downside”) that investors can choose based on their risk appetite. This spares users from needing to understand or manage complex options themselves—it’s fully abstracted away. Buying a RiskOFF token is as simple as purchasing any ERC-20 token, yet it implicitly means you hold a protected, lower-volatility exposure to the underlying. SMART Tokens effectively enable users to *focus on outcomes, rather than mechanics*.
* **Price Discovery & Liquidity:** It has been our observation that, while most DeFi projects tout lego-like composability, this is not the case in practice. The reason is quite simple. True composability in DeFi requires price discovery and liquidity for such tokens to be practically usable elsewhere in DeFi. Our design incorporates these two elements: a) we publish a second-by-second Net Token Value for all our SMART Tokens, and b) we have created a liquidity marketplace for them.
* **Fully Collateralized, No Liquidations:** Every SMART Token pair is 100% backed by collateral (the initial deposit asset). There are no borrowed funds, so margin calls and liquidation events never occur[^2]. Even in extreme market moves, RiskOFF’s put is always made whole, while the RiskON token can go to near-zero, but never negative.
* **On-Demand Creation and Redemption:** Users can mint or burn SMART Tokens at any time through TRP’s smart contracts. To create a pair, you deposit one unit of a supported asset and mint a SMART Token [pair ](#user-content-fn-4)[^4]\(for instance, deposit 0.25 ETH, and mint 0.25 RiskOFF ETH + 0.25 RiskON ETH). To redeem the underlying asset at any point, you burn one of each token in the SMART Token pair and receive the underlying asset. This creation/redemption mechanism ensures that the combined market value of each SMART Token pair remains tethered to the underlying asset. If RiskON + RiskOFF ever trade at significantly higher or lower levels than the underlying asset, arbitrageurs can step in, minting new pairs or burning them to capture the difference, thus pulling prices back in line.
* **Highly Configurable Risk Profiles:** The SMART framework is flexible—by adjusting parameters such as the underlying asset, option strike levels, option types, or option maturity, TRP can create a wide range of risk/reward payoffs. One can imagine other SMART Token pairs, for instance, tokens that let you go long volatility (profiting from large swings regardless of direction) or short volatility (earning yield if prices stay calm), or tokens that protect specifically against tail-risk events. TRP’s design allows for endless risk-reward profiles by varying a few key parameters. All such tokens share the same DNA—splitting an underlying asset using synthetic options—but can be tailored to different use cases. Over time, the TRP’s SMART Token ecosystem will expand to many more programmable risk profiles beyond the initial offerings.
* **Epochs and Rebalancing:** Each SMART Token operates in periods called epochs (a week, a month, or a quarter, depending on the type of SMART Token). During an epoch, the payoff structure (for example, a -5% floor and +\~8% cap for RiskOFF) is fixed. At the end of the epoch, the system automatically rebalances: essentially, a new RiskON/RiskOFF pair is established for the next period, starting again from equal values. This allows the tokens to be *perpetual—they don’t expire or settle in cash, but roll over continuously*. Rebalancing ensures that RiskOFF’s protection and RiskON’s leverage are reset appropriately for each period[^5].&#x20;

By combining these elements, SMART Tokens introduce a powerful concept: *volatility as a tradable asset*. Investors with different risk appetites can now hold different “*risk flavors*” of an underlying asset. A conservative holder of ETH (or other underlying asset), such as a DAO Treasury, can convert their ETH into RiskOFF ETH to significantly reduce day-to-day volatility (while allowing upside participation up to the cap). RiskOFF is *not a stablecoin, but most definitely a “stabler” coin*—volatility can, in fact, be reduced to the levels of the broader equity markets. Meanwhile, an aggressive trader who is comfortable with higher volatility can either buy the RiskON ETH tokens that the conservative investor sheds or mint their own to get a leveraged play on ETH. What used to require complex option strategies or margin management is now as easy as swapping tokens, sophisticated under the hood, but simple on the surface.

### 2. b)  Payoff Scenarios

To make the mechanics of SMART Tokens concrete, we illustrate three simple scenarios for a Bitcoin holder who splits 1 BTC into RiskOFF and RiskON at the start of an epoch[^6].&#x20;

At inception, let’s assume that BTC is trading at $100,000. RiskON & RiskOFF are minted, each holding a 50% claim on the underlying BTC, plus their offsetting options position. So, at the outset, both RiskOn & RiskOFF = $50,000. Note that the SMART Tokens are designed such that RiskON + RiskOFF = Underlying BTC.

Let’s further assume that:

* On the downside, RiskOFF is protected beyond a 5% drawdown: it is designed (using synthetic options) not to lose more than 5% of its initial value in that epoch. Any losses beyond -5% shall be absorbed by RiskON.&#x20;
* On the upside, RiskOFF participates fully up to a \~+8% rally in BTC. Beyond that level, RiskOFF is capped, and all additional upside accrues to RiskON.

<figure><img src="/files/HQ7ESS5IOfuNNmQrWSf7" alt=""><figcaption></figcaption></figure>

In **Scenario 1 (BTC +30%)**, BTC rallies to $130,000. Once BTC is up more than +8%, RiskOFF is capped at $54,000 (+8%), and all further upside flows to RiskON. RiskON finishes at $76,000 (+52%). The pair again totals $130,000; however, the upside is skewed heavily towards RiskON.

In **Scenario 2 (BTC +12%)**, the move remains within the −5%/+8% band. Since the options are out of the money, both tokens essentially track BTC one-for-one: RiskOFF and RiskON each end at $52,500, a +5% return, and the combined position is equivalent to holding BTC at $105,000.

In **Scenario 3 (BTC −30%)**, BTC falls from $100,000 to $70,000. RiskOFF's loss is limited to −5%, so it finishes at $47,500 instead of following BTC all the way down. RiskON absorbs the remaining loss, ending at $22,500 ($70,000 − $47,500), a −55% return relative to its initial $50,000.

The above scenarios illustrate the payoff (over a range of returns) at the end of an epoch with embedded options settling at intrinsic value. However, the same logic would apply intra-period in determining the value of RiskON/RiskOFF at any point in time, and our risk marketplace ensures that anyone looking to lock in a payoff before the end of the epoch can do so.

Taken together, these scenarios show the intuition behind these SMART Tokens. Within the strikes, in range-bound markets, the returns of both tokens in the pair track the underlying. In down markets, RiskOFF cushions losses beyond the floor, while RiskON bears the extra downside. In bull markets, RiskOFF’s returns are capped, and RiskON captures all additional upside, creating a levered version of the underlying (*RiskON is 2X levered outside the option strikes*).

### 2. c)  The Risk Marketplace: Liquidity for SMART Tokens

Creating novel risk-based tokens is only half the equation—the other half is ensuring there’s a liquid market for them. The Risk Protocol addresses this through its integrated [Risk Marketplace](https://app.riskprotocol.io/swap), a decentralized exchange specifically for trading SMART Tokens. As soon as a user mints RiskON and RiskOFF, they have the freedom to hold or trade either token[^7]. For instance, if an investor only wants the low-risk portion, they can sell their RiskON and keep just the RiskOFF. Conversely, if someone wants extra risk, they might swap into more RiskON tokens. The Risk Marketplace is where these swaps occur—it’s where risk-takers and the risk-averse meet to exchange exposure.

The Risk Marketplace is implemented using an AMM mechanism to facilitate continuous liquidity. We have built our marketplace with custom pool configurations optimized for the unique nature of SMART Tokens. Thanks to the creation/redemption mechanism, arbitrage keeps aggregate prices aligned: if RiskOFF + RiskON is overpriced relative to the underlying (or vice versa), arbitrageurs can create or burn pairs to profit until the imbalance corrects. This design is similar to how an ETF works in TradFi, where an arbitrage mechanism ties the fund price to its underlying NAV.

The marketplace also allows users to become LPs for SMART Token pools. LPs earn trading fees whenever users swap SMART Tokens and may earn additional incentives (TRP plans to reward early liquidity). One unique feature of our LP pools is that *LP fees adjust dynamically based on the volatility of the underlying assets*. As volatility increases, LP fees dynamically rise to offset a higher risk of impermanent loss. As volatility subsides, LP fees revert to a base level.

The user experience of the Risk Marketplace is designed to be straightforward and intuitive. Users can navigate to the 'Swap' section and trade, say, RiskOFF ETH for ETH or for RiskON ETH, just as they would trade any token pair on a DEX. Under the hood, they are tapping into liquidity pools customized for these tokens. The result is an intuitive, one-stop platform: users can mint SMART tokens, swap between risk profiles, and redeem back to the underlying asset all in a few clicks.

### 2. d)  The Risk Engine

TRP has developed a *sophisticated proprietary risk engine* to aid in price discovery. We publish a real-time Net Token Value (“NTV”) for all SMART Tokens, each second. The NTV is akin to a continuously updating “indicative value” based on the price of the underlying asset and the valuation of the embedded options. TRP’s risk engine uses live second-by-second volatility forecasts to calculate what each RiskON or RiskOFF token should be worth at that second, given the state of the market. Traders and liquidity providers can use NTVs as guideposts, and arbitrage bots can use them to determine when a token is trading at a premium or discount. By *facilitating transparent price discovery*, TRP ensures the marketplace remains efficient and the tokens trade at or near their intrinsic value. We have also developed several open source arbitrage bots designed to anchor SMART Token market prices to intrinsic value. &#x20;

The rebalancing at the beginning and end of each epoch is driven by pricing data generated by the risk engine and communicated to the underlying smart contracts via oracles.

### 2. e) Use Cases and Benefits of SMART Tokens

SMART Tokens and the Risk Marketplace combine to unlock a variety of use cases, catering to both risk-averse participants and risk-seeking traders. Here are a few examples of how TRP’s products can be used in practice:

* **Hedge Volatility without Leaving Crypto**: Perhaps the most immediate use case is for investors who believe in crypto’s long-term potential but can’t stomach the short-term volatility. Instead of selling their holdings for stablecoins, they can convert their assets into RiskOFF tokens. For example, an ETH holder worried about market turbulence could swap into RiskOFF ETH. If ETH’s price drops significantly, the RiskOFF token will drop much less, preserving capital. If ETH rises, RiskOFF ETH will also rise up to its cap—still capturing moderate upside. If users see sustained upside momentum, they can seamlessly swap into RiskON. This strategy provides a crypto-native form of downside protection. Unlike with a stablecoin, the holder remains invested in ETH (and can benefit if ETH recovers) while having a cushion against extreme moves. This can be especially valuable for long-term holders during bear markets or for miners, stakers, and treasuries who accumulate crypto but want to reduce drawdown risk. DeFi treasuries and DAOs that currently park funds in stablecoins (exiting crypto exposure to preserve runway) could instead hold RiskOFF. This way, a project treasury could hedge downside risk while still benefiting from upside if the token performs well. Unlike stablecoins, which eliminate upside entirely, RiskOFF provides a middle ground: risk reduction without full exit and continuing to capture modest upside.
* **“Stabler” Collateral for DeFi**: RiskOFF tokens could become a better form of collateral for lending protocols, DEXs, and stablecoin issuers, as these protocols often struggle with the high volatility of crypto collateral, which can trigger liquidations or require significant over-collateralization. RiskOFF, being significantly less volatile than BTC and ETH, is inherently a superior collateral asset. For instance, RiskOFF BTC has historically shown long-term volatility equivalent to that of traditional equity markets. Logically, a lending protocol should allow higher LTV ratios for RiskOFF BTC than for BTC. If DeFi money markets, DEXs, or stablecoin issuers integrate RiskOFF tokens as accepted collateral, users could get more against their holdings with less risk of liquidation.
* **Leverage without Margin Calls or Liquidation**: On the flip side, traders who want to amplify their exposure can use RiskON tokens as a safer form of leverage. Buying a RiskON-BTC token, for instance, gives you levered exposure to Bitcoin’s moves—you gain extra on the upside in exchange for taking on extra risk on the downside. Crucially, this leverage comes without any risk of liquidation. In a traditional margin trade or using leveraged tokens, a sudden dip might liquidate your position. With RiskON, even if the market swings against you, the token simply loses value, but you are never forced out—you can hold it and possibly recover if the market rebounds. This makes RiskON tokens an attractive tool for expressing bullish views or short-term trades where the user is comfortable with high volatility but doesn’t want the administrative headache or tail risk of margin loans.
* **“Risk as Alpha”**: TRP's tokens enable a new kind of active strategy: dynamically shifting between RiskON and RiskOFF in response to market conditions. In strong bull phases, you rotate into RiskON to concentrate upside; in stressed or sideways phases, you rotate into RiskOFF to cushion drawdowns and de-risk. Our historical backtests as of April 1, 2026, illustrate the theoretical ceiling of this approach. For BTC, a "best possible" dynamic SMART Token path would have flipped a \~28% drawdown over the last 1 year into a \~15% gain (\~1.6× spot), turned a \~132% gain over 3 years into \~1,921% (\~8.7× spot), and amplified a modest \~13% gain over 5 years into \~17,222% (\~153× spot). For ETH, the same exercise turns \~20% into \~309% over 1 year (\~3.4× spot), \~14% into \~2,121% over 3 years (\~19.5× spot), and flips a \~19% drawdown over 5 years into \~38,440% (\~479× spot). Now, of course, no one can time the market perfectly in practice, but these "best path" figures show how powerful risk-mode switching between RiskON and RiskOFF can be compared with passive buy-and-hold. For active traders, SMART Tokens effectively open up a new source of alpha, using fully collateralized instruments rather than leveraged perps or margin loans.

#### Dynamically Shifting Between RiskON BTC & RiskOFF BTC

<figure><img src="/files/Y7cA8Okz9GmBpPEGf1ff" alt=""><figcaption></figcaption></figure>

#### Dynamically Shifting Between RiskOn ETH & RiskOFF ETH

<figure><img src="/files/wacdZY8kbUPXGOSTMwcy" alt=""><figcaption></figcaption></figure>

In summary, SMART Tokens provide DeFi a toolkit to trade risk at the native level, rather than resorting to off-chain derivatives or blunt instruments like selling to USD.

## 3.  Beyond Volatility to a Full-Stack Risk Layer

The initial launch of The Risk Protocol focuses on RiskON/RiskOFF SMART tokens for blue-chip cryptocurrencies, such as BTC and ETH. However, our vision is broader—our objective is to build the missing risk layer of crypto, encompassing multiple products and services that collectively address a spectrum of risks in the crypto ecosystem. Here’s a look at what’s on the horizon:

* **Expansion of SMART Token Strategies**: TRP has already developed several additional SMART token designs with varying risk-return profiles. In the coming months, users can expect a pipeline of new SMART Tokens to roll out, each exploiting volatility in a unique way. For example, we plan to introduce tokens that let you explicitly go long or short volatility, yield-generating tokens, or tokens that give you 10X Bull or -10X Bear exposure without any margin calls or liquidations. The programmability of SMART tokens means that we can craft bespoke risk products for various use cases—whether it’s hedging against minor fluctuations (range-bound tokens) or targeting tail events (catastrophe tokens). Over time, our SMART Token suite will expand beyond BTC and ETH to include select other top-20 coins and new types of SMART Tokens.
* **Risk Prediction Markets**: Another major element of the roadmap is the introduction of risk prediction markets. These are markets where users can bet on the outcome of specific risk-related events, bringing the power of collective intelligence to risk pricing. Imagine being able to trade on questions like: “Will Ether’s 30-day volatility exceed X% by year-end?” or “Will Binance’s BTC/USDT 1% depth fall below $X by Date?” TRP’s prediction markets will tokenize these probabilities and extend the reach of TRP’s RiskFi product from continuous financial exposure (i.e., the SMART tokens) to discrete, event-based bets. It effectively creates a market for forecasting risk in the crypto space. By bringing this on-chain, TRP will enable transparent odds on various risks and, in theory, produce informative signals (risk odds) that external observers can use as a barometer of sentiment. Combined with SMART Tokens, this will make TRP’s platform a comprehensive venue for trading both continuous risk and binary risk events.
* **Risk Intelligence**: Alongside tradable products, we publish a suite of [Risk Dashboards](https://www.riskprotocol.io/risk-dashboard) that decompose market behavior into actionable risk signals, giving traders a real-time view of how risk is building, shifting, and being priced. The dashboards cover a universe of leading cryptocurrencies and surface metrics such as historical and forecast volatility, upside versus downside risk, sector-level risk concentration, and other risk-regime indicators. Each view is designed to answer a concrete question a risk-conscious trader might ask: Which assets are transitioning into a higher-volatility regime? Where is the downside risk becoming asymmetric? Which sectors are carrying the most systemic risk right now? These [dashboards are live](#user-content-fn-8)[^8] and can be accessed directly via the TRP interface or as embedded widgets in external venues. In practice, they serve two roles: as a standalone risk-intelligence layer for anyone in the market, and as the analytical foundation from which users form views that are then expressed through SMART Tokens, Prediction Markets, or other risk-related products.

This approach creates a new paradigm—“**RiskFi**”. *RiskFi represents a new primitive within DeFi in which risk—volatility, liquidity stress, tail events, stablecoin depegs, funding-rate risk, and more—becomes an explicit, on-chain tradable asset*. Instead of burying risk inside complex instruments, RiskFi isolates and tokenizes it, enabling transparent markets where users can directly *speculate* on, *hedge*, *transfer*, or *acquire* specific risk exposures. RiskFi fills a structural gap in the crypto financial stack. While trading and payments infrastructure have advanced rapidly (AMMs, perps, intent-based systems, etc.), robust and transparent risk markets have lagged. By making risk *measurable, composable, and liquid*, RiskFi unlocks new forms of speculation, portfolio construction, hedging, and risk-aware yield generation. It lays the foundation for a mature crypto financial system—one where *risk is traded with the same granularity and transparency as any other digital asset*.

TradFi’s \~$18 trillion+ risk market underscores how crucial risk products are in a developed financial system. Crypto is only now beginning to take the first steps to build an equivalent risk infrastructure. As mentioned earlier, TRP estimates that **risk tokenization, risk prediction markets, and related markets could unlock a $350+ billion sector**. By being a first mover in RiskFi, TRP aims to set the standards for on-chain risk products.

## Conclusion

TRP’s launch comes at a time when the crypto industry is gradually maturing. Each major wave—from ICOs to DeFi summer to NFTs—has highlighted that as markets grow, so does the need for robust risk management infrastructure. With institutions increasingly exploring crypto, products like SMART Tokens can be key enablers: we offer a way to participate in crypto’s growth while controlling exposure to its volatility, all within the on-chain ecosystem. For DeFi natives and degens, TRP’s products represent untapped “[**risk alpha**](https://www.riskprotocol.io/articles/risk-alpha-the-55-threshold)” opportunities and money-lego primitives to compose with.

If we want to realize our collective vision of “institutions are coming” or “mainstream adoption,” it is vital that we solve for risk. By starting with volatility—crypto’s most notorious and permanent feature—and providing a means to split and trade that volatility, TRP is laying the foundation for a more mature market where risk is not just an inevitable downside, but also a *resource to be exploited*. First-time crypto holders won’t be forced onto the same rollercoaster of volatility; they will be able to choose their own adventure, whether that’s a calmer ride or an amplified thrill, and those with the insight to predict risk can profit in entirely new ways.

As of this writing, our **Incentivized Testnet** is live, featuring the [Trading Competition](https://app.riskprotocol.io/dashboard) to boost usage and reward early adopters. With the mainnet on the horizon, the era of RiskFi is beginning. TRP invites the community—traders, HODLers, investors, builders, and curious minds alike—to join as we launch these new primitives, refine them, and **unlock the vast untapped value in RiskFi**!

[^1]: The initial focus is volatility risk. Subsequent products will provide risk exposures to other kinds of risks like liquidity, liquidation, smart contract etc.

[^2]: An early rebalance can be triggered in extreme market downturns. Based on five years of stress simulations, we have observed a need to trigger an early rebalance only once. This would require an extreme, intra-epoch crash of \~55%. In such a scenario, the RiskON token may be written down to near zero in order to ensure that the RiskOFF token is made whole on its put. Please refer to protocol documentation for more details.&#x20;

[^3]: Value of RiskOFF = 50% of underlying + value of put - value of call. See "Product Specifications" in protocol documentation for more detail.

[^4]: While minting, you can also choose to receive either just RiskON or just RiskOFF and this is seamlessly executed in one transaction from the user's perspective (while in the background, first the RiskON/RiskOFF SMART Token pair is created and then one token is swapped for the other).

[^5]: Notably, suppose an extreme move happens during an epoch (say, the underlying price crashes through RiskOFF’s floor and breaches the down and out barrier), the protocol will trigger an early settlement. In such a scenario, RiskON effectively transfers any remaining collateral to RiskOFF and is extinguished (goes to pennies on the dollar), and a new epoch begins immediately with both tokens reset to equal value. This mechanism ensures that RiskOFF holders receive protection when needed, and RiskON holders never owe more than their initial stake. Such safeguards make the system robust even in black-swan events.

[^6]: &#x20;For the sake of simplicity, in our examples, we ignore any protocol fees. See protocol documentation for details on fees.

[^7]: When minting SMART Tokens, the user can seamlessly choose to receive just RiskON or RiskOFF.&#x20;

[^8]: In addition to the current dashboards we intend to actively design and deploy, on an ongoing basis, additional dashboards that provide unique insights into different types of crypto risks.


# dApp User Guide

Walkthrough: From BTC to RiskON/RiskOFF and Back

This is a dApp walkthrough that takes you from holding plain BTC to experiencing the full “SMART Token” flow on The Risk Protocol ("TRP"), and then back again. You will see how to claim test BTC, split it into RiskON BTC and RiskOFF BTC, lean into protection when you wish, earn LP fees by supporting the DEX, and finally redeem your SMART tokens back into BTC.

{% hint style="info" %}
The flow is the same for ETH as well.
{% endhint %}

{% hint style="info" %}
To interact with the TRP Testnet, you will need ETH on Arbitrum Sepolia to pay gas fees. It is free: claim Sepolia ETH from a faucet and move it across with the official Arbitrum Bridge—relevant details can be found in the [Getting Started](https://docs.riskprotocol.io/overview/getting-started) section.
{% endhint %}

Follow the steps on the testnet first to get comfortable with the mechanics before committing real capital. Once you have gone through this loop once or twice, the logic behind TRP's design becomes very natural.

## **1.  Landing on the Homepage**

<figure><img src="/files/CXIbn1pFqlgDBNrX2sc8" alt=""><figcaption></figcaption></figure>

You begin on The Risk Protocol homepage. This is where you get the high-level idea: TRP lets you choose how much risk you actually want to hold, by splitting one BTC position into two SMART tokens—RiskON BTC for more levered exposure, and RiskOFF BTC for buffered downside. When you’re ready to make your first trade, click **“Launch dApp”**.&#x20;

## **2.  Launching the dApp and Connecting Wallet**

<figure><img src="/files/pjfBCMiPnIvQV7Yp112E" alt=""><figcaption><p>You can use WalletConnect to access The Risk Protocol via 500+ wallets of your choice.</p></figcaption></figure>

We support a wide variety of wallets. In this walkthrough, we continue with MetaMask, one of the most popular browser wallets, but you can use any supported wallet you are comfortable with. When the connection prompt appears, approve it, and ensure you are on the correct network (Arbitrum Sepolia).

## 3.  Getting Test ETH for Gas

Before you can transact, you will need a small amount of test ETH to pay gas fees on Arbitrum Sepolia, where the TRP Testnet runs. Getting it takes two short steps, and both are free. First, claim Sepolia ETH on Ethereum Sepolia: several public faucets can send it to you, and one popular option is the Sepolia faucet hosted by [Google](https://cloud.google.com/application/web3/faucet/ethereum/sepolia). Choose **Ethereum Sepolia** as the network, paste in your wallet address, and request funds. Within a few seconds, you should see the test ETH balance appear in your wallet.

Choose **Ethereum Sepolia** as the network, paste in your wallet address, and request funds. Within a few seconds, you should see the test ETH balance appear in your wallet. Bridge it to Arbitrum via [Arbitrum's official bridge](https://bridge.arbitrum.io/). Now you are all set to start transacting on Sepolia, and we can move on to getting test BTC in the [TRP dApp](https://app.riskprotocol.io).

<figure><img src="/files/HkQqLSHDtdQiJEooGjhU" alt=""><figcaption></figcaption></figure>

## 4.  Getting Test BTC from the Faucet

Now that you have ETH for gas, you need some test BTC to experience how The Risk Protocol works end-to-end. Inside the TRP dApp, you can request Test Funds (BTC or ETH) directly from the interface. You can get Test Funds (BTC) from the wallet button's drop-down menu. This test BTC is what you will split into RiskON BTC and RiskOFF BTC in the next step.

<figure><img src="/files/O7ukf2D83lDRYTHVUWIk" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/CmGekNeA3PiZP2juCB9b" alt=""><figcaption><p>Confirm the transaction.</p></figcaption></figure>

<figure><img src="/files/6G1gZobg3WcN27hj4yal" alt=""><figcaption><p>Transaction Successfully Completed.</p></figcaption></figure>

## 5.  Splitting BTC into RiskON BTC and RiskOFF BTC

With test BTC in your wallet, you are ready to perform the core TRP action: **splitting** BTC into RiskON BTC and RiskOFF BTC.

Navigate to the “**Split**” screen. Here you can choose how much BTC you want to convert into SMART tokens and how you want to allocate between RiskON and RiskOFF. In this example, we are splitting a 0.2 BTC test allocation, selecting a 50% / 50% split. That means half of the risk is allocated to RiskON BTC and half to RiskOFF BTC. You could choose a different percentage if you want.

When you are satisfied with the amounts, click **“Split”** and confirm the transaction in your wallet. Once it settles, your BTC balance goes down by the amount you deposited, and you now hold both **RiskON BTC** and **RiskOFF BTC** in your wallet. You have just turned a single, blunt BTC exposure into two structured positions that treat upside and downside very differently.

<figure><img src="/files/flzkTj1kVZgUuZ9nNEyh" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/lLXb2s4x7N99kS6s86V3" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Over time, we expect users to arrive with a clear preference for which side of the structure they want—RiskON or RiskOFF. To make this easy, the dApp also lets you complete this step in one go. If you move the slider to 100% RiskON or 100% RiskOFF, the interface will show a “Split & Swap” path instead of a plain split. In a single transaction, our smart contracts mint both SMART tokens and then automatically swap everything into your chosen side at the current rate. On the surface, you only make one click and receive exactly what you wanted—for example, ending up entirely in RiskOFF BTC as shown in the example—while all the intermediate steps are handled for you in the background.
{% endhint %}

<figure><img src="/files/U6usoeeWtwa2W4yeChzO" alt="" width="563"><figcaption><p>Here is how you can execute Split &#x26; Swap in one go.</p></figcaption></figure>

## 6.  Swapping RiskON BTC for RiskOFF BTC

After the split, you will see balances for both RiskON BTC (ronBTC) and RiskOFF BTC (roffBTC). From here, you can adjust your exposure based on your market view.

If you did a plain Split in the previous step and now decide you want more protection, you can swap some or all of your RiskON BTC into extra RiskOFF BTC. Go to the **“Swap”** section, set the **“Sell”** token to ronBTC and the **“Buy”** token to roffBTC, then enter the amount of RiskON BTC you wish to convert. The interface will show you how much RiskOFF BTC you are expected to receive and the route used to execute the trade. Click **“Swap”**, confirm the transaction, and once it has been mined, your wallet balances in the dApp will update accordingly.

If, however, you already know your desired stance in advance (for example, you want to be fully in RiskOFF BTC for this epoch), you can often achieve the same result more directly via the **“Split & Swap”** path described earlier. In that case, you select 100% RiskON or 100% RiskOFF on the Split screen and let the contracts handle the minting and swap in a single flow, rather than splitting first and swapping afterward.

You can move between RiskON and RiskOFF as often as you wish over the life of an epoch. Whether you choose a separate Split followed by Swap, or a single Split & Swap, the idea is the same: adjust your BTC exposure so it matches your current view of the market.

<figure><img src="/files/UeH612iQbivKVQYb0UWc" alt="" width="563"><figcaption></figcaption></figure>

## 7.  Adding Liquidity

Beyond holding SMART tokens, you can also support the protocol’s markets and earn fees by adding liquidity, similar to what you might do on Uniswap, Curve, or Balancer. Liquidity providers help make trading smoother for everyone and are rewarded with liquidity provider ("LP") fees (and potentially other incentives).

To begin, go to the “**Liquidity**” section in the top navigation and click “**Add Liquidity**”. This brings up a list of available pools.

Select the pool you want to join; in this walkthrough, we choose the **ETH Pool**, which holds **ETH**, **RiskON ETH**, and **RiskOFF ETH**.

<figure><img src="/files/fSHRC7dreEfEcX4GSjz7" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ugIESPjD7iidLF11tZ65" alt=""><figcaption></figcaption></figure>

In the example shown, you choose how many LP tokens you want to mint, and the pool automatically calculates the proportional amounts of BTC or ETH, and their corresponding RiskON and RiskOFF that need to be deposited, based on the current pool balances and weights. Once you confirm and the transaction succeeds, a summary screen will confirm that your liquidity has been added and that LP tokens have been sent to your wallet.

<figure><img src="/files/9VguraJDWjXpRouqvOVx" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/hs1AwZG6OWQj70sFCUxC" alt=""><figcaption></figcaption></figure>

Removing liquidity follows almost exactly the same flow. From the same pool view, click “**Withdraw**”, choose how many LP tokens to redeem, and confirm. The pool will burn your LP tokens and return the underlying assets back to your wallet, along with your share of accumulated fees.

## 8.  Redeeming Collateral

You can redeem your collateral at any point and revert to holding BTC. To redeem the underlying BTC, you will need **equal amounts of RiskON BTC and RiskOFF BTC. This 1:1 equivalence is a fundamental tenet of the protocol, designed to ensure that the platform remains risk-neutral.**

When you initially select a RiskON/RiskOFF token to redeem, the dApp will automatically show you the maximum BTC you can redeem based on your holdings of the two SMART Tokens. If you have unequal amounts of the two tokens, you can either choose to redeem the maximum BTC you can based on your current holdings or use the Swap module to top up the lower-balance token until you have matching quantities. In the example here, you can see that if we want to redeem 0.1 BTC, we have sufficient balances of both tokens. Once you have a balanced pair, head to the **“Redeem”** panel. Enter how much you want to burn—for instance, 0.1 of each SMART token—and confirm the transaction. The protocol burns your 0.1 ronBTC and 0.1 roffBTC and sends **0.1 BTC** back to your wallet.

This is the final step in the loop: you began with BTC, moved through splits, swaps, and liquidity provision, and then came back to BTC with a more controlled and deliberate risk profile along the way.

<figure><img src="/files/XYrOHjfgd3tZi4XWINDb" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/mMDCphBVifKRyX1jSO9T" alt=""><figcaption></figcaption></figure>

## Final Thoughts

In a market where most BTC holders are forced to choose between “do nothing” and “go full degen”, The Risk Protocol offers a genuine middle path: stay in BTC, but decide how much risk you actually want to shoulder. By splitting BTC into SMART tokens like RiskON BTC and RiskOFF BTC, TRP transforms a single, blunt exposure into a more nuanced set of choices that both long-term allocators and short-term traders can dial up or down across different market regimes.

In TradFi, risk-transfer instruments quietly underpin how institutions manage trillions in exposure. TRP brings a similar philosophy on-chain for BTC and ETH and for other assets later on: clear pay-offs, epoch-based outcomes, and transparent rules that govern how upside and downside are shared between RiskON and RiskOFF. Instead of passively enduring crashes or constantly trying to time the market, BTC holders can pre-define where they want protection to kick in and how much upside they are willing to share in return.

On top of that, liquidity pools around SMART Tokens add another layer of opportunity. Users who are comfortable with the mechanics can provide liquidity and earn fees and incentives, effectively stacking yield. Traders, passive allocators, and DAO treasuries can all meet in the same venue: some seeking convex upside in RiskON, some seeking buffered downside in RiskOFF, and others farming the excess return possible by dynamically allocating across the 2 tokens as market sentiment changes.

The walkthrough you have just followed is one complete pass through this system on testnet. Once you are familiar with each step—from faucet, to split, to swap, to liquidity, to redemption—you can start to experiment with your own views, allocations, and time horizons, using The Risk Protocol as a way to remain in BTC and ETH while taking a much more intentional stance on risk.


# Whitepaper

{% file src="/files/j6Uj2B98Zlcb0KyqPr0V" %}


# Math Proofs & Derivations

Mathematical foundations of protocol design

*On the way....*


# Video Guides

*We're working on this—more details on the way...*


# SMART Tokens

Split Mechanism for Asset Risk-Tokenisation

## Underlying Concept

SMART Tokens are the core primitive for risk-tokenization, built on an ERC-4626–compatible interface with integrated rebalancing. We launch initially with a specific type of SMART Token called **RiskON** & **RiskOFF**.&#x20;

When you deposit an asset as collateral with The Risk Protocol, that asset is split into two complementary tokens—for example, depositing 1 BTC yields 1 RiskON BTC and 1 RiskOFF BTC. These two tokens, in aggregate, always represent the underlying asset’s value, but each is programmed with a different risk/return profile. They are two halves of the same whole, but with dramatically different behavior. RiskOFF offers stability and downside protection, while RiskON provides leveraged exposure. Think of these as two different "risk flavors".

**RiskOFF is the low-risk half**. It has a claim on 50% of the underlying and is designed to track the underlying asset’s price, but within a limited range. It does that by having a built-in *floor on losses and a cap on gains*. For example, RiskOFF BTC might be defined to never drop more than -5% (the *“floor”*) in a given period and to forgo any upside beyond +8% (the *“cap”*). It achieves this by holding options, specifically a "costless collar". In essence, RiskOFF sacrifices extreme upside in exchange for a safety net on the downside. *The result is a token that is significantly less volatile than the underlying.*

**RiskON is the high-risk half.** It, too, has a claim on 50% of the underlying and is the mirror image of RiskOFF—the same options, but opposite in sign. Where RiskOFF is long a put, it is short the same put, and where RiskOFF is short the call, it is long the same call. RiskON takes on the volatility that RiskOFF sheds. The simple contract between RiskON & RiskOFF is that by agreeing to bear the downside beyond RiskOFF’s floor, RiskON earns the right to all upside beyond RiskOFF’s cap. *This makes RiskON a super-charged leveraged version of the underlying asset.* If the asset’s price rallies strongly, RiskON will outperform the asset (since it gets an extra slice of upside). Conversely, if the price plunges, RiskON will underperform and absorb more losses, even approaching zero in extreme cases—that is the trade-off for its leveraged upside.

Within the cap and the floor, both RiskON & RiskOFF behave the same as the underlying asset (because each has a 50% claim on the underlying and all the options are out of the money).

How can two tokens cover each other’s risk like this? The magic lies in *synthetic options* and *smart contract design*. TRP doesn’t purchase options from an exchange or work with any market makers—no external liquidity is needed to price the options. Instead, the *two tokens are counterparties to each other*. It’s an internal risk swap: *RiskOFF’s contract with RiskON guarantees RiskOFF a certain payoff (the put option’s protection) and, in exchange, obligates RiskOFF to give up some payoff to RiskON (the call option’s upside share)*. The synthetic options held by RiskON & RiskOFF are equal in magnitude but opposite in sign. Bring them together, and they cancel each other out, leaving the holder with a 50% claim on the collateral + a 50% claim on the collateral = the underlying collateral asset.&#x20;

Because these derivatives are synthetic and perfectly offset within the pair, the system remains self-contained and *delta-neutral*. Depositing 1 BTC as collateral allows a user to mint 1 RiskON + 1 RiskOFF. A user can redeem the 1 BTC at any point by burning 1 RiskON and 1 RiskOFF. This 1:1 equivalency ensures that TRP itself takes *no directional exposure and never risks its solvency*.


# Primary Attributes

Unique Design Features of SMART Tokens

SMART Tokens are defined by the primary attributes listed below. Please refer to [*Product Specifications*](/protocol-design-and-specifications/product-specifications) for a detailed description of the various types of SMART Tokens:

1. **Intuitive Risk Profiles:** Each SMART token offers a pre-packaged risk/return profile or payoff (e.g., "RiskON", “Low VOL”, or "10x BULL") that investors can choose based on their risk appetite. This spares users from needing to understand or manage complex options themselves—the complexity is fully abstracted away. Buying a RiskOFF token is as simple as purchasing any ERC-20 token, yet it implicitly means you hold a protected, lower-volatility exposure to the underlying. SMART Tokens effectively allow crypto users to focus on *outcomes, not mechanics*.
2. **Price Discovery & Liquidity**: It has been our observation that, while most DeFi projects tout lego-like composability, this is not the case in practice. The reason is quite simple. True composability requires price discovery and liquidity in order to make such tokens practically usable. Our design incorporates both these elements:&#x20;
   1. We facilitate price discovery by publishing a second-by-second Net Token Value ("NTV") for all our SMART Tokens and,&#x20;
   2. We’ve created an AMM liquidity marketplace for the SMART Tokens.
3. **Fully collateralized, No Liquidations**: Every SMART token pair is 100% backed by collateral (the initial deposit asset). There are no borrowed funds, so margin calls and liquidation events never occur. Even in extreme market moves, the RiskOFF put is always made whole, while the RiskON token can go to near zero but never negative.<sup>\[1]</sup>
4. **Highly Configurable Risk Profiles:** The SMART tokens are highly configurable, and we can create an endless range of risk payoffs by varying key parameters such as option strategy, strike levels, and duration. In addition:
   1. The collateral can be an underlying cryptocurrency or a stablecoin.
   2. The synthetic options can be based on a reference asset that is different from the collateral asset.
5. **On-Demand Creation & Redemption**: SMART tokens are always created in pairs. If a user deposits 1 BTC, they will receive 1 RiskON BTC and 1 RiskOFF BTC. Similarly, they can only be redeemed in pairs. In the example used above, if the user wants to redeem his/her collateral of 1 BTC, they will have to burn 1 RiskON BTC and 1 RiskOFF BTC. SMART tokens can be minted at any time by interacting with TRP's permissionless smart contracts, and the collateral can also be redeemed at any time, subject to the requirement mentioned in this paragraph.
6. **Tethered Value:** Each SMART token pair is designed to have an aggregate value equal to the underlying collateral. Arbitrage opportunities are created when that is not the case.
7. **Synthetic Options**: The SMART tokens owe their risk profile to embedded synthetic options that represent a claim on the underlying collateral. The options embedded in the SMART tokens are not purchased on any exchange or OTC desk; instead, they are synthetically created by TRP by having the two SMART tokens in a SMART token pair serve as counterparties to each other.

***

<sup>*\[1] In the event that the barrier in the down-and-out put is hit, RiskON will transfer its share of the underlying collateral to RiskOFF and go to near zero. The current epoch will end, and a new one will commence immediately, with RiskON and RiskOFF set to equal values again.*</sup>


# Utility & Benefits

SMART Tokens and the [Risk Marketplace](/protocol-design-and-specifications/risk-marketplace) combine to unlock a variety of use cases, catering to both risk-averse participants and risk-seeking traders. Here are a few examples of how TRP’s products can be used in practice and the associated benefits:

### **1.  Hedge Volatility without Leaving Crypto**

Perhaps the most immediate use case is for investors who believe in crypto’s long-term potential but can’t stomach the short-term volatility. Instead of selling their holdings for stablecoins, they can convert their assets into RiskOFF tokens. For example, an ETH holder worried about market turbulence could swap into RiskOFF ETH. If ETH’s price drops significantly, the RiskOFF token will drop much less, preserving capital. If ETH rises, RiskOFF ETH will also rise up to its cap—still capturing moderate upside. If users see sustained upside momentum, they can seamlessly swap into RiskON. This strategy provides a crypto-native form of downside protection. *Unlike a stablecoin, the holder remains invested in ETH (and can benefit if ETH recovers), but with a cushion against extreme moves*. This can be especially valuable for long-term holders during bear markets or for miners, stakers, and treasuries who accumulate crypto but want to reduce drawdown risk. DeFi treasuries and DAOs that currently park funds in stablecoins (exiting crypto exposure to preserve runway) could instead hold RiskOFF. This way, a project treasury could hedge the downside risk while still benefiting from some upside when the token performs well. *Unlike stablecoins, which eliminate upside entirely, RiskOFF provides a middle ground: risk reduction without full exit and continuing to capture modest upside*.

### **2.  “Stabler” Collateral for DeFi**

RiskOFF tokens could become a better form of collateral for lending protocols, DEXs, and stablecoin issuers, as they often struggle with the fact that crypto collateral is highly volatile, which can trigger liquidations or require significant over-collateralization. RiskOFF, being significantly less volatile than the likes of BTC and ETH, is inherently a superior collateral asset. For instance, RiskOFF BTC has historically shown long-term volatility equivalent to that of traditional equity markets. Logically, a lending protocol would allow higher LTV ratios on RiskOFF BTC compared to BTC. If DeFi money markets, DEXs, or stablecoin issuers integrate RiskOFF tokens as accepted collateral, users could get more against their holdings with less risk of liquidation. *RiskOFF is not a stablecoin but definitely a "stabler" coin compared to the underlying asset.*

### **3.  Leverage without Margin Calls or Liquidation**

On the flip side, traders who want to amplify their exposure can use *RiskON tokens as a safer form of leverage*. Buying a RiskON-BTC token, for instance, gives you levered exposure to Bitcoin’s moves—you gain extra on the upside in exchange for taking on extra risk on the downside. Crucially, this leverage comes without any risk of liquidation. In a traditional margin trade or using leveraged tokens, a sudden dip might liquidate your position. With RiskON, even if the market swings against you, the token simply loses value, but you are never forced out—you can hold it and possibly recover if the market rebounds. This makes RiskON tokens an attractive tool for expressing bullish views or short-term trades where the user is comfortable with high volatility but doesn’t want the administrative headache or tail risk of margin loans.

### **4.  “Risk as Alpha”**

TRP's tokens enable a new kind of active alpha strategy: dynamically shifting between RiskON and RiskOFF, based on market conditions. In strong bull phases, you rotate into RiskON to concentrate upside; in stressed or sideways phases, you rotate into RiskOFF to cushion drawdowns and de-risk. Our historical backtests as of April 2026 illustrate the theoretical ceiling of this approach. For BTC, a dynamic SMART Token selection strategy of actively swapping between RiskON & RiskOFF tokens would have flipped a \~28% BTC drawdown over the last 1 year into a \~15% gain (\~1.6× BTC) for the dynamic strategy, turned a \~132% BTC gain over 3 years into \~1,921% (\~8.7× BTC), and amplified a modest \~13% BTC gain over 5 years into \~17,222% (\~153× BTC). For ETH, the same exercise turns a \~20% gain for ETH over 1 year into \~309% for the dynamic strategy (\~3.4× ETH), a \~14% ETH gain into \~2,121% over 3 years (\~19.5× ETH), and flips a \~19% ETH drawdown over 5 years into \~38,440% (\~479× ETH). Now, of course, no one can time the market perfectly in practice, but these "best path" figures show how powerful risk-mode switching between RiskON and RiskOFF can be compared with passive buy-and-hold. For active traders, SMART Tokens effectively open up a new source of alpha, using fully collateralized instruments rather than leveraged perps or margin loans.

#### Dynamically Shifting Between RiskON BTC & RiskOFF BTC

<figure><img src="/files/4ZXHzJpU3Iy5v0MqHhIK" alt=""><figcaption></figcaption></figure>

#### Dynamically Shifting Between RiskOn ETH & RiskOFF ETH

<figure><img src="/files/ngaweplmwc2EuZAC30Tl" alt=""><figcaption></figcaption></figure>

*In summary, picking the right token for the market environment will yield significant outperformance relative to just holding the underlying asset, as illustrated in the analysis above.* SMART Tokens provide DeFi a toolkit to trade risk at the native level, rather than resorting to off-chain derivatives or blunt instruments like selling to USD.

### **5.  SIMPLICITY**

No Greeks. No spreadsheets. SMART Tokens wrap complex risk exposures into a single, intuitive token so you can act on your market view without having to understand derivatives or the mechanics behind them. Focus on the outcome, and let the complexity run under the hood. Designed for both traders and non-traders, SMART Tokens don’t require a derivatives background. They behave like simple tokens you can hold in a wallet, LP into, use as collateral, or integrate into other DeFi protocols—without ever touching an options chain or perp exchange.

### **6.  Unique Alpha**

SMART Tokens unlock alpha streams unavailable in perps or spot.&#x20;

***Unlike perps***: Perps give you linear leverage with funding-rate risk and liquidations. TRP’s SMART Tokens, on the other hand, provide non-linear exposure with the ability to “bend” the risk/return profile of the underlying. There are no liquidations, no funding-rate payments, and no margin management. You’re holding a fully collateralized payoff that automatically adjusts to market volatility. Instead of managing leverage, you select a risk flavor (RiskON or RiskOFF) and hold it like any other token.

***Unlike options markets***: Options are powerful but complex—implied vols, Greeks, expiries, strikes, premium decay, etc. TRP abstracts away all of that. No constructing various option legs, no rolling positions. You simply choose the level of risk you want, and the protocol handles the mechanics behind the scenes.&#x20;

TRP offers a new primitive, not another derivative instrument: With a derivative, you bet on an asset. With TRP, you hold a transformed version of the asset itself. A primitive behaves like a simple asset you own, not a contract you must maintain and monitor. It can be:

* *Sent*
* *Traded*
* *Used as collateral*
* *Composed with other protocols*
* *LP’d or staked in DeFi*

Most perp platforms (GMX, Hyperliquid, Synthetix Perps), on the other hand, expose positions that are:

* *Account-based, not tokenized*
* *Dependent on margin and liquidation engines*
* *Dynamic due to funding payments*
* *Non-transferable*
* *Not ERC-20 assets*

Because perp positions live within the protocol’s accounting system, they cannot be moved, used as collateral elsewhere, or LP’d or staked like a simple token.

### **7.  PERPETUAL**

Finally, with SMART tokens, there’s no need to roll over expiring derivative positions. You get automatically rebalanced at zero cost


# Split & Redeem

SMART tokens are always created in pairs and there is always 1:1 equivalency between the underlying cryptocurrency deposited as collateral and the number of SMART Tokens created. If a user deposits 1 BTC, the user will receive 1 RiskON BTC + 1 RiskOFF BTC. Similarly, they can only be redeemed in pairs. In the example used above, if the user wants to redeem his/her collateral of 1 BTC, they will have to burn 1 RiskON BTC and 1 RiskOFF BTC.&#x20;

SMART tokens can be created (minted) at any time by interacting with TRP's open source, permissionless, smart contracts and the collateral can also be redeemed at any time by burning a SMART Token pair. The minting and the burning mechanisms are frictionless with no minting or redemption fee.

## 1.  Split

This function enables users to "split" underlying cryptocurrencies into two halves represented by the RiskON & RiskOFF SMART tokens. This process allows users to manage and customize their exposure to cryptocurrency volatility.\
\
Split Algorithm: `1 Underlying = 1 RiskON + 1 RiskOFF` &#x20;

#### Key Functions <a href="#key-functions" id="key-functions"></a>

* **Deposit Method**: This method converts underlying tokens into SMART tokens and distributes them to the specified recipient.
  * Parameters:
    1. `assets`: Amount of the underlying token to be split.
    2. `recipient`: The receiver of the SMART tokens.
* **Mint Method**: This method allows users to mint SMART tokens directly by specifying the number of shares they wish to receive.
  * Parameters:
    1. `shares`: Amount of SMART tokens to be received.
    2. `recipient`: The receiver of the SMART tokens.

#### Process <a href="#process" id="process"></a>

1. Approval:
   * Users must first `approve` the `TokenFactory` contract to spend their underlying tokens.
2. Execution:
   * After approval, users can utilize the `deposit` or mint `methods` to convert their assets into SMART tokens.
3. Conversion:
   * The conversion process splits the underlying token into two SMART tokens: RiskON, a leveraged version of the underlying token, and RiskOFF, which is more stable and protects against downside volatility.

#### Use Cases <a href="#use-cases" id="use-cases"></a>

* The `split` function is particularly useful for users who want to manage their exposure to crypto volatility. By splitting their holdings, users can choose to hold either the RiskON or RiskOFF tokens based on their risk appetite and prevailing market conditions, enabling a more "risk aware" investment strategy.

#### Example Scenario <a href="#example-scenario" id="example-scenario"></a>

A user holds 10 units of BTC but is wary about potential losses given uncertain market conditions. By using the deposit method, the user splits their tokens into 10 RiskON BTC and 10 RiskOFF BTC, then swaps the 10 RiskON tokens for additional RiskOFF. Now the user has downside protection without having needed to trade any derivative instruments.&#x20;

Conversely, had the market environment been more bullish, the user might have chosen to hold RiskON tokens, which would have given the user leveraged upside.&#x20;

It is our expectation that users will split with a view to holding either the RiskON or the RiskOFF token and swapping out of the undesired token.

## 2.  Redeem

The Redeem function enables users to convert their SMART tokens (RiskON & RiskOFF) back into the underlying cryptocurrency at any time. By burning SMART tokens in matched pairs, the system ensures that the aggregate value of RiskON + RiskOFF is always tethered to the underlying asset's value.\
\
This mechanism naturally creates arbitrage incentives that help maintain price stability between the SMART tokens and their underlying assets.

Redeem Algorithm: `1 RiskON + 1 RiskOFF = 1 Underlying`

#### **Key Functions**

* **Withdraw Method**: This method handles burning SMART tokens and converting them back into the underlying asset, based on the amount of the asset.
  * Parameters:
    1. `assets`: The amount of underlying assets to withdraw.
    2. `recipient`: The receiver of the underlying tokens.
    3. `owner`: The owner of the SMART tokens<br>
* **Redeem Method**: This method handles burning SMART tokens and converting them back into the underlying asset based on the input number of shares.
  * Parameters:
    1. `shares`: The number of shares to redeem for underlying assets
    2. `receiver:` The recipient of the underlying tokens.
    3. `owner`: The owner of the SMART tokens

#### **Process**

1. Preparation
   * Users must hold **equal amounts** of RiskON and RiskOFF to redeem the underlying token.\
     If the user holds only one side, they can obtain the matching token via swap pools before redeeming.
2. Execution
   * Users call the **redeem** method on the SMART Token contract, specifying the number of shares and the recipient.
3. Conversion

   * The platform’s redemption algorithm converts SMART tokens back into the underlying at a fixed rate:

   > **1 RiskON + 1 RiskOFF = 1 Underlying**

   \
   This ensures:

   * Predictable redemption outcomes
   * Continuous arbitrage alignment between the tokens and the underlying asset

#### **Use Cases**

* Users who no longer want exposure to RiskON or RiskOFF or who spot an arbitrage opportunity can quickly redeem their tokens for the underlying asset.

#### **Example Scenario**

The market prices of RiskON BTC & RiskOFF BTC aggregate up to $85,000 on TRP's Risk Marketplace. The current market price of BTC is $90,000.&#x20;

1. The user buys 1 RiskON and 1 RiskOFF
2. User then burns 1 RiskON + 1 RiskOFF
3. The user receives 1 BTC, resulting in a profit of $5,000.


# Rebalance

There are 2 types of `rebalance`:

1. **Natural Rebalance**: Occurs at regular, predefined intervals called Epochs. This type of `rebalance` is scheduled and happens automatically according to the set time periods.
2. **Early Rebalance**: Triggered by severe market downturn. Specifically, this occurs when RiskON is close to going to zero as a result of breaching the threshold pre-defined in the RiskON/RiskOFF [Product Specifications](/protocol-design-and-specifications/product-specifications) (see example below).

## How Rebalancing Works

At the end of each epoch, SMART Tokens undergo a rebalancing process that resets token prices while preserving each holder's dollar value. Think of it as a fresh start that carries your gains (or cushioned losses) forward into the next period.

Here is a walkthrough of exactly how rebalancing works—with real numbers you can follow along with.

#### The Core Principles

Before diving into the examples, here's what you need to know:

1. *Your dollar value is always preserved*. At rebalance, you receive new tokens at reset prices that equal your end-of-epoch value. No value is lost in the transition.
2. *Prices reset to 50/50*. Each new epoch starts with RiskON and RiskOFF priced equally—each representing half of the underlying collateral value.
3. *The "losing" side stays in their token*. Holders of the token with the lower Net Token Value (NTV) at epoch end receive the same token (RiskON or RiskOFF) in the new epoch.
4. *The "winning" side gets a mix*. Holders of the token with the higher NTV at epoch end receive mostly their original token type, plus some of the other token to balance the system (so they will receive both RiskON & RiskOFF).
5. *RiskOFF's protection is always honored*. Even in extreme scenarios, RiskOFF's embedded put option is made whole. RiskON can go to near zero, but never negative—you can never owe more than your initial stake.

#### Scenario Analysis &#x20;

Let's walk through some scenarios using the following assumptions:

| **Parameter**          | **Value**                    |
| ---------------------- | ---------------------------- |
| Initial BTC Price      | $100,000                     |
| Collateral Deposited   | 1 BTC                        |
| SMART Tokens Minted    | 1 RiskON BTC + 1 RiskOFF BTC |
| Starting RiskON Price  | $50,000                      |
| Starting RiskOFF Price | $50,000                      |
| RiskOFF Floor (−5%)    | $47,500                      |
| RiskOFF Cap (+8%)      | $54,000                      |

#### Our Cast of Characters

We have three users, each starting with $50,000 of value but with different risk preferences and holdings.

| **User** | **Holdings** | **Value** | **Risk Profile** |
| -------- | ------------ | --------- | ---------------- |
| User A   | 0.5 BTC      | $50,000   | Neutral          |
| User B   | 1 RiskON     | $50,000   | Aggressive       |
| User C   | 1 RiskOFF    | $50,000   | Conservative     |

## Scenario 1: Regular Rebalance (BTC Doubles)

Let's see what happens when Bitcoin has a spectacular run—doubling from $100,000 to $200,000 by the end of the epoch.

#### End-of-Epoch Results

Here's where each user stands when the epoch closes:

<table data-header-hidden><thead><tr><th></th><th width="119"></th><th></th><th></th><th></th></tr></thead><tbody><tr><td><strong>User</strong></td><td><strong>Holdings</strong></td><td><strong>Token Price</strong></td><td><strong>Value of Holdings at Epoch end</strong></td><td><strong>Return</strong></td></tr><tr><td>User A</td><td>0.5 BTC</td><td>$200,000/BTC</td><td>$100,000</td><td>+100%</td></tr><tr><td>User B</td><td>1 RiskON</td><td>$146,000 (NTV)</td><td>$146,000</td><td>+192%</td></tr><tr><td>User C</td><td>1 RiskOFF</td><td>$54,000 (NTV)</td><td>$54,000</td><td>+8%</td></tr></tbody></table>

Notice the risk transfer in action: User B's RiskON captured amplified upside (+192%) because they took on User C's upside above the cap. User C's RiskOFF was capped at +8%—the trade-off for having downside protection.

#### The Rebalancing Process

When Epoch 2 begins, token prices reset to equal values based on the new BTC price:

| **Token**     | **Epoch 2 Beginning of Period Price** |
| ------------- | ------------------------------------- |
| 1 BTC         | $200,000                              |
| 1 RiskON BTC  | $100,000                              |
| 1 RiskOFF BTC | $100,000                              |

The protocol must now deliver the correct value to each SMART Token holder:

* User B needs to receive $146,000 worth of new tokens
* User C needs to receive $54,000 worth of new tokens

#### How Tokens Are Allocated

*User C (Lower NTV Holder) → Gets Only RiskOFF*

User C held the "losing" side (token with lower Net Token Value at epoch end). They receive their entire value in their original token type:

User C end value of holdings = $54,000

RiskOFF tokens = $54,000 ÷ $100,000 = 0.54 RiskOFF

This keeps User C's conservative risk preference intact—they stay fully in RiskOFF.

*User B (Higher NTV Holder) → Gets Both Tokens*

User B held the "winning" side (token with higher Net Token Value at epoch end). They receive mostly their original token type, plus some RiskOFF to balance the system:

| **Token Type Received by User B** | **Quantity** | **Value of User B’s Holdings** |
| --------------------------------- | ------------ | ------------------------------ |
| RiskON                            | 1.000        | $100,000                       |
| RiskOFF                           | 0.46         | $46,000                        |
| Total                             | —            | $146,000 ✓                     |

#### Why This Allocation?

The total RiskOFF in the system must equal the total RiskON (since each pair backs the same collateral). At the new epoch prices:

* Total RiskOFF distributed: 0.540 (User C) + 0.460 (User B) = 1.000
* Total RiskON distributed: 1.000 (User B)

This maintains the 1:1 token balance required by the protocol.

#### What Happens Next?

If User B wants to continue with pure RiskON exposure (no RiskOFF), they can simply swap their 0.460 RiskOFF for more RiskON in the Risk Marketplace. The rebalancing preserves their value—what they do with the tokens afterward is their choice.

## Scenario 2: Barrier-Triggered Early Rebalance

Regular rebalances happen at the scheduled epoch end. But what if the market moves so violently that it threatens RiskON’s ability to provide downside protection to RiskOFF (remember that the collateral underwriting RiskON’s obligation is melting in line with the market). That's where the barrier-triggered early rebalance comes in.

#### When Does This Trigger?

An early rebalance is triggered shortly before the threshold at which RiskON goes to zero. For RiskON/RiskOFF SMART Tokens, the threshold is known in advance and is mathematically equal to half the put strike. At the threshold, the put obligation of RiskON exactly equals the value of the collateral that RiskON owns (50% of the underlying collateral), and RiskON's value is equal to zero. To prevent RiskON from going to zero, the Product Specifications dictate that the barrier knocks out shortly before the threshold and RiskON transfers its 50% share of the underlying to RiskOFF. Simultaneously, a new epoch begins, with RiskON and RiskOFF prices reset to equal each other. Such a barrier event and early rebalance are anticipated to be extremely rare.

In our earlier example, with BTC starting at $100,000 and the put strike at $95,000 (the level corresponding to RiskOFF's −5% floor), triggering an early rebalance would require BTC to crash to around $47,500—a \~52.5% drop within a single epoch.

#### Example: The Extreme Crash

Let's say BTC crashes from $100,000 to $47,500 (−52.5%) mid-epoch. Here's where each user stands:

| **User** | **Holdings** | **Token Price** | **Value of Holdings at Epoch end** | **Return** |
| -------- | ------------ | --------------- | ---------------------------------- | ---------- |
| User A   | 0.5 BTC      | $47,500/BTC     | $23,750                            | −52.5%     |
| User B   | 1 RiskON     | \~$0            | \~$0                               | −100%      |
| User C   | 1 RiskOFF    | $47,500         | $47,500                            | −5%        |

#### The Critical Guarantee: RiskOFF's Put Is Always Honored

This is where the protocol's design shines. Even in this catastrophic scenario:

* User C (RiskOFF) is protected at their floor—they only lost 5% despite BTC crashing \~52.5%. Their embedded put option was made whole.
* User B (RiskON) absorbed the excess losses. Their token went to near zero—that's the trade-off for having leveraged upside potential.
* Crucially, RiskON can go to near zero but never negative. User B can never owe more than their initial stake. There are no margin calls, no liquidations, no debt.

#### How Value Is Preserved

The total collateral in the system (1 BTC = $47,500) is distributed to make RiskOFF whole:

* RiskOFF receives: $47,500 (the full remaining collateral value)
* RiskON receives: \~$0 (effectively extinguished to honor RiskOFF's put)

A new epoch then begins immediately with both tokens reset to equal value, giving User B a fresh start (albeit with significantly less capital).

## The Rebalancing Rules Summarized

1. *Value is always preserved*. Your dollar value at epoch end carries forward exactly into the new epoch.
2. *Holders of the token with the lower NTV at the end of the epoch stay in their token*. If you held the token that ended the epoch with a lower value, you receive only that token type.
3. *Holders of the token with the higher NTV at the end of the epoch receive both tokens*. If you held the token that ended the epoch with a higher value, at the beginning of the new epoch, the majority of your holdings will be in the same token, but you will receive some of the other token as well.
4. *Total number of tokens remains balanced*. The protocol always maintains a 1:1 ratio between total RiskON and total RiskOFF.
5. *RiskOFF's protection is sacred*. Even in extreme crashes (\~52.5%), RiskOFF's embedded put option is honored.
6. *RiskON can go to near zero, but never go negative*. You can lose your stake, but you'll never owe money.
7. *You can always swap back*. After receiving mixed tokens, use the Risk Marketplace to return to your preferred single-token position.

> <mark style="color:blue;">**Bottom Line: Rebalancing ensures SMART Tokens are perpetual—they never expire or settle in cash, but roll over continuously. Your risk preferences are maintained, your value is preserved, and the system remains solvent even in black-swan events.**</mark>

For the mathematical derivations, please see [`protocol-papers-and-user-guides/math-proofs-and-derivations`.](/protocol-papers-and-user-guides/math-proofs-and-derivations)


# Risk Marketplace

DEX providing liquidity for the SMART Tokens

The Risk Marketplace is a weighted constant product automated market maker (AMM) that enables decentralized token trading. The DEX supports two main types of swaps: standard `swaps` and `split-and-swap`  operations.

## 1.  Types of Swaps <a href="#types-of-swaps" id="types-of-swaps"></a>

* **Standard Swap**: Users can trade between underlying assets and the SMART tokens within customized elastic supply pools.
* **Split and Swap**: This function allows users to deposit the underlying token and simultaneously swap one of the resulting SMART tokens for the other in a single, atomic transaction. This is particularly useful for traders who prefer to hold only one type of SMART token.

## 2.  Core Mechanism

The Risk Marketplace uses a weighted constant product invariant to determine token prices and swap outputs. Unlike traditional constant product AMMs (x × y = k), it extends the formula to support multiple tokens with customizable weights:

$$\prod\_{i=1}^{n} B\_i^{W\_i} = k$$

Where:

* $$B\_i$$ = Balance of token (i) in the pool
* $$W\_i$$ = Normalized weight of token (i)
* $$k$$ = Invariant (remains constant during swaps)

This design allows pools to hold 2-8 tokens with arbitrary weight distributions (e.g., 80/20, 60/20/20), enabling more capital-efficient exposure to specific assets.

***

#### Spot Price

The spot price between any two tokens in the pool is derived from their balance and weight ratios:

$$SP\_{i}^{o} = \frac{B\_i / W\_i}{B\_o / W\_o} \cdot \frac{1}{1 - LPFee}$$

Wher&#x65;**:**

* $$B\_i$$: Balance of token *i*, the token being sold by the trader (going into the pool).
* $$B\_o$$: Balance of token *o*, the token being bought by the trader (coming out of the pool).
* $$W\_i$$: Weight of token *i*.
* $$W\_o$$: Weight of token *o*.

***

## 3.  Swap Calculations

#### 3. a)  Output Given Input (Exact In)

When a user specifies an exact input amount, the output is calculated as:

$$
A\_o = B\_o \cdot \left(1 - \left(\frac{B\_i}{B\_i + A\_i \cdot (1 - \text{LPFee})}\right)^{\frac{W\_i}{W\_o}}\right)
$$

Where:

* $$A\_o$$: Output token amount
* $$A\_i$$: Input token amount
* $$B\_i, B\_o$$: Pool balances for tokens (i) and (o), respectively
* $$W\_i, W\_o$$: Weights of tokens (i) and (o)

#### 3. b)  Input Given Output (Exact Out)

When a user specifies an exact output amount, the required input is:

$$
A\_i = \frac{B\_i \cdot \left(\left(\frac{B\_o}{B\_o - A\_o}\right)^{\frac{W\_o}{W\_i}} - 1\right)}{1 - \text{LPFee}}
$$

Where:

* $$A\_i$$: Input token amount needed
* $$A\_o$$: Desired output token amount
* $$B\_i, B\_o$$: Pool balances for tokens (i) and (o), respectively
* $$W\_i, W\_o$$: Weights of tokens (i) and (o)


# Providing Liquidity

Liquidity providers (LPs) deposit tokens into Risk Marketplace pools and receive pool share tokens representing their proportional ownership. LPs earn LP fees generated by trading activity in the pool.

### **Pool Shares**

When providing liquidity, users receive pool shares calculated based on their contribution relative to the existing pool value. These shares:

* Represent proportional ownership of all tokens in the pool
* Accumulate value as LP fees are retained in the pool
* Can be redeemed for underlying tokens at any time (subject to circuit breakers)

### Fees

Single-asset joins and exits incur two fees that proportional joins and exits do not. Single-asset exits also incur a third, small fee on the pool shares themselves.

**LP Fee (dynamic).** Paid on the rebalancing portion of the implicit swap and **retained in the pool**, accruing to existing LPs. The LP fee is dynamic: each single-asset call must include a `feeData` payload signed off-chain by an authorized signer. The contract validates:

* ECDSA signature against the set of authorized signers
* Domain binding (`pool` matches the calling pool, `chainId` matches `block.chainid`)
* Freshness (`timestamp` within the configured `stalenessThreshold`)
* Bounds (`fee` lies within the configured `[minFee, maxFee]`)

If validation fails, the call reverts.

**Protocol Fee.** Taken on the **gross input** for joins and the **gross output** for exits. The fee is transferred directly to `protocolAddress` and is **not** retained in the pool. The rate is read from `bPool.getProtocolFee()`. If `protocolAddress` is unset, the fee is waived for that call and a `ProtocolFeeSkipped` event is emitted.

**Emergency Mode.** If signing infrastructure is unavailable, the pool owner can enable emergency mode. While enabled, single-asset joins and exits accept an empty `feeData` and fall back to a pre-configured `emergencyFee`. Outside emergency mode, calls with empty `feeData` revert with `BPOOL_Missing_Fee_Data`.

## 1.  Joining a Pool

### *1 a)  Proportional Join (Multi-Asset Deposit)*

Deposit all pool tokens in their current ratio. This method incurs no LP fees since it maintains the pool balance.

Calculation:

$$tokenAmountIn\_i = \frac{poolAmountOut}{poolSupply} \times B\_i$$

Where:

* $$poolAmountOut$$ = Pool shares to receive
* $$poolSupply$$ = Current total pool shares
* $$B\_i$$ = Current balance of token (i)

#### Key Functions

* **joinPool Method**: Handles depositing multiple tokens proportionally in exchange for the pool\
  shares.
  * Parameters:
    1. `poolAmountOut:` The amount of pool shares  to receive
    2. `maxAmountsIn[]`: Maximum amounts of each token willing to deposit (slippage protection)

#### Process

1. Ratio Calculation
   * The system calculates the ratio of requested pool shares to total supply.
   * This ratio determines how much of each token is required
2. Token Transfer
   * For each token in the pool, the required amount is calculated: `tokenAmountIn = ratio × tokenBalance`.
   * Tokens are transferred from the user to the pool; If any calculated amount exceeds `maxAmountsIn`, the transaction reverts
3. Share Minting
   * Pool shares are minted to the user equal to `poolAmountOut`

*Example*: A pool contains 1,000 ETH and 2,000,000 USDC with a total supply of 100 pool share tokens. To receive 10 pool share tokens (10% of supply):

* ETH required: 10% × 1,000 = 100 ETH
* USDC required: 10% × 2,000,000 = 200,000 USDC

### *1 b)  Single-Asset Join (Single Token Deposit)*

Deposit only one token. The pool implicitly swaps part of the deposit into the other pool tokens; the rebalancing portion incurs an LP fee. The protocol fee is taken on the full deposit amount before share math runs.

$$
poolAmountOut = \left( \left( \frac{B\_i + A\_i \times (1 - (1 - W\_i^n) \times LPFee)}{B\_i} \right)^{W\_i^n} - 1 \right) \times poolSupply
$$

Where:

* $$`A_i`$$= Amount of token credited to the pool (= `tokenAmountIn − protocolFee`)
* $$`B_i`$$ = Current balance of deposit token
* $$`W_i^n`$$ = Normalized weight of deposit token
* $$`LPFee`$$= Validated dynamic LP fee from the signed `feeData` payload

**Key Functions**

**joinswapExternAmountIn Method**: Deposit an exact amount of one token, receive calculated pool shares.

| Parameter          | Type    | Description                                                                                                                   |
| ------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `tokenIn`          | address | Address of the token being deposited                                                                                          |
| `tokenAmountIn`    | uint    | Total amount transferred from the LP. The protocol fee is taken out of this amount and the remainder is credited to the pool. |
| `minPoolAmountOut` | uint    | Minimum pool shares to receive (slippage protection)                                                                          |
| `feeData`          | bytes   | ABI-encoded `(fee, timestamp, pool, chainId)` from an authorized signer                                                       |
| `signature`        | bytes   | ECDSA signature over `feeData`                                                                                                |

**joinswapPoolAmountOut Method**: Specify exact pool shares desired; the system calculates the required deposit.

| Parameter       | Type    | Description                                                                         |
| --------------- | ------- | ----------------------------------------------------------------------------------- |
| `tokenIn`       | address | Address of the token being deposited                                                |
| `poolAmountOut` | uint    | Exact amount of pool shares to receive                                              |
| `maxAmountIn`   | uint    | Maximum tokens willing to pay, **including the protocol fee** (slippage protection) |
| `feeData`       | bytes   | ABI-encoded `(fee, timestamp, pool, chainId)` from an authorized signer             |
| `signature`     | bytes   | ECDSA signature over `feeData`                                                      |

**Process**

1. **Fee Validation** - `feeData` and `signature` are verified; the dynamic LP fee is extracted.
2. **Protocol Fee** - Computed on `tokenAmountIn` (or the implied input for `joinswapPoolAmountOut`) and routed to `protocolAddress`. Pool-share math runs on the **post-protocol-fee** amount.
3. **Pool Shares Calculation** - Uses weighted math on the net amount. The LP fee applies only to the portion that "rebalances" the pool.
4. **Execution** - Net deposit transferred from the user to the pool. Pool shares minted to the user.

{% hint style="warning" %}
**Fee Logic**: Only the portion that rebalances the pool pays the LP fee. If a token has 25% weight, depositing that token implicitly trades 75% of it for other tokens — only that 75% incurs the LP fee. The protocol fee, by contrast, is taken on the entire input.
{% endhint %}

{% hint style="info" %}
**Example**: Single-asset join with 1,000 USDC into a pool where USDC has 20% weight, LP fee 0.3%, protocol fee 0.05%:

* Protocol fee taken from input: 0.05% × 1,000 = 0.5 USDC → sent to `protocolAddress`
* Net amount credited to pool: 999.5 USDC
* Implicit swap portion: 80% × 999.5 ≈ 799.6 USDC
* LP fee paid (retained in pool): 0.3% × 799.6 ≈ 2.4 USDC
* Net contribution used for share calculation: \~997.1 USDC equivalent
  {% endhint %}

## 2.  Exiting a Pool

### *2 a)  Proportional Exit (Multi-Asset Withdrawal)*

Redeem pool shares for all tokens proportionally. This method incurs no LP fees.

Calculation:

$$tokenAmountOut\_i = \frac{poolAmountIn}{poolSupply} \times B\_i$$

Where:

* $$poolAmountIn$$ = Pool shares being redeemed
* $$poolSupply$$ = Current total pool shares
* $$B\_i$$ = Current balance of token (i)

#### Key Functions

* **exitPool Method**: Burn pool shares and receive all underlying tokens proportionally.
  * Parameters:
    1. `minAmountsOut`: Minimum amounts of each token to receive (slippage protection)
    2. `poolAmountIn`: Amount of pool shares to redeem

#### Process

1. Ratio Calculation
   * The system calculates the ratio of redeemed shares to total supply, which determines how much of each token the user receives
2. Share Burning
   * Pool shares are pulled from the user's balance and are burned, reducing the total supply
3. Token Distribution
   * For each token: tokenAmountOut = ratio × tokenBalance, and if any calculated amount is below minAmountsOut, the transaction reverts
   * Tokens are transferred from the pool to the user

*Example*: Redeeming 10 BPT from a pool with 100 BPT supply, 1,000 ETH, and 2,000,000 USDC:

* ETH received: 10% × 1,000 = 100 ETH
* USDC received: 10% × 2,000,000 = 200,000 USDC

### *2 b)  Single-Asset Exit (Single Token Withdrawal)*

Redeem pool shares for only one token. The pool implicitly sells the other tokens for the desired token; the rebalancing portion incurs an LP fee. The protocol fee is taken from the gross output before delivery, and the `EXIT_FEE` (if set) is taken on pool shares.

**Tokens Received (net of protocol fee):**

$$
tokenAmountOut = B\_o \times \left( 1 - \left( \frac{poolSupply - poolAmountIn}{poolSupply} \right)^{\frac{1}{W\_o^n}} \right) \times \left( 1 - (1 - W\_o^n) \times LPFee \right) \times \left( 1 - ProtocolFee \right)
$$

Where:

* $$`B_o`$$ = Current balance of withdrawal token
* $$`W_o^n`$$ = Normalized weight of withdrawal token
* $$`poolAmountIn`$$ = Pool shares being redeemed (before `EXIT_FEE` on shares)
* $$`LPFee`$$ = Validated dynamic LP fee from the signed `feeData` payload
* $$`ProtocolFee`$$ = `bPool.getProtocolFee()`

**Key Functions**

**exitswapPoolAmountIn Method**: Burn exact pool shares, receive calculated token amount.

| Parameter      | Type    | Description                                                                    |
| -------------- | ------- | ------------------------------------------------------------------------------ |
| `tokenOut`     | address | Address of the token to receive                                                |
| `poolAmountIn` | uint    | Exact amount of pool shares to redeem                                          |
| `minAmountOut` | uint    | Minimum **net** tokens to receive after the protocol fee (slippage protection) |
| `feeData`      | bytes   | ABI-encoded `(fee, timestamp, pool, chainId)` from an authorized signer        |
| `signature`    | bytes   | ECDSA signature over `feeData`                                                 |

**exitswapExternAmountOut Method**: Specify the exact net token amount desired; the system calculates the shares to burn.

| Parameter         | Type    | Description                                                                                                               |
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| `tokenOut`        | address | Address of the token to receive                                                                                           |
| `tokenAmountOut`  | uint    | Exact **net** amount of tokens to receive                                                                                 |
| `maxPoolAmountIn` | uint    | Maximum pool shares willing to burn. Must cover the gross calculation (`tokenAmountOut + protocolFee`), not just the net. |
| `feeData`         | bytes   | ABI-encoded `(fee, timestamp, pool, chainId)` from an authorized signer                                                   |
| `signature`       | bytes   | ECDSA signature over `feeData`                                                                                            |

**Process**

1. **Fee Validation** - `feeData` and `signature` are verified; the dynamic LP fee is extracted.
2. **Output Calculation** - Uses weighted math to determine fair gross token output.
3. **Protocol Fee** - Protocol fee is computed on the gross output and routed to `protocolAddress`. The user receives `grossAmountOut − protocolFee`.
4. **Exit Fee on Pool Shares** - `EXIT_FEE × poolAmountIn` of pool shares is sent to the factory. The remainder of the redeemed shares is burned.
5. **Execution** - Net token amount transferred from the pool to the user.

{% hint style="warning" %}
**Fee Logic**: The LP fee applies to the portion being implicitly swapped. Withdrawing a 20% weight token means 80% of the value comes from selling other tokens — that portion pays the LP fee. The protocol fee is taken on the entire gross output. The `EXIT_FEE` is taken on pool shares regardless of which token is withdrawn.
{% endhint %}

{% hint style="info" %}
**Example**: Single-asset exit for 1 BPT from a pool with 100 BPT supply, 1,000 ETH, and 2,000,000 USDC, withdrawing USDC at 80% weight, LP fee 0.3%, protocol fee 0.05%, EXIT\_FEE 0%:

* Gross USDC released by weighted math: \~25,000 USDC (illustrative)
* LP fee retained in pool: 0.3% × (1 − 0.8) × 25,000 = 15 USDC
* Net of LP fee: \~24,985 USDC
* Protocol fee: 0.05% × 24,985 ≈ 12.5 USDC → sent to `protocolAddress`
* USDC delivered to LP: \~24,972.5 USDC
  {% endhint %}


# Dynamic LP Fees

LP Fees vary based on real-time volatility

## Overview

We have designed and implemented a novel "dynamic swap fee" mechanism that adjusts the swap fees LPs receive based on the real-time volatility of the underlying asset. The rationale is simple: higher volatility typically means greater potential impermanent loss for LPs, so to compensate them, swap fees rise as volatility increases and fall as it subsides. The swap fees are *calculated dynamically based on real-time market volatility*. The fees range from a base of 40 bps to a maximum of 150 bps during periods of high volatility and are adjusted every 1 min. Fees are automatically calculated and applied to each swap transaction.

The details below describe the analysis we did to design the fee mechanism, the overall design, the rationale for design, and the implementation results simulated historically.&#x20;

{% hint style="info" %}
The following shows the analysis and design for the BTC pool. The ETH pool works similarly.
{% endhint %}

## 1.  Data Foundation and Volatility Calculation

We looked at 6 years of historical data (as of July 2025) at a frequency of 1 minute intervals, amounting to approximately 3.15 million minute-level observations

The volatility calculation employs a 60-minute rolling window approach. The last 60 minutes of price data (1-minute sampling) are used to calculate 1-minute log returns. The volatility calculated is the annualized 1-hour realized volatility (computed from 1-minute returns with a 60-minute rolling window):

*annualized\_volatility = log\_returns.rolling(window=60).std() \* sqrt(365 \* 24 \* 60)*

Key Components:

* **Log Returns**: Natural logarithm of price ratios for continuous compounding
* **Rolling Window**: 60-minute (1-hour) lookback period
* **Annualization Factor**: √(365 × 24 × 60) = √525,600 ≈ 724.68

This approach captures short-term volatility patterns while providing sufficient data points for statistical significance.

## 2.  Volatility Distribution Analysis

The chart below shows the distribution of the hourly volatility over the last 6 years :

<figure><img src="/files/ALFuvMUn1KjKJGyyCGtA" alt=""><figcaption></figcaption></figure>

* **Minimum Volatility**: 0.0217 (2.17% annualized)
* **Maximum Volatility**: 13.9931 (1399.3% annualized)
* **Median**: 0.40 (40% annualized)
* **Mean**: 0.50 (50% annualized)
* **95th Percentile**: 1.19 (119% annualized)

The volatility distribution exhibits:

* **Right-skewed distribution**: Most observations cluster around low volatility levels
* **Heavy right tail**: Occasional extreme volatility spikes during market stress
* **Concentration**: Approximately 50% of observations below 40% annualized volatility

## 3.  Fee Structure Design

The fee structure operates within defined bounds:

* **Minimum Fee**: 0.004 (40 basis points)
* **Maximum Fee**: 0.015 (150 basis points)
* **Transition Start**: 0.40 (median volatility)
* **Transition End**: 1.19 (95th percentile volatility)

Minimum swap fees of 40 bps apply for measured volatility levels of 40% and below. Maximum swap fees of 150 bps apply to measured volatility levels of 40% or higher. Between these ranges, swap fees are interpolated based on a smoothstep mapping function as detailed below:

*def smooth\_fee(volatility, min\_fee, max\_fee, v\_min, v\_max):*

&#x20;   *t = (volatility - v\_min) / (v\_max - v\_min)*

&#x20;   *t = np.clip(t, 0, 1)*

&#x20;   *return min\_fee + (max\_fee - min\_fee) \* (3\*t² - 2\*t³)*

This results in a fee mechanism with the following mathematical properties:

* **Smooth Transitions**: First and second derivatives are continuous
* **Bounded Output**: Fees constrained between min\_fee and max\_fee
* **Non-linear Mapping**: Gentle acceleration in fee increases during moderate volatility
* **Plateau Behavior**: Minimal fee changes at volatility extremes

<figure><img src="/files/WUWnysJlUmyc1sh2qXE5" alt=""><figcaption></figcaption></figure>

**Design Rationale**

*Lower Bound (v\_min = 0.40)*:

* Represents median market conditions
* Ensures 50% of trading occurs at or near minimum fees
* Provides competitive pricing during normal market conditions

*Upper Bound (v\_max = 1.19)*:

* Captures 95% of historical volatility observations
* Prevents excessive fee spikes during extreme events
* Balances risk compensation with market accessibility

## 4.  Implementation Results

We applied the fee design to the last 6 years of historical data. The chart below shows the distribution of hourly fee outcomes.

<figure><img src="/files/ULwqxM4kfU6XcFYOy43Z" alt=""><figcaption></figcaption></figure>

The implemented fee structure produces:

* **Median of fee distribution**: 0.41% (41 basis points)
* **Mean of fee distribution**: 0.58% (58 basis points)
* **95th Percentile Fee**: 1.42% (142 basis points)
* **Fee Range**: 0.40% - 1.50%

&#x20;&#x20;

The charts below show the 1-hour and 1-day average fees in 2024 and 2025

<figure><img src="/files/runRrxHkGHoW6PDK3QVC" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/zFQ0qJUAcxqWzXQG7hls" alt=""><figcaption></figcaption></figure>

**This fee mechanism protects liquidity providers during volatile market conditions while offering competitive rates during stable periods, promoting efficient price discovery and fair value exchange.**


# Wrappers

`Wrapped smart tokens`  are a specialized form of SMART Tokens designed to simplify user interactions and provide a stable representation of a user's share in the total deposit pool. By wrapping `smart tokens` , we create a fixed balance representation, where the ratio of a user's balance to the total supply represents their proportionate share of the `underlying` assets.

## 1.  Customization & Utility  <a href="#customization-for-the-risk-protocol" id="customization-for-the-risk-protocol"></a>

Built on top of `Buttonwood’s` Unbutton contracts, these wrapped smart tokens have been customized specifically to meet the unique requirements of the Risk Protocol. This customization allows us to integrate the advanced features of SMART Tokens while providing users with a more accessible and user-friendly interface.

**Benefits and Usage of Wrapped Smart Tokens**

1. **Simplified User Experience:**
   * *Accessibility for non-technical users*: Unlike smart tokens, which may experience balance fluctuations due to rebalancing, wrapped smart tokens maintain a fixed balance. This means users don’t need to worry about understanding or managing the complex mechanics of rebalancing, making it easier for them to hold and interact with the tokens.
   * *Stable Proportional Ownership*: The ratio of a user’s balance to the total supply of wrapped smart tokens directly represents their share of the total deposit pool. This proportional ownership model ensures that users can easily track their investment in the protocol without having to deal with fluctuating balances.
2. **Extended Utilities:**
   * *Composability*: By wrapping smart tokens, we ensure compatibility with a variety of DeFi protocols and applications that may not natively support the rebalancing properties of the original SMART Tokens. This opens up additional avenues for users to utilize their tokens, such as creating liquidity pools on DEXs, in lending/borrowing, and yield farming.
   * *Access to Flashloans*: Users can participate in [Flashloans](/protocol-design-and-specifications/flashloans) using unwanted tokens held by the Wrapped SMART Token contracts, providing opportunities for arbitrage. For more info, check the `Flashloan` section.

## 2.  Wrap

The Wrap function enables users to convert their SMART tokens (RiskON or RiskOFF) into Wrapped SMART tokens. By depositing SMART tokens, users receive a proportional share of wrapped tokens\
representing their stake in the total deposit pool.

**Wrap Algorithm**: `wrappedTokens = (depositAmount × totalSupply) / totalUnderlying`

#### **Key Functions**

* **Deposit Method**: Converts a specific amount of underlying SMART Tokens into wrapped tokens.
  * Parameters:
    1. `uAmount`: The amount of underlying SMART tokens to deposit
* **DepositFor Method**: Deposits SMART tokens and mints wrapped tokens to a specified recipient.
  * Parameters:
    1. `to`: The recipient address for wrapped tokens
    2. `uAmount`: The amount of underlying SMART tokens to deposit

#### **Process**

1. Preparation
   * User holds SMART Tokens (RiskON or RiskOFF)
   * User approves the Wrapped SMART Token contract to transfer their tokens
2. Execution
   * User calls deposit(uAmount) specifying the amount of SMART Tokens to wrap
   * &#x20;Contract calculates proportional wrapped tokens based on the current exchange rate
3. Conversion
   * The wrapped token amount is calculated as: `wrappedAmount = (uAmount × totalSupply) / totalUnderlying`, ensuring users receive a proportional share of the total pool

## 3.  Unwrap

The Unwrap function enables users to convert their Wrapped SMART Tokens back into the underlying SMART Tokens. When unwrapping, users also receive their proportional share of any "unwanted tokens" (see [Flashloans](/protocol-design-and-specifications/flashloans) for explanation) that have accumulated (through rebalances) in the wrapper.

**Unwrap Algorithm**: `underlyingAmount = (wrappedAmount × totalUnderlying) / totalSupply`

#### **Key Functions**

* **Withdraw Method**: Converts a specific amount of underlying back by burning the required wrapped tokens.
  * Parameters:
    1. `uAmount`: The amount of underlying SMART Tokens to withdraw
* **WithdrawTo Method**: Withdraws underlying tokens to a specified recipient.
  * Parameters:
    1. `to`: The recipient address for the underlying token&#x20;
    2. `uAmount`: The amount of underlying SMART Tokens to withdraw

#### **Process**

1. Preparation
   * User holds Wrapped SMART tokens
2. Execution
   * User calls withdraw(uAmount) specifying how much to unwrap
   * Contract calculates the proportional underlying based on the current exchange rate
3. Conversion
   * The underlying amount is calculated as: `underlyingAmount = (wrappedAmount × totalUnderlying) / totalSupply`&#x20;
   * Additionally, users receive their proportional share of unwanted tokens: `unwantedTokenShare = (unwantedBalance × userShare) / totalSupply`


# Flashloans

The Risk Protocol provides two types of `Flashloans`:

1. Flashloan of Underlying Assets
2. Flashloan of Unwanted Assets in Wrapped Smart Tokens

## 1.  Flashloan of Underlying Assets

This type of `flashloan` is similar to those offered by protocols like AAVE. We provide access to the underlying tokens locked in our smart contracts as flash loans. These loans are issued against a fixed fee and must be repaid within the same transaction.

* The `flashLoan`  method is exposed on the smart token contracts, making it accessible via the RiskON/RiskOFF token contracts.

#### Flashloan Method on Smart Contracts

The `flashloan`  method to be called on the smart contract is as follows:

```solidity
function flashLoan(
    address receiver,
    uint256 amount,
    bytes memory params
) external
```

where

* **receiver**: The address of the contract that will receive the `flashloan` and must implement the `IFlashLoanReceiver` interface
* **amount**: self-descriptive
* **params**: any parameters that would be used in the `flashloan` receiver

#### The `IFlashLoanReceiver` Interface

The receiver contract must implement the following interface to handle the `flashloan`:

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.9;

interface IFlashLoanReceiver {
  function executeOperation(
    address[] calldata assets,
    uint256[] calldata amounts,
    uint256[] calldata premiums,
    address initiator,
    bytes calldata params
  ) external returns (bool);
}

```

**Note:**

The receiver contract must `approve`  the smart token contract to spend the underlying token on its behalf.

#### Sample FlashLoan Receiver Contract

Below is an example of a simple receiver contract that implements the IFlashLoanReceiver interface:

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.9;

import "../interfaces/flashloan/IFlashLoanReceiver.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";

/**
 * @title MockFlashLoanReceiver_UND
 * @dev This contract implements the IFlashLoanReceiver interface and serves as a mock receiver for flashloan operations.
 */
contract MockFlashLoanReceiver_UND is IFlashLoanReceiver {
   using SafeMathUpgradeable for uint256;
   using SafeERC20 for IERC20;

   address public immutable LENDING_POOL;
   bool public isApproved;
   bool public mockReturn;

   event FlashLoanExecuted(
       address[] assets,
       uint256[] amounts,
       uint256[] premiums,
       address initiator
   );


   constructor(address _LENDING_POOL) {
       LENDING_POOL = _LENDING_POOL;
       mockReturn = true;
   }


   function setApprovalStatus(bool _approved) external {
       isApproved = _approved;
   }

   function updateMockReturn(bool return_) external {
       mockReturn = return_;
   }


   function executeOperation(
       address[] calldata assets,
       uint256[] calldata amounts,
       uint256[] calldata premiums,
       address initiator,
       bytes calldata params
   ) external override returns (bool) {
       for (uint256 i = 0; i < assets.length; i++) {
           // Perform operations with the loaned assets (e.g., arbitrage, liquidation)

           // Approve the LENDING_POOL to pull the repay amount
           if (isApproved) {
               IERC20(assets[i]).safeApprove(
                   address(LENDING_POOL),
                   amounts[i].add(premiums[i])
               );
           }
       }

       // Emit an event to log the flashloan execution
       emit FlashLoanExecuted(assets, amounts, premiums, initiator);

       // Return the success status
       return mockReturn;
   }
}

```

## 2.  Flashloan of Unwanted Assets in Wrapped Smart Token contracts

This type of `flashloan` is unique to our protocol, offering users access to pools of excess or unwanted smart tokens on the wrapped smart token contracts.

**Scenario Explanation**

To understand this concept better, let's consider an example involving BTC:

* We have BTC RiskON and BTC RiskOFF as smart tokens.
* Correspondingly, we have wBTC RiskON and wBTC RiskOFF as wrapped ERC20 tokens.

Each wrapped token contract (wBTC RiskON and wBTC RiskOFF) functions like a separate wallet, holding a specific amount of its corresponding smart token. (More details can be found in the Wrapped Smart Token section.

During a `rebalance`, depending on market conditions, one of the wrapped smart token contracts might end up holding not only its respective smart tokens (the "wanted" tokens) but also the other SMART Token in the SMART Token pair (the "unwanted" tokens. See "Why This Allocation?" section in [Rebalance](/protocol-design-and-specifications/smart-tokens/rebalance) for explanation). This means one of the Wrapped Smart Token contracts now contains some excess or unwanted tokens.

#### Flashloan Mechanism

In this context, our `flashloan`  feature allows users to borrow these unwanted tokens at a discount to NTV. The borrowed amount must be repaid in the wanted tokens. The discount on unwanted tokens increases progressively to incentivize their rapid liquidation from the wrapped contracts, helping maintain balance in the system.

The `flashloan` method is exposed on the Wrapped SMART Token contracts, making it accessible via the wRiskON/wRiskOFF token contracts.

#### Flashloan Method on Wrapped SMART Token Contracts

The `flashloan`  method available on these contracts is as follows:

```solidity
    function flashLoan(
        address receiver,
        uint256 amount,
        bytes memory encodedData,
        bytes memory signature,
        bytes memory params
    )
        external

```

where

* **receiver**: The address of the contract that will receive the `flashloan` and must implement the `IFlashLoanReceiverAlt` interface.
* **amount**: self-descriptive
* **params**: Any additional parameters that would be used within the `flashloan` receiver.
* **encodedData**: Encoded market prices retrieved from our API.
* **signature**: The signature of the encoded market prices from our API.

#### The IFlashLoanReceiverAlt Interface

The receiver contract must implement the `IFlashLoanReceiverAlt` interface to handle the `flashloan` operation for unwanted assets on wrapped smart tokens.

```solidity
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.9;

//Used by the flashloan in the wrapped smart token
interface IFlashLoanReceiverAlt {
    function executeOperation(
        uint256 loanAmount,
        address repayToken,
        uint256 repayAmount,
        address initiator,
        bytes calldata params
    ) external returns (bool);
}

```

**Interface Parameters**

* **loanAmount**: The amount of unwanted tokens borrowed through the `flashloan`.
* **repayToken**: The address of the token to be used for repayment (the wanted token).
* **repayAmount**: The total amount of the repayToken that needs to be repaid, including any fees or discounts.
* **initiator**: The address of the entity that initiated the `flashloan`.
* **params**: Additional parameters that may be required by the receiver contract during the `flashloan` operation.

Note:\
The receiver contract must `approve`  the wrapped smart token contract to spend the wanted smart tokens for the repayment of the loan.

#### Sample FlashLoan Receiver Contract

Below is an example of a simple receiver contract that implements the `IFlashLoanReceiverAlt` interface:

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.9;

import "../interfaces/flashloan/IFlashLoanReceiverAlt.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";

/**
 * @title MockFlashLoanReceiver_UnwantedTokens
 * @dev This contract implements the IFlashLoanReceiverAlt interface and serves as a mock receiver for flashloan operations involving unwanted tokens.
 */
contract MockFlashLoanReceiver_UnwantedTokens is IFlashLoanReceiverAlt {
    using SafeMathUpgradeable for uint256;
    using SafeERC20 for IERC20;

    address public immutable LENDING_POOL;
    bool public isApproved;
    bool public mockReturn;


    event FlashLoanExecuted(
        uint256 loanAmount,
        address repayToken,
        uint256 repayAmount,
        address initiator
    );


    constructor(address _LENDING_POOL) {
        LENDING_POOL = _LENDING_POOL;
        mockReturn = true;
    }

   
    function setApprovalStatus(bool _approved) external {
        isApproved = _approved;
    }

  
    function updateMockReturn(bool return_) external {
        mockReturn = return_;
    }

  
    function executeOperation(
        uint256 loanAmount,
        address repayToken,
        uint256 repayAmount,
        address initiator,
        bytes calldata params
    ) external override returns (bool) {
        // @note The user is expected to perform operations that ensure the repayment of tokens

        // Approve the LENDING_POOL to pull the repay amount
        if (isApproved) {
            IERC20(repayToken).safeApprove(
                address(LENDING_POOL),
                repayAmount
            );
        }

        // Emit an event to log the flashloan execution
        emit FlashLoanExecuted(loanAmount, repayToken, repayAmount, initiator);

        // Return the success status
        return mockReturn;
    }
}
```


# Trading Bots

## Overview

The Risk Protocol Trading Bot is an autonomous arbitrage system that continuously monitors and executes profitable opportunities across Risk Protocol's token ecosystem. The bot operates 24/7, executing complex multi-step transactions involving flashloans, token swaps, and redemptions to capture price inefficiencies between Risk Protocol's 1:1 deposit/redemption mechanism and market prices on decentralized exchanges, including our own.

Key Characteristics of the trading bot:

* **Autonomous Operation**: Runs continuously with configurable check intervals
* **Multi-Strategy**: Implements 6 distinct arbitrage routes
* **Capital Efficient**: Utilizes flashloans to execute arbitrage without upfront capital
* **Performance Optimized**: Sub-2-second cycle times with batched RPC calls and cached data
* **Production Hardened**: Includes retry logic, monitoring, resource management, and failsafes

We plan to open-source it soon. Users may fork the trading bot from our GitHub once we open-source it.

## System Architecture

High-Level Components

```
┌─────────────────────────────────────────────────────────────┐
│                      Trading Bot (Node.js)                  │
│  ┌─────────────┐  ┌──────────────┐  ┌──────────────────┐    │
│  │   Bot.ts    │─▶│ Helper.ts    │─▶│ Strategies.sol   │    │
│  │ (Orchestr.) │  │ (Route Logic)│  │ (Smart Contract) │    │
│  └─────────────┘  └──────────────┘  └──────────────────┘    │
│         │                │                     │            │
│         ▼                ▼                     ▼            │
│  ┌──────────────────────────────────────────────────┐       │
│  │          Shared Data Layer (Cached)              │       │
│  │  • Prices  • Flashloan Data  • Pool State        │       │
│  └──────────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────┘
                          │
        ┌─────────────────┼─────────────────┐
        ▼                 ▼                 ▼
  ┌───────────┐    ┌────────────┐    ┌──────────┐
  │  Ethereum │    │   Price    │    │ BetterSt.│
  │    RPC    │    │    API     │    │  Logging │
  └───────────┘    └────────────┘    └──────────┘
```

## Arbitrage Strategies

The bot implements 6 distinct arbitrage routes or strategies, each exploiting different market inefficiencies. The six trading bot strategies are listed below:

### Route 1: MONZA (Nested Flashloan Arbitrage)

**Strategy**: Exploit price discrepancy when `market(rON) + market(rOFF) < underlying`

**Execution Flow:**

1. Flashloan rON from Wrapper X
2. Nested flashloan rOFF from Wrapper Y
3. Redeem both tokens for the underlying (1:1 ratio)
4. Swap underlying on TRP DEX for rOFF to repay Wrapper Y
5. Swap underlying for rON to repay Wrapper X
6. Retain profit in underlying tokens

**Use Case**: When the aggregate market price of both SMART Tokens trades at a discount to the value of the underlying upon redemption.

***

### Route 2: SUZUKA (Single Token Arbitrage)

**Strategy**: Borrow unwanted token, swap for wanted token

**Execution Flow:**

1. Flashloan unwanted token from wrapper
2. Swap on Balancer for the wanted token
3. Repay the flashloan with the wanted token
4. Profit from price spread

**Use Case**: When the discount on the unwanted token in one of the wrappers is large enough to constitute a profitable arbitrage.

***

### Route 3: MUGELLO (Unwanted Token Disposal)

**Strategy**: Nested flashloans with unwanted token disposal and underlying redemption

**Execution Flow:**

1. Flashloan rON from Wrapper X
2. Nested flashloan rOFF from Wrapper Y
3. Redeem equal amounts for the underlying
4. Use underlying to acquire rOFF on Balancer
5. Repay Wrapper Y with rOFF
6. Repay Wrapper X with the remaining rON
7. Retain profit

**Use Case**: Complex market conditions with asymmetric liquidity

***

### Route 4: SPA (Premium Flashloan Strategy)

**Strategy**: Similar to Route 1 but with a premium payment structure

**Execution Flow:**

1. Flashloan both rON and rOFF from wrappers with premiums
2. Redeem for underlying (1:1)
3. Execute Balancer swaps to acquire repayment tokens
4. Repay both flashloans with premiums
5. Retain profit after covering premium costs

**Use Case**: When the arbitrage opportunity exceeds the flashloan premium costs

***

### Route 5: ASSEN (Aave Deposit-and-Swap)

**Strategy**: Arbitrage TRP 1:1 deposit rate vs Balancer market rates

**Execution Flow:**

1. Flashloan underlying from Aave V3 (0.09% premium)
2. Deposit underlying to Risk Protocol → receive rON + rOFF (1:1 ratio)
3. Swap rON to the underlying on Balancer
4. Swap rOFF to the underlying on Balancer
5. Repay Aave flashloan with premium
6. Retain profit from swap rates exceeding deposit cost

**Use Case**: When the market is buying risk tokens below 1:1 underlying value

***

### Route 6: PHILLIP ISLAND (Aave Buy-and-Redeem)

**Strategy**: Arbitrage Balancer market rates vs TRP 1:1 redemption rate

**Execution Flow:**

1. Flashloan underlying from Aave V3 (0.09% premium)
2. Calculate optimal spending for equal rON and rOFF quantities
3. Buy rON from Balancer using the calculated amount
4. Buy rOFF from Balancer using the calculated amount
5. Redeem equal amounts of rON + rOFF for underlying (1:1)
6. Repay Aave flashloan with premium
7. Retain profit from the redemption value exceeding the purchase cost

**Use Case**: When the market is selling risk tokens above 1:1 underlying value

***

#### Bot Runtime

| Property               | Value           |
| ---------------------- | --------------- |
| **Runtime**            | Node.js v18+    |
| **Language**           | TypeScript 5.7+ |
| **Blockchain Library** | ethers.js v6    |

#### Dependencies

**Protocol Integrations**:

* `@trp/core` - Risk Protocol core contracts (SmartToken, WrappedSmartToken)
* `@trp/esp` - Elastic Supply Pool (Balancer-based)

**External Protocols:**

* Aave V3 Pool (Routes 5 & 6)

#### Performance Metrics

| Metric              | Value                           |
| ------------------- | ------------------------------- |
| **Cycle Time**      | 1.5-3.0 seconds (optimized)     |
| **Data Fetch**      | \~300-500ms (batched API calls) |
| **Route Execution** | \~1.2-2.5s (parallel execution) |
| **Memory Usage**    | < 200MB steady state            |
| **RPC Batch Size**  | 100 calls per batch             |

#### Deployment

Prerequisites

**Smart Contract Deployment:**

1. Deploy Strategy contract using Hardhat UUPS proxy
2. Configure contract with token addresses and pool addresses
3. Set Aave pool address for Routes 5 & 6 (optional)
4. Verify the contract on the block explorer

**Bot Deployment:**

1. Configure environment variables (RPC, private key, contract addresses)
2. Fund the bot wallet with ETH for gas
3. Set API URL for price data endpoint

#### Bot Output Example

```
🚀 TRP Arbitrage Bot Starting...
✅ Connected to Ethereum Mainnet
✅ Loaded 6 arbitrage routes: 1,2,3,4,5,6
✅ Strategy contract: 0xABC123...
✅ Monitoring every 15 seconds

[2024-01-15 10:30:45] 🔍 Scanning routes...
[2024-01-15 10:30:46] Route 1: Complex Route: No arbitrage opportunity
[2024-01-15 10:30:47] Route 2: Simple Route: Profitable arbitrage route
[2024-01-15 10:30:48] 💰 Executed Route 2: Profit = 0.025 ETH ($45.50)
[2024-01-15 10:30:49] Route 3: Third Route: No arbitrage opportunity
[2024-01-15 10:30:50] Route 4: Fourth Route: No arbitrage opportunity
[2024-01-15 10:30:51] Route 5: Route 5: No arbitrage opportunity  
[2024-01-15 10:30:52] Route 6: Route 6: Huge arbitrage opportunity found! Profit ratio: 15%
[2024-01-15 10:30:53] 💰 Executed Route 6: Profit = 0.150 ETH ($273.00)
[2024-01-15 10:30:54] ✅ Cycle complete. Next check in 15 seconds...
```

The Trading Bot provides a powerful, automated solution for capitalizing on arbitrage opportunities in the TRP ecosystem. By following this guide and implementing proper risk management practices, users can operate the bot safely and profitably.

Remember to always:

* Test thoroughly before production use
* Monitor operations closely
* Keep configurations updated
* Maintain proper security practices
* Stay informed about protocol updates
* **USE AT YOUR OWN RISK**

Happy Arbitraging! 🚀


# Protocol Fees

There are two sources of protocol fee revenues:

1. &#x20;A SMART Token fee for the risk infrastructure provided by The Risk Protocol &#x20;
2. A Protocol Swap fee on transactions on the TRP DEX

To minimize user friction, there is no creation or redemption fee.

### 1.  SMART Token Fee&#x20;

Users are charged for the upcoming `Fee` period at each interval. A `Fee`  period is the atomic unit for charging SMART Token fees, usually set to 24 hours or one day. The `fee` is charged in the SMART Tokens themselves.

**Example:**\
If the `fee` is 0.01%, and a user holds 10 RiskON at a given time, the fee for that period would be 0.01% of 10 RiskON, which equals 0.0001 RiskON.

This `fee`  mechanism was designed to ensure that users are only charged for the actual time their assets are in the TRP ecosystem, promoting fairness and transparency in fee assessments. For instance, if a user splits an underlying asset and then redeems after 7 days, they will incur fees only for the 7-day period they were in the system, rather than a flat fee charged at the time of splitting and creating the SMART Tokens. &#x20;

### 2.  Protocol Swap Fees

A Protocol Swap Fee is charged on swap operations to generate revenue for the protocol treasury. Users are charged a percentage-based fee on the input token amount for each swap transaction. The fee is deducted before the swap calculation occurs. This fee mechanism ensures the protocol captures value from trading activity while maintaining transparent, predictable costs for users.

`Fee Token`: The fee is charged in the input token of the swap.

**How It Works**

1. Fee Calculation: The protocol fee is calculated as a percentage of the swap input amount.
2. Fee Collection: The fee is transferred directly from the user to the protocol address.
3. Swap Execution: The remaining amount (after protocol fee deduction) proceeds through the swap calculation, which nets out the [Dynamic LP Fees](/protocol-design-and-specifications/risk-marketplace/dynamic-lp-fees).

**Example**

If the protocol fee is 0.15% and a user swaps 1000 ETH:

* Protocol fee = 0.15% × 1000 ETH = 1.5 ETH (sent to protocol treasury)
* Remaining amount = 998.5 ETH (used for swap calculation)
* The LP fee (e.g., 0.4%) is then applied to the 998.5 ETH during swap price calculation

*Note: The values above are for illustrative purposes only.*


# Product Specifications

Specs of the different types of SMART Tokens offered by The Risk Protocol

{% content-ref url="/pages/kuxoIJtpN9GN4k7pJFSW" %}
[RiskON & RiskOFF](/protocol-design-and-specifications/product-specifications/riskon-and-riskoff)
{% endcontent-ref %}


# RiskON & RiskOFF

Version 12.06.25

## Introduction

To tokenize risk, TRP uses a novel mechanism called SMART—short for “*Split Mechanism for Asset Risk-Tokenization*.” This mechanism enables any crypto asset to be split into two “SMART Tokens” with distinct risk profiles. TRP has created several types of SMART Tokens. This product specification focuses on RiskON/RiskOFF.

## 1. Product Description

Upon deposit by a trader of \[x] units of an eligible cryptocurrency ("Underlying Collateral" or "Underlying Cryptocurrency"), TRP will issue to the trader two SMART Tokens that are designed to have an aggregate Net Token Value ("NTV") equivalent to the value of the Underlying Collateral. The design separates the risk of owning the Underlying Collateral into a lower-risk token, RiskOFF, and a higher-risk token, RiskON.

RiskOFF is designed to have lower volatility and beta than the Underlying Cryptocurrency, while RiskON is designed to have higher volatility and beta than the Underlying Cryptocurrency. While RiskOFF provides exposure to the Underlying Cryptocurrency at dampened volatility levels, RiskON provides leveraged upside exposure. Neither SMART Token takes on any debt in the pursuit of these objectives; leverage is achieved synthetically through embedded options positions.

For each unit of Underlying Cryptocurrency deposited, the trader shall receive 1 unit each of RiskON and RiskOFF<sup>1</sup>. For example, if a trader deposits 1 BTC with the platform, they shall receive 1 RiskON BTC and 1 RiskOFF BTC SMART Token. At any point in time, by design, NTV of RiskON + NTV of RiskOFF = Price of Underlying Cryptocurrency.&#x20;

In order to redeem the 1 unit of Underlying Collateral, a trader must deposit 1 unit each of RiskON & RiskOFF<sup>2</sup>. &#x20;

## 2. Investment Period (Epoch)

Depending on the type of SMART Token, an investment period ("Epoch") can last 30 days (a "monthly Epoch") or 7 days (a "weekly Epoch"). The period shall be specified for each SMART Token pair at product launch<sup>3</sup>. The exact Epoch end date and time will be published at the commencement of each Epoch.

On the last day of each Epoch, each token shall settle and be rebalanced into new RiskON/RiskOFF SMART Tokens for the next Epoch. The settlement and rebalancing process is described in detail below.

## 3. RiskOFF Token Specifications

The RiskOFF Token consists of:

* \[x/2] units of the Underlying Cryptocurrency
* One short out-of-the-money European-style call option on \[x/2] units of the Underlying Cryptocurrency
* One long out-of-the-money American-style down-and-out barrier put option with a collateral rebate, also on \[x/2] units of the Underlying Cryptocurrency

*Barrier Put Mechanism*: The barrier put will knock out (become worthless) if the Underlying Cryptocurrency price touches or falls below the Barrier Level during the Epoch. Upon knock-out, RiskON shall pay RiskOFF a collateral rebate. This rebate is approximately equal to the value of the Underlying Cryptocurrency held by RiskON at the time of knock-out (which represents RiskON's remaining claim on the deposited collateral).

The strikes for the two options are selected so that the proceeds from the short call exactly offset the cost of buying the down-and-out barrier put, forming a "costless collar." Both option positions are risk-reducing and, together with the underlying crypto position, should result in an investment with significantly lower volatility than holding the Underlying Cryptocurrency directly.

**RiskOFF NTV = (x/2) × Underlying Cryptocurrency Price - Call Value + Put Value**

The prices and NTV of the RiskOFF token (and the embedded options) are denominated in USD.

## 4. RiskON Token Specifications

The RiskON Token consists of:

* \[x/2] units of the Underlying Cryptocurrency
* One long out-of-the-money European-style call option on \[x/2] units of the Underlying Cryptocurrency
* One short out-of-the-money American-style down-and-out barrier put option with a collateral rebate obligation, also on \[x/2] units of the Underlying Cryptocurrency

The strikes for the RiskON options are identical to those in the RiskOFF token, ensuring the options positions of RiskON exactly offset the options positions of RiskOFF. The embedded options in RiskON, in combination with the underlying crypto position, result in an investment with enhanced or leveraged market exposure beyond the strike levels<sup>4</sup>.

**RiskON NTV = (x/2) × Underlying Cryptocurrency Price + Call Value - Put Value**

The prices and NTV of the RiskON token (and the embedded options) are denominated in USD.

## 5. Option Parameters

The following table summarizes the typical option parameters for each Epoch. Actual parameters are published at the start of each Epoch based on prevailing volatility conditions.

| Parameter           | Typical Value                                                                                | Notes                                                                                                               |
| ------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Put Strike          | 95% of price of Underlying Cryptocurrency at the start of the Epoch                          | 5% out-of-the-money                                                                                                 |
| Call Strike         | <p>\~105-110% of price of Underlying Cryptocurrency at the start of the Epoch</p><p><br></p> | We back into the call strike in order to make the put and call a costless collar                                    |
| Barrier Level       | \~47.5% of price of Underlying Cryptocurrency at the start of the Epoch                      | 52.5% decline within an Epoch triggers knock-out                                                                    |
| Rebate Level        | \~48.5% of price of Underlying Cryptocurrency at the start of the Epoch<sup>5</sup>          | Rebate is slightly less than the barrier level so that RiskON declines to near 0 but is never completely wiped out. |
| Option Style - Call | European                                                                                     | Exercisable at expiry only                                                                                          |
| Option Style - Put  | Down-and-out barrier option                                                                  | Knock-out monitored every second                                                                                    |

## &#x20;6. The Risk-Splitting Mechanism

The options in each RiskON/RiskOFF token pair are exactly equal positions but opposite in sign. The short call in RiskOFF has the same specifications as the long call in RiskON. The short put in RiskON has the same specifications as the long put in RiskOFF. By combining one unit of RiskON and one unit of RiskOFF, the options positions cancel, leaving only exposure to the Underlying Cryptocurrency.

*Creation Process*: When a trader deposits 1 unit of an Underlying Cryptocurrency with TRP, they receive 1 unit of RiskOFF and 1 unit of RiskON. The trader may then choose to sell either token and/or buy additional tokens on the platform's secondary marketplace. A trader can create SMART Tokens at any point in the Epoch.

*Redemption Process:* At any time during an Epoch, a trader may return one unit of RiskOFF and one unit of RiskON to the platform to redeem one unit of the Underlying Cryptocurrency.&#x20;

The Creation and Redemption processes and the 1:1 equivalency of an Underlying Cryptocurrency and SMART Tokens ensure that the aggregate NTVs of the two tokens remain tethered to the price of the Underlying Cryptocurrency and that the TRP platform maintains zero net delta exposure.

## 7. Pricing: Market Prices and NTVs

TRP uses proprietary volatility forecasting models (two-component GJR-GARCH) and option pricing models (Black 76 for vanilla options; Merton/Reiner-Rubinstein framework for barrier options with SABR stochastic volatility adjustments) to calculate:

* Initial option strikes that form a costless collar at the Epoch start
* Real-time (second-by-second) NTVs throughout the Epoch&#x20;

*Transparency*: All model parameters (input volatility, risk-free rate, strikes, etc.) and the decomposition of NTVs (standalone value of each embedded call and put + the value of the Underlying Cryptocurrency) are published in real time, allowing traders complete transparency into the pricing methodology.

*Important: NTVs are reference prices calculated by TRP's models. Actual market prices on the secondary marketplace may differ from NTVs due to supply and demand. Traders should be aware that they may buy or sell at prices that differ from the published NTV.*

## 8. Secondary Market

TRP provides a Risk Marketplace for secondary trading of RiskON and RiskOFF SMART Tokens. Traders may use the secondary market to:

* Trade based on perceived mispricing relative to NTVs
* Tactically switch between RiskON and RiskOFF based on market sentiment
* Convert to or from Underlying Cryptocurrency exposure

A trader who wants exposure to RiskON or RiskOFF can either go through the splitting process and then swap out of the undesired SMART Token into the desired SMART Token or directly swap into the desired SMART Token on the risk marketplace.

## 9. Settlement and Rebalancing Process

*End of Epoch Settlement*: On the settlement date, NTVs reflect the intrinsic value of each token in USD based on the settlement price of the Underlying Cryptocurrency.

*Rebalancing*: Simultaneously with the end of an Epoch, a new Epoch begins. New RiskON/RiskOFF tokens are created such that the embedded options again form a zero-cost collar at the new Epoch start price. Each trader's USD value of expiring tokens is used to determine their holdings in the new tokens. The token balances are adjusted ("rebased") such that the trader's combined USD NTV in the new tokens equals their expiring USD NTV.

At rebalance, traders holding the token with the higher NTV at the Epoch end will receive both RiskON and RiskOFF tokens in the new Epoch (see [Rebalance](/protocol-design-and-specifications/smart-tokens/rebalance) for explanation). Traders holding the lower-NTV token will continue to hold only that token type in the new Epoch. The settlement and issuance occur through an atomic swap.

### 9.1 Barrier Knock-Out Event

If the Underlying Cryptocurrency price declines to the Barrier Level at any time during an Epoch:

* The down-and-out barrier put is extinguished (knocked out)
* RiskON pays the Collateral Rebate to RiskOFF, which approximately equals the value of RiskON's remaining share of the Underlying Cryptocurrency at the knock-out price
* The current Epoch terminates immediately
* A new Epoch commences with new strikes, and token balances are rebased as described above

At barrier knock-out, RiskON's NTV will be near zero, as almost all of its claim on the collateral is transferred to RiskOFF.

## 10. Risk Factors and Disclosures

*IMPORTANT: Traders should carefully consider the following risk factors before investing in RiskON or RiskOFF SMART Tokens. This list is not exhaustive.*

### 10.1 RiskON-Specific Risks

* *Total Loss Risk: If the Underlying Cryptocurrency price declines to the Barrier Level, RiskON's NTV will be reduced to near zero, and traders in RiskON can lose nearly all of their investment.*
* *Short Put Obligation*: RiskON has a short put position. If the underlying declines below the put strike (until barrier), RiskON has levered downside exposure as a result of this obligation.

### 10.2 RiskOFF-Specific Risks

* *Barrier Knock-Out Risk*: If the barrier is breached, RiskOFF's protective put is extinguished. While RiskOFF receives the collateral rebate, subsequent declines below the barrier level will not be protected unless RiskOFF is able to sell the RiskON tokens it receives in the new Epoch.
* *Capped Upside*: Due to the short call position, RiskOFF's upside is capped at the call strike level. If the underlying appreciates significantly, RiskOFF will underperform.
* *Not a Stablecoin*: RiskOFF is NOT a stablecoin. Its volatility is significantly lower than that of the Underlying Cryptocurrency, but it can still lose value. If the Underlying Cryptocurrency declines, RiskOFF will lose value 1:1 up to the put strike. It will be protected from any further declines up to the Barrier Level.&#x20;

### 10.3 General Risks

* *Cryptocurrency Volatility*: Cryptocurrencies are highly volatile. Both SMART Tokens derive their value from the Underlying Cryptocurrency and embedded options on it.
* *Model Risk*: NTVs are calculated using TRP's proprietary models. These models may not accurately reflect true market values. Actual market values based on supply and demand may differ materially from NTVs.
* *Liquidity Risk*: The secondary market may have limited liquidity. Traders may not be able to sell tokens at fair value or in a timely manner.
* *Smart Contract Risk*: RiskON/RiskOFF are implemented via smart contracts. Bugs, exploits, or vulnerabilities could result in loss of funds.
* *Rebalancing Risk*: At rebalance, traders may receive a different token mix than they previously held. This is a structural feature of the protocol given our rebalancing mechanism.
* *No Margin Calls, But Potential Total Loss*: While the protocol does not issue margin calls, RiskON traders face the possibility of near-total loss of principal if the barrier is breached.
* *Regulatory Risk*: The regulatory environment for cryptocurrency derivatives is uncertain and varies significantly across geographies. The regulatory climate could affect the availability of these tokens in certain jurisdictions.

## 11. Disclaimers

*Past Performance:* Backtested and historical performance data shown in TRP materials are for illustrative purposes only. Past performance is not indicative of future results. Actual results may differ materially from backtested results.

*Not Investment Advice*: This document is for informational purposes only and does not constitute investment advice, financial advice, trading advice, or any other sort of advice. Investors should consult their own advisors before making any investment decisions.

*Suitability*: RiskON is not a suitable long-term investment given the possibility of near-total loss in extreme market downturns.

*No Guarantee*: TRP does not guarantee any returns, the accuracy of NTVs, or the platform's availability.

***

***Footnotes:***

<sup>1</sup>  *1 BTC is just for illustration purposes; the mechanism works similarly for fractional units of collateral. Similarly, while the example uses BTC, the mechanism applies to other cryptocurrencies supported by TRP.*\ <sup>*2*</sup>*&#x20;1 unit used for illustration purposes only, the mechanism works similarly for fractional units of Underlying Cryptocurrency and SMART Tokens.*\ <sup>*3*</sup>*&#x20; An Epoch of 30 days or 7 days may not precisely align with calendar quarters, months or weeks.*\ <sup>*4*</sup>*&#x20;RiskON is 2:1 levered outside the strikes*\ <sup>*5*</sup>*&#x20; (Barrier % level + 1%) x price of Underlying Cryptocurrency at the start of the Epoch*


# Risk Engine

{% content-ref url="/pages/75RcOV3boroMGpGr8yv3" %}
[Components](/protocol-design-and-specifications/risk-engine/components)
{% endcontent-ref %}

{% content-ref url="/pages/XzZxScuPg7Wd2W074GA1" %}
[Forecasting Volatility](/protocol-design-and-specifications/risk-engine/forecasting-volatility)
{% endcontent-ref %}

{% content-ref url="/pages/4iMe8jdbS1fHFzfAdqBa" %}
[Valuing SMART Tokens](/protocol-design-and-specifications/risk-engine/valuing-smart-tokens)
{% endcontent-ref %}


# Components

TRP has developed a highly sophisticated proprietary Risk Engine to construct tokenized products with specific risk/return profiles. The Risk Engine consists of two main components:

1. The TRP Volatility Forecasting Model.
2. The Option Pricing Engine, which includes a SABR stochastic volatility model along with an implied volatility skew model and option pricing functions.

### 2-component GARCH-GJR Models

TRP employs its volatility forecasting model to determine the strike prices of options used in its products and to price tokens in real time. Extensive research by TRP into crypto volatility (refer to "[The Nature of the Beast](https://www.riskprotocol.io/research-articles)") led to the selection of the 2-component GARCH-GJR (Glosten, Jagannathan, Runkle 1993) model for forecasting Bitcoin and Ethereum volatility. This model leverages historical return data to estimate the underlying volatility term structure.

The 2-component GARCH-GJR forecast is crucial for pricing options embedded in The Risk Protocol’s tokenized products. All TRP products include options generated using TRP's proprietary SMART mechanism. In most cases, these options do not have listed or actively traded counterparts. As a result, TRP lacks access to market prices for these options, necessitating real-time option valuation to accurately value tokens.

### SABR & Option Pricing Models

TRP is committed to providing investors with a high-quality, unbiased estimate of the value of its tokenized products. To achieve this, options must be priced in real time and incorporated into token price calculations. The options used in Risk On/Risk Off products include an out-of-the-money call and an out-of-the-money knockout barrier put with a cash rebate. Fortunately, closed-form solutions exist for pricing these options, though they involve simplifying assumptions. One of the most unrealistic assumptions in commonly used pricing models is that volatility remains constant throughout the life of the option. This assumption is clearly flawed. The SABR model is a stochastic volatility framework that adjusts volatility in traditional pricing models to account for non-constant volatility. A key advantage of SABR is that it produces a full volatility surface, which includes both an implied volatility skew and a volatility term structure. TRP uses SABR to derive stochastic volatility-adjusted implied volatilities for all strikes and expirations.

The primary input to SABR is the instantaneous volatility estimate produced by TRP’s 2-component GARCH-GJR forecast. Additional inputs include volatility of volatility (denoted as xi), a beta parameter that adjusts for different underlying price return distributions, and rho, which is the correlation between asset price returns and instantaneous volatility.

Option pricing models are employed to estimate TRP options. For standard vanilla options, TRP uses the Black 76 variant of the widely known Black-Scholes pricing model. Inputs for this model include the current underlying crypto price, the option’s strike price, a risk-free interest rate, income from the underlying cryptocurrency, time to expiration, option type (put or call), and the volatility estimate from the 2-component GARCH-GJR model adjusted by SABR. For the down-and-out knockout barrier put with a cash rebate, TRP uses formulas developed by Merton, Reiner, and Rubinstein, as detailed in Haug (2007). Inputs for this model include the underlying crypto price, strike price, risk-free interest rate, knockout barrier, cash rebate (in case of a knockout), time to expiration, income from the underlying crypto, instantaneous volatility of the underlying asset, and option type (put or call).


# Forecasting Volatility

One of the most important variables in determining the prices of the RiskON and RiskOFF instruments is the volatility of the underlying assets, such as BTC or ETH. TRP has conducted a systematic study on various attributes of cryptocurrency return volatilities for the top 50 cryptocurrencies (see [Gosal, McMurran, and Ding 2022 ](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4954736)for details). Our research shows that most stylized facts observed in other financial market instruments, such as equities, bonds, and foreign exchange rates, also hold for cryptocurrency returns.

For BTC and ETH, there are two significant features of return volatility that are commonly found in other financial data:

1. The leverage effect, which states that future volatility is usually higher if the underlying price goes down than when it goes up by the same amount (see Black 1976).
2. The long-memory property of speculative returns (see Ding, Granger, and Engle 1993), which shows that autocorrelations in absolute or squared returns decay hyperbolically instead of exponentially. The long-memory property is especially evident in high-frequency financial data.

To capture these stylized facts in the return and volatility generating process, we use the two-component GARCH-GJR specification (see [Ding, Gosal, and McMurran 2024](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4921210)) to model the volatility process. The conditional variance equation is specified as follows:

$$
\begin{align\*}
\sigma\_t^2 &= \frac{\alpha\_0}{(1-\beta\_1)(1-\beta\_2)} + \frac{\alpha\_1 + \varphi\_1 S\_{t-1}}{1-\beta\_1 B} \varepsilon\_{t-1}^2 + \frac{\alpha\_2 + \varphi\_2 S\_{t-1}}{1-\beta\_2 B} \varepsilon\_{t-1}^2 \\
&= \alpha\_0 + \left\[ (\alpha\_1 + \alpha\_2) + (\varphi\_1 + \varphi\_2)S\_{t-1} \right] \varepsilon\_{t-1}^2 \\
&\quad - \left\[ (\alpha\_1 \beta\_2 + \alpha\_2 \beta\_1) + (\beta\_2 \varphi\_1 + \beta\_1 \varphi\_2)S\_{t-2} \right] \varepsilon\_{t-2}^2 + (\beta\_1 + \beta\_2)\sigma\_{t-1}^2 - \beta\_1 \beta\_2 \sigma\_{t-2}^2
\end{align\*} (1)
$$

$$
\text{where } \varepsilon\_t \text{ is the de-meaned returns (residuals) with conditional mean 0 and standard deviation of } \ \sigma\_t,
\text{and } S\_{t-k} = \begin{cases}
1 & \text{if } \varepsilon\_{t-k} < 0, \\
0 & \text{if } \varepsilon\_{t-k} \geq 0
\end{cases} \quad \text{for } k=1,2
$$

is the GJR term (see Glosten, Jaganathan, and Runkle 1993) in the conditional variance equation to capture the asymmetric leverage effect of the volatility process. The two volatility components capture both long-term memory and short-term fluctuations in the volatility process.

*Our research shows that the two-component GARCH-GJR model captures the volatility dynamics in cryptocurrencies quite well*. Among the GARCH family of models, the two-component GARCH-GJR model performed best in backtesting, as measured by both the Bias-stat and Q-stat. It also outperformed implied volatility overall.


# Valuing SMART Tokens

TRP’s SMART Tokens will always consist of either the underlying cryptocurrency and options or a stablecoin and options. RiskON/RiskOFF tokens have a 30-day investment period. On day 1, TRP determines the structure of the tokens. Each token represents a claim on ½ of the cryptocurrency deposited with TRP. TRP sets the barrier put strike at 95% of the current market price of the underlying token (BTC or ETH) and records the price of this 30-day put. TRP then uses its pricing models to find the out-of-the-money 30-day call option strike price equal to the barrier put's price. The RiskON token consists of the underlying cryptocurrency, a short 30-day 95% strike-barrier put, and a long 30-day plain-vanilla call. Since the price of the long call and the short put in the RiskON token are equal and RiskON tokens have positions with opposite signs, the initial price of a Risk On token will be ½ of the underlying cryptocurrency.

RiskOFF holds the other half of the deposited cryptocurrency plus the same options as the RiskON token, except that RiskOFF is short the call and long the barrier put. This means that RiskOFF will also have an initial price of ½ of the underlying cryptocurrency.

TRP’s goal is to facilitate a thriving, liquid secondary market for its tokens. Token market participants require accurate price data to determine whether to buy or sell TRP tokens. TRP believes that general interest in its tokens will be sufficient to ensure liquidity on the Automated Market Maker (AMM), so that the tokens' live market prices reflect their actual value. To aid in price discovery, TRP also publishes model-based estimates of the net token value (NTV) for each traded SMART Token, using its 2-component GARCH-GJR forecast, SABR, and option-pricing models. These price estimates will be published on a second-by-second basis.

**The procedure to provide estimated real-time NTVs is as follows**:

1. Generate an instantaneous volatility forecast for the underlying cryptocurrency for the period from the current time to the expiration date (rebalance date).
2. Use the SABR model to adjust this volatility forecast for stochastic volatility.
3. Use the SABR model to adjust the option implied volatility to account for the implied volatility skew.
4. Use these volatilities to price the options in TRP tokens.
5. Add up the values of the long and short positions in each token and publish the price.

**On the rebalance date for the SMART Tokens, TRP will perform the following actions**:

1. Retrieve the final price of the underlying cryptocurrency.
2. Since the options are expiring, all option values will be priced using the intrinsic value formulas:
   * Final call price = max(crypto final price - strike price, 0)
   * Final put price = max(strike price - crypto final price, 0)
3. Add the cryptocurrency value and the final option values in each token to generate a final NTV.
4. Use the procedure described in the first paragraph to determine the structure of the tokens for the next 30 days. This means that each RiskON and RiskOFF token will be priced at ½ of the final cryptocurrency price.
5. Reinvest the entire values from step 3 above to buy the new tokens using the rebalance formula described earlier.


# APIs

{% content-ref url="/pages/oQ3fAQ2eEyjTYIYdCGvN" %}
[SDK](/apis-and-sdk/apis/sdk)
{% endcontent-ref %}

{% content-ref url="/pages/xXcOiLfAc3rj3ksS8QJc" %}
[TokenFactory](/apis-and-sdk/apis/tokenfactory)
{% endcontent-ref %}

{% content-ref url="/pages/D0LfYojc8AYR5XfXql3n" %}
[SmartTokens](/apis-and-sdk/apis/smarttokens)
{% endcontent-ref %}

{% content-ref url="/pages/q7d2FkB9GsnKylvRe6V4" %}
[Wrapped SmartTokens](/apis-and-sdk/apis/wrapped-smarttokens)
{% endcontent-ref %}


# SDK

## API Reference

Complete API reference for the Risk Protocol SDK.

### TokenFactory

Core token operations and management.

#### Base Methods

| Method                        | Parameters      | Returns           | Description                      |
| ----------------------------- | --------------- | ----------------- | -------------------------------- |
| `getBaseToken()`              | -               | `Promise<string>` | Get base token address           |
| `decimals()`                  | -               | `Promise<number>` | Get token decimals               |
| `getSmartTokenAddress(index)` | `index: number` | `Promise<string>` | Get smart token address by index |

#### Management Fees

Access via `sdk.tokenFactory.managementFees`

| Method                                    | Parameters                                                         | Returns                        | Description                                 |
| ----------------------------------------- | ------------------------------------------------------------------ | ------------------------------ | ------------------------------------------- |
| `getRate()`                               | -                                                                  | `Promise<bigint>`              | Get current fee rate in wei (1 bps = 10^14) |
| `isFeeActive()`                           | -                                                                  | `Promise<boolean>`             | Check if fees are currently active          |
| `calculateManagementFee(amount, mgmtFee)` | <p><code>amount: string</code><br><code>mgmtFee: number</code></p> | `Promise<bigint>`              | Calculate fee for given amount              |
| `getTreasuryAddress()`                    | -                                                                  | `Promise<string>`              | Get treasury wallet address                 |
| `calculateRollOverValue()`                | -                                                                  | `Promise<bigint>`              | Calculate rollover value                    |
| `updateUserLastRebalanceCount(owner)`     | `owner: string`                                                    | `Promise<TransactionResponse>` | Update user's last rebalance count          |

**Admin Methods**

| Method                         | Parameters       | Returns                        | Description                 |
| ------------------------------ | ---------------- | ------------------------------ | --------------------------- |
| `setManagementFeeRate(rate)`   | `rate: string`   | `Promise<TransactionResponse>` | Set new fee rate            |
| `setManagementFeeState(state)` | `state: boolean` | `Promise<TransactionResponse>` | Enable/disable fees         |
| `setTreasuryWallet(wallet)`    | `wallet: string` | `Promise<TransactionResponse>` | Set treasury wallet address |

#### Rebalance

Access via `sdk.tokenFactory.rebalance`

| Method                                    | Parameters                                                                | Returns                        | Description                       |
| ----------------------------------------- | ------------------------------------------------------------------------- | ------------------------------ | --------------------------------- |
| `getRebalanceInterval()`                  | -                                                                         | `Promise<number>`              | Get rebalance interval in seconds |
| `getLastRebalanceTimestamp()`             | -                                                                         | `Promise<number>`              | Get timestamp of last rebalance   |
| `getScheduledRebalances()`                | -                                                                         | `Promise<any[]>`               | Get all scheduled rebalances      |
| `getNextSequenceNumber()`                 | -                                                                         | `Promise<number>`              | Get next sequence number          |
| `getLastTimeStamp()`                      | -                                                                         | `Promise<number>`              | Get last rebalance timestamp      |
| `getRebalanceNumber()`                    | -                                                                         | `Promise<number>`              | Get total rebalance count         |
| `getUserLastRebalanceCount(address)`      | `address: string`                                                         | `Promise<number>`              | Get user's last rebalance count   |
| `getInterval()`                           | -                                                                         | `Promise<number>`              | Get rebalance interval            |
| `applyRebalance(owner)`                   | `owner: string`                                                           | `Promise<TransactionResponse>` | Apply rebalance for user          |
| `verifyAndDecode(signature, encodedData)` | <p><code>signature: string</code><br><code>encodedData: string</code></p> | `Promise<any>`                 | Verify signature and decode data  |

**Admin Methods**

| Method                       | Parameters        | Returns                        | Description                   |
| ---------------------------- | ----------------- | ------------------------------ | ----------------------------- |
| `setSignersAddress(address)` | `address: string` | `Promise<TransactionResponse>` | Set authorized signer address |
| `getSignersAddress()`        | -                 | `Promise<string>`              | Get authorized signer address |

***

### SmartToken

#### Read Methods

| Method                                    | Parameters                                            | Returns           | Description                  |                             |
| ----------------------------------------- | ----------------------------------------------------- | ----------------- | ---------------------------- | --------------------------- |
| `balanceOf(address, contract?)`           | <p><code>address: string</code><br><code>contract?: 0 | 1</code></p>      | `Promise<bigint>`            | Get token balance           |
| `unScaledbalanceOf(address, contract?)`   | <p><code>address: string</code><br><code>contract?: 0 | 1</code></p>      | `Promise<bigint>`            | Get unscaled balance        |
| `hasPendingRebalance(address, contract?)` | <p><code>address: string</code><br><code>contract?: 0 | 1</code></p>      | `Promise<boolean>`           | Check for pending rebalance |
| `getTokenFactory(contract?)`              | `contract?: 0\|1`                                     | `Promise<string>` | Get TokenFactory address     |                             |
| `asset(contract?)`                        | `contract?: 0\|1`                                     | `Promise<string>` | Get underlying asset address |                             |
| `totalAssets(contract?)`                  | `contract?: 0\|1`                                     | `Promise<bigint>` | Get total assets in vault    |                             |
| `convertToShares(amount, contract?)`      | <p><code>amount: string</code><br><code>contract?: 0  | 1</code></p>      | `Promise<bigint>`            | Convert assets to shares    |
| `convertToAssets(amount, contract?)`      | <p><code>amount: string</code><br><code>contract?: 0  | 1</code></p>      | `Promise<bigint>`            | Convert shares to assets    |

#### Write Methods

| Method                                                 | Parameters                                                                             | Returns      | Description                    |                          |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------- | ------------ | ------------------------------ | ------------------------ |
| `handlePendingRebalance(sender, recipient, contract?)` | <p><code>sender: string</code><br><code>recipient: string</code><br><code>contract?: 0 | 1</code></p> | `Promise<TransactionResponse>` | Handle pending rebalance |

#### Transactions

Access via `sdk.smartToken.transaction`

**Transfers**

| Method                                               | Parameters                                                                                                            | Returns      | Description                    |                                      |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------ | ------------------------------------ |
| `transfer(recipient, amount, contract?)`             | <p><code>recipient: string</code><br><code>amount: string</code><br><code>contract?: 0                                | 1</code></p> | `Promise<TransactionResponse>` | Transfer tokens                      |
| `transferFrom(sender, recipient, amount, contract?)` | <p><code>sender: string</code><br><code>recipient: string</code><br><code>amount: string</code><br><code>contract?: 0 | 1</code></p> | `Promise<TransactionResponse>` | Transfer tokens from another address |

**Deposits**

| Method                                                               | Parameters                                                                                                                                                                                            | Returns      | Description                    |                                     |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------ | ----------------------------------- |
| `maxDeposit(account, contract?)`                                     | <p><code>account: string</code><br><code>contract?: 0                                                                                                                                                 | 1</code></p> | `Promise<bigint>`              | Get max deposit allowed             |
| `previewDeposit(amount, contract?)`                                  | <p><code>amount: string</code><br><code>contract?: 0                                                                                                                                                  | 1</code></p> | `Promise<bigint>`              | Preview shares received for deposit |
| `deposit(amount, recipient, contract?)`                              | <p><code>amount: string</code><br><code>recipient: string</code><br><code>contract?: 0                                                                                                                | 1</code></p> | `Promise<TransactionResponse>` | Deposit assets for shares           |
| `depositWithNative(amount, recipient, contract?)`                    | <p><code>amount: string</code><br><code>recipient: string</code><br><code>contract?: 0                                                                                                                | 1</code></p> | `Promise<TransactionResponse>` | Deposit native token (ETH)          |
| `depositWithExpiry(amount, recipient, expiryDate, contract?)`        | <p><code>amount: string</code><br><code>recipient: string</code><br><code>expiryDate: string</code><br><code>contract?: 0                                                                             | 1</code></p> | `Promise<TransactionResponse>` | Deposit with expiry timestamp       |
| `depositWithPermit(amount, recipient, deadline, v, r, s, contract?)` | <p><code>amount: string</code><br><code>recipient: string</code><br><code>deadline: number</code><br><code>v: number</code><br><code>r: string</code><br><code>s: string</code><br><code>contract?: 0 | 1</code></p> | `Promise<TransactionResponse>` | Deposit with EIP-2612 permit        |

**Minting**

| Method                               | Parameters                                                                             | Returns      | Description                    |                                |
| ------------------------------------ | -------------------------------------------------------------------------------------- | ------------ | ------------------------------ | ------------------------------ |
| `maxMint(account, contract?)`        | <p><code>account: string</code><br><code>contract?: 0                                  | 1</code></p> | `Promise<bigint>`              | Get max mint allowed           |
| `previewMint(amount, contract?)`     | <p><code>amount: string</code><br><code>contract?: 0                                   | 1</code></p> | `Promise<bigint>`              | Preview assets needed for mint |
| `mint(amount, recipient, contract?)` | <p><code>amount: string</code><br><code>recipient: string</code><br><code>contract?: 0 | 1</code></p> | `Promise<TransactionResponse>` | Mint exact shares              |

**Withdrawals**

| Method                                                                | Parameters                                                                                                                                              | Returns      | Description                    |                                      |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------ | ------------------------------------ |
| `maxWithdraw(account, contract?)`                                     | <p><code>account: string</code><br><code>contract?: 0                                                                                                   | 1</code></p> | `Promise<bigint>`              | Get max withdrawal allowed           |
| `previewWithdraw(amount, contract?)`                                  | <p><code>amount: string</code><br><code>contract?: 0                                                                                                    | 1</code></p> | `Promise<bigint>`              | Preview shares burned for withdrawal |
| `withdraw(amount, recipient, owner, contract?)`                       | <p><code>amount: string</code><br><code>recipient: string</code><br><code>owner: string</code><br><code>contract?: 0                                    | 1</code></p> | `Promise<TransactionResponse>` | Withdraw exact assets                |
| `withdrawWithExpiry(amount, recipient, owner, expiryDate, contract?)` | <p><code>amount: string</code><br><code>recipient: string</code><br><code>owner: string</code><br><code>expiryDate: string</code><br><code>contract?: 0 | 1</code></p> | `Promise<TransactionResponse>` | Withdraw with expiry timestamp       |

**Redemptions**

| Method                                        | Parameters                                                                                                           | Returns      | Description                    |                                        |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------ | -------------------------------------- |
| `maxRedeem(account, contract?)`               | <p><code>account: string</code><br><code>contract?: 0                                                                | 1</code></p> | `Promise<bigint>`              | Get max redemption allowed             |
| `previewRedeem(amount, contract?)`            | <p><code>amount: string</code><br><code>contract?: 0                                                                 | 1</code></p> | `Promise<bigint>`              | Preview assets received for redemption |
| `redeem(amount, recipient, owner, contract?)` | <p><code>amount: string</code><br><code>recipient: string</code><br><code>owner: string</code><br><code>contract?: 0 | 1</code></p> | `Promise<TransactionResponse>` | Redeem exact shares for assets         |

***

### Orchestrator

Scheduled operations and Balancer pool management.

| Method                         | Parameters | Returns                        | Description                      |
| ------------------------------ | ---------- | ------------------------------ | -------------------------------- |
| `executeScheduledRebalances()` | -          | `Promise<TransactionResponse>` | Execute all scheduled rebalances |
| `getTokenFactory()`            | -          | `Promise<string>`              | Get TokenFactory address         |
| `operationsSize()`             | -          | `Promise<number>`              | Get number of operations         |
| `getBalancerPools()`           | -          | `Promise<string[]>`            | Get all Balancer pool addresses  |

**Admin Methods**

| Method                                             | Parameters                                                                                             | Returns                        | Description               |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------ | ------------------------- |
| `addOperation(index, destination, data)`           | <p><code>index: number</code><br><code>destination: string</code><br><code>data: string</code></p>     | `Promise<TransactionResponse>` | Add new operation         |
| `removeOperation(index)`                           | `index: number`                                                                                        | `Promise<TransactionResponse>` | Remove operation by index |
| `setOperationEnabled(index, destination, enabled)` | <p><code>index: number</code><br><code>destination: string</code><br><code>enabled: boolean</code></p> | `Promise<TransactionResponse>` | Enable/disable operation  |
| `addBalancerPool(index, pool)`                     | <p><code>index: number</code><br><code>pool: string</code></p>                                         | `Promise<TransactionResponse>` | Add Balancer pool         |
| `removeBalancerPool(index)`                        | `index: number`                                                                                        | `Promise<TransactionResponse>` | Remove Balancer pool      |

***

### BalancerHelper

Balancer pool calculations and utilities.

| Method                                                                                                                                           | Parameters                                                                                                                                                                                                                                                                                                                                       | Returns                                                                                                               | Description                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `getExpectedAmountOut(bpoolCoreAddress, tokenInAddress, tokenOutAddress, amountIn)`                                                              | <p><code>bpoolCoreAddress: string</code><br><code>tokenInAddress: string</code><br><code>tokenOutAddress: string</code><br><code>amountIn: bigint</code></p>                                                                                                                                                                                     | `Promise<bigint>`                                                                                                     | Calculate expected output for swap                                                          |
| `calculatePoolAmountOut(bpoolEsPAddress, tokens, outAmount)`                                                                                     | <p><code>bpoolEsPAddress: string</code><br><code>tokens: string\[]</code><br><code>outAmount: bigint</code></p>                                                                                                                                                                                                                                  | `Promise<{amountsIn: bigint[], approveAmt: bigint[]}>`                                                                | Calculate amounts needed for liquidity provision                                            |
| `getDollarAmounts(underlying, fees, inputToken, outputToken, inputAmount, tokenInAddress, tokenOutAddress, underlyingAddress, bpoolCoreAddress)` | <p><code>underlying: number</code><br><code>fees: number</code><br><code>inputToken: string</code><br><code>outputToken: string</code><br><code>inputAmount: number</code><br><code>tokenInAddress: string</code><br><code>tokenOutAddress: string</code><br><code>underlyingAddress: string</code><br><code>bpoolCoreAddress: string</code></p> | `Promise<{ronDollarValue: Decimal, roffDollarValue: Decimal, underlying: Decimal, LPfee: Decimal, swapFee: Decimal}>` | Calculate dollar values and fees for token swaps. Valid tokens: "ron", "roff", "underlying" |

***

### PriceEstimates

Price discovery, NTV calculations, and slippage management.

| Method                                                 | Parameters                                                                                            | Returns                                                  | Description                           |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------------- |
| `getGasInfo()`                                         | -                                                                                                     | `Promise<any>`                                           | Get current gas price information     |
| `getBalancerPrices(chainId)`                           | `chainId: number`                                                                                     | `Promise<any>`                                           | Get all Balancer token prices         |
| `getBalancerPrice(tokenAddress, chainId)`              | <p><code>tokenAddress: string</code><br><code>chainId: number</code></p>                              | `Promise<number>`                                        | Get price for specific token          |
| `getNTVPrice(tokenIn, tokenOut, discount)`             | <p><code>tokenIn: string</code><br><code>tokenOut: string</code><br><code>discount: number</code></p> | `Promise<{outRatio: number}>`                            | Get NTV price with discount           |
| `getMaxSlippage(classicSlippage, discountNTVSlippage)` | <p><code>classicSlippage: number</code><br><code>discountNTVSlippage: number</code></p>               | `number`                                                 | Calculate maximum slippage            |
| `getSplitOutputAmounts(smartTokenX, input)`            | <p><code>smartTokenX: string</code><br><code>input: string</code></p>                                 | `Promise<{outputAmount: bigint, mgmtFeeAmount: bigint}>` | Calculate output for split operation  |
| `getRedeemOutputAmounts(smartTokenX, input)`           | <p><code>smartTokenX: string</code><br><code>input: string</code></p>                                 | `Promise<{outputAmount: bigint, mgmtFeeRefund: bigint}>` | Calculate output for redeem operation |
| `getSignedFeeData()`                                   | -                                                                                                     | `Promise<any>`                                           | Get signed fee data                   |


# TokenFactory

The Vault

## TokenFactory

[Git Source](https://github.com/RiskProtocol/core-protocol/blob/d59ee719f0b8aa5daeb239f6468bda6d3a1b56be/contracts/vaults/TokenFactory.sol)

**Inherits:** ReentrancyGuardUpgradeable, OwnableUpgradeable, UUPSUpgradeable, BaseContract

The main purposes of this contract is to act as a vault as well as it contains the shared logic used by riskON/OFF tokens.

*Acts as the vault for holding the underlying assets/tokens. Also contains shared logic used by riskON/OFF*

### State Variables

#### rebalanceElements

```solidity
RebalanceElements[] private rebalanceElements;
```

#### dailyFeeFactors

```solidity
uint256[] private dailyFeeFactors;
```

#### userRebalanceElements

```solidity
mapping(address => UserRebalanceElements) private userRebalanceElements;
```

#### REBALANCE\_INT\_MULTIPLIER

```solidity
uint256 private constant REBALANCE_INT_MULTIPLIER = 10 ** 18;
```

#### smartTokenArray

```solidity
SmartToken[] private smartTokenArray;
```

#### lastRebalanceCount

This mapping keeps track of the last rebalance applied to a user/address

```solidity
mapping(address => uint256) private lastRebalanceCount;
```

#### lastdailyFFcount

```solidity
mapping(address => uint256) private lastdailyFFcount;
```

#### baseToken

This is the instance of the underlying Token

```solidity
IERC20Update private baseToken;
```

#### baseTokenDecimals

The number of decimals of the underlying Asset/Token

```solidity
uint8 private baseTokenDecimals;
```

#### interval

The rebalance interval in seconds

```solidity
uint256 private interval;
```

#### lastTimeStamp

The timestamp of the last rebalance

```solidity
uint256 private lastTimeStamp;
```

#### smartTokenInitialized

This boolean keeps track if the smart tokens(RiskON/OFF) have already been initialized in the system

```solidity
bool private smartTokenInitialized;
```

#### signers

This is the signers address of RP api's that generate encoded params for rebalance

```solidity
mapping(address => bool) private signers;
```

#### FFinterval

This is used by the feefactors method to calculate the fees

```solidity
uint256 private FFinterval;
```

#### FFLastTimeStamp

```solidity
uint256 private FFLastTimeStamp;
```

#### sequenceNumberApplied

This keeps track of the 'sequenceNumber' of a rebalance which helps

```solidity
mapping(uint256 => bool) private sequenceNumberApplied;
```

#### managementFeesRate

```solidity
uint256 private managementFeesRate;
```

#### managementFeeEnabled

```solidity
bool private managementFeeEnabled;
```

#### lastRebalanceFees

```solidity
uint256 private lastRebalanceFees;
```

#### treasuryWallet

```solidity
address private treasuryWallet;
```

#### orchestrator

```solidity
address private orchestrator;
```

#### isNativeToken

```solidity
bool private isNativeToken;
```

#### premiumPercentage

```solidity
uint16 private premiumPercentage;
```

#### premiumCharged

```solidity
uint256 private premiumCharged;
```

#### scheduledRebalances

*A mapping to hold the scheduled rebalances. This helps in storing rebalances in the order they are scheduled till they are all executed*

```solidity
mapping(uint256 => Shared.ScheduledRebalance) private scheduledRebalances;
```

#### scheduledRebalancesLength

```solidity
uint256 private scheduledRebalancesLength;
```

#### nextSequenceNumber

*A counter to generate a unique sequence number for each rebalance. This ensures that rebalances are executed in the order they are scheduled.*

```solidity
uint256 private nextSequenceNumber;
```

#### period

```solidity
uint256 private period;
```

#### withdrawLimit

```solidity
uint256 private withdrawLimit;
```

#### depositLimit

```solidity
uint256 private depositLimit;
```

#### hasWithdrawLimit

```solidity
bool private hasWithdrawLimit;
```

#### hasDepositLimit

```solidity
bool private hasDepositLimit;
```

#### currentWithdrawPeriodEnd

```solidity
mapping(address => uint256) private currentWithdrawPeriodEnd;
```

#### currentWithdrawPeriodAmount

```solidity
mapping(address => uint256) private currentWithdrawPeriodAmount;
```

#### currentDepositPeriodEnd

```solidity
mapping(address => uint256) private currentDepositPeriodEnd;
```

#### currentDepositPeriodAmount

```solidity
mapping(address => uint256) private currentDepositPeriodAmount;
```

#### redemptionFee

```solidity
uint256 private redemptionFee;
```

### Functions

#### onlySmartTokens

Ensures the caller is one of the SmartTokens(RiskOn/Off).

*This modifier checks if the caller is either smartTokenArray\[0] or smartTokenArray\[1]. If not, it reverts with a custom error message.*

```solidity
modifier onlySmartTokens();
```

#### onlyOrchestrator

```solidity
modifier onlyOrchestrator();
```

#### onlyIntializedOnce

```solidity
modifier onlyIntializedOnce();
```

#### constructor

**Note:** oz-upgrades-unsafe-allow: constructor

```solidity
constructor();
```

#### initialize

Initializes(replacement for the constructor) the Vault (TokenFactory) contract with specified params

*This function sets up the initial state of the TokenFactory contract. Callable only once.*

```solidity
function initialize(
    IERC20Update baseTokenAddress,
    uint256 rebalanceInterval,
    uint256 ffInterval,
    address sanctionsContract_,
    address signersAddress_,
    address owner_,
    uint256 withdrawLimit_,
    uint256 depositLimit_,
    uint256 limitPeriod_,
    bool isNativeToken_
) public initializer;
```

**Parameters**

| Name                 | Type           | Description                                                                                 |
| -------------------- | -------------- | ------------------------------------------------------------------------------------------- |
| `baseTokenAddress`   | `IERC20Update` | The address of the underlying token/asset                                                   |
| `rebalanceInterval`  | `uint256`      | The interval (in seconds) at which natural rebalances are scheduled.                        |
| `ffInterval`         | `uint256`      |                                                                                             |
| `sanctionsContract_` | `address`      | The address of the sanctions contract(chainalysis contract) to verify blacklisted addresses |
| `signersAddress_`    | `address`      | The address of the signer ( RP Api's) which signed the rebalance data                       |
| `owner_`             | `address`      |                                                                                             |
| `withdrawLimit_`     | `uint256`      |                                                                                             |
| `depositLimit_`      | `uint256`      |                                                                                             |
| `limitPeriod_`       | `uint256`      |                                                                                             |
| `isNativeToken_`     | `bool`         |                                                                                             |

#### \_authorizeUpgrade

Authorizes an upgrade to a new contract implementation.

*This function can only be called by the contract owner. It overrides the `_authorizeUpgrade` function from the `UUPSUpgradeable` contract to include the `onlyOwner` modifier, ensuring only the owner can authorize upgrades.*

```solidity
function _authorizeUpgrade(address) internal override(UUPSUpgradeable) onlyOwner;
```

#### initializeSMART

Initializes the smart tokens associated with this TokenFactory. renaming this method to avoid conflicts with upgradable initialize

*This function can only be called once, and only by the contract owner.*

```solidity
function initializeSMART(SmartToken token1, SmartToken token2) external onlyOwner onlyIntializedOnce;
```

**Parameters**

| Name     | Type         | Description            |
| -------- | ------------ | ---------------------- |
| `token1` | `SmartToken` | The first smart token  |
| `token2` | `SmartToken` | The second smart token |

#### initializeOrchestrator

```solidity
function initializeOrchestrator(address orchestrator_) external onlyOwner;
```

#### \_tryGetAssetDecimals

Attempts to fetch the decimals of underlying token

*This function uses a static call to query the decimals from the asset. If the call fails or the returned data is invalid, it defaults to 0.*

```solidity
function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool, uint8);
```

**Parameters**

| Name     | Type     | Description                         |
| -------- | -------- | ----------------------------------- |
| `asset_` | `IERC20` | The address of the underlying token |

**Returns**

| Name     | Type    | Description                                                                                                         |
| -------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `bool`  | A return vaule containing a boolean indicating success and the decimals of the token. or false if it failed somehow |
| `<none>` | `uint8` |                                                                                                                     |

#### decimals

Fetches the decimal value of the underlying token

*This function returns the value of decimals that was set in the 'initialize' method*

```solidity
function decimals() public view virtual returns (uint8);
```

**Returns**

| Name     | Type    | Description                                    |
| -------- | ------- | ---------------------------------------------- |
| `<none>` | `uint8` | The number of decimals of the underlying token |

#### getBaseToken

Retrieves the instance of the underlying token contract

*This function provides a way to access the instance of the underlying contract*

```solidity
function getBaseToken() public view virtual returns (IERC20Update);
```

**Returns**

| Name     | Type           | Description                             |
| -------- | -------------- | --------------------------------------- |
| `<none>` | `IERC20Update` | The instance of the underlying contract |

#### maxAmountToWithdraw

Returns the maximum amount of assets the owner can withdraw.

*This function compares the balance of both smart tokens(RiskON/OFF) for the owner and returns the balance of the smart token with the lesser amount.*

```solidity
function maxAmountToWithdraw(address owner_) public view virtual returns (uint256);
```

**Parameters**

| Name     | Type      | Description              |
| -------- | --------- | ------------------------ |
| `owner_` | `address` | The address of the owner |

**Returns**

| Name     | Type      | Description                                                    |
| -------- | --------- | -------------------------------------------------------------- |
| `<none>` | `uint256` | The maximum amount of assets the specified owner can withdraw. |

#### maxSharesOwned

Determines the maximum amount of shares owned by the owner

*This function compares the balance of both smart tokens(RiskON/OFF) for the owner and returns the balance of the smart token with the greater amount.*

```solidity
function maxSharesOwned(address owner_) public view virtual returns (uint256);
```

**Parameters**

| Name     | Type      | Description              |
| -------- | --------- | ------------------------ |
| `owner_` | `address` | The address of the owner |

**Returns**

| Name     | Type      | Description                                                |
| -------- | --------- | ---------------------------------------------------------- |
| `<none>` | `uint256` | The maximum amount of shares owned by the specified owner. |

#### \_deposit

Deposit/mint common workflow, deposit underlying tokens, mints new shares(RiskON/OFF) to the receiver, and also charges management fees

*Deposit/mint common workflow.*

*This function can only be called by the smart tokens and requires the caller and receiver to not be sanctioned.*

```solidity
function _deposit(address caller, address receiver, uint256 assets, uint256 shares)
    external
    virtual
    onlyNotSanctioned(caller)
    onlyNotSanctioned(receiver)
    onlySmartTokens;
```

**Parameters**

| Name       | Type      | Description                                               |
| ---------- | --------- | --------------------------------------------------------- |
| `caller`   | `address` | The address of depositor                                  |
| `receiver` | `address` | The address of receiver                                   |
| `assets`   | `uint256` | The amount of underlying tokens being deposited.          |
| `shares`   | `uint256` | The amount of shares(RiskON/OFF) to mint to the receiver. |

#### \_withdraw

Withdraw/redeem common workflow. Handles the withdrawal of underlying token. burns shares(RiskON/OFF) from the caller, and refund any management fees

*This function can only be called by the smart tokens and requires the caller and receiver to not be sanctioned.*

```solidity
function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares)
    external
    virtual
    onlyNotSanctioned(caller)
    onlyNotSanctioned(receiver)
    onlySmartTokens;
```

**Parameters**

| Name       | Type      | Description                                               |
| ---------- | --------- | --------------------------------------------------------- |
| `caller`   | `address` | The address withdrawing.                                  |
| `receiver` | `address` | The address receiving the underlying token.               |
| `owner`    | `address` | The owner of the shares.                                  |
| `assets`   | `uint256` | The amount of underlying Token being withdrawn.           |
| `shares`   | `uint256` | The amount of shares(RiskON/OFF) to burn from the caller. |

#### getUserRecords

```solidity
function getUserRecords(address sender, address recipient) external view onlySmartTokens returns (uint256[4] memory);
```

#### transferRecords

```solidity
function transferRecords(
    address sender,
    address recipient,
    bool tokenType,
    uint256 amount,
    uint256 prevBalXsender,
    uint256 prevBalYsender,
    uint256 prevBalXrecipient,
    uint256 prevBalYrecipient
) external onlySmartTokens;
```

#### updateRecord

```solidity
function updateRecord(bool tokenType, address account, uint256 amount) external onlySmartTokens;
```

#### updateRecord

```solidity
function updateRecord(bool tokenType, uint256 amount) external onlySmartTokens;
```

#### factoryMint

Mints the specified amount of Shares(RiskON/OFF) to the receiver

*It first previews the minting process to get the amount of Shares(RiskON/OFF)that will be minted, and then performs the actual minting.*

```solidity
function factoryMint(uint256 smartTokenIndex, address receiver, uint256 amount) private;
```

**Parameters**

| Name              | Type      | Description                                          |
| ----------------- | --------- | ---------------------------------------------------- |
| `smartTokenIndex` | `uint256` | The index of the smart token in the smartTokenArray. |
| `receiver`        | `address` | The address of the receiver                          |
| `amount`          | `uint256` | The amount of Shares(RiskON/OFF) to mint.            |

#### factoryBurn

Burns the specified amount of Shares(either of RiskON/OFF)from the owner

*It calls the `burn` function on the smart token contract*

```solidity
function factoryBurn(uint256 smartTokenIndex, address owner_, uint256 amount) private;
```

**Parameters**

| Name              | Type      | Description                                            |
| ----------------- | --------- | ------------------------------------------------------ |
| `smartTokenIndex` | `uint256` | The index of the smart token in the `smartTokenArray`. |
| `owner_`          | `address` | The address of the owner                               |
| `amount`          | `uint256` | The amount of Shares(either of RiskON/OFF) to burn.    |

#### factoryTreasuryTransfer

```solidity
function factoryTreasuryTransfer(uint256 amount) private;
```

#### factoryBalanceAdjust

```solidity
function factoryBalanceAdjust(address account, uint256 amountX, uint256 amountY) private;
```

#### executeRebalance

Executes a rebalance based on the provided encoded data and signature.

*This function validates the rebalance call, schedules it, and possibly triggers a rebalance if the sequence is in order. It first verifies the signature of the rebalance params with the signer's public key. Then we verify if the sequence number is aligned and not already used. Then we push the rebalance params into an array of scheduled rebalances. Finally, if there is no gaps between the previous rebalance'sequence number, we execute this rebalance This function can only be called when rebalance is not stopped with the `stopRebalance` modifier.*

```solidity
function executeRebalance(bytes memory encodedData, bytes memory signature) external stopRebalance onlyOrchestrator;
```

**Parameters**

| Name          | Type    | Description                                                                                                                          |
| ------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `encodedData` | `bytes` | The encoded data containing the sequence number, the boolean value for natural rebalance and the price of underlying and smartTokenX |
| `signature`   | `bytes` | The signature of the encoded data to verify its authenticity.                                                                        |

#### executeScheduledRebalances

Executes scheduled rebalances pending in the queue

*This function is called when the scheduled rebalance queue had more than 5 entries only 5 will be executed and the rest will be left in the queue*

```solidity
function executeScheduledRebalances() external stopRebalance onlyOrchestrator;
```

#### chargeFees

Charges the management fees

*This function is responsible for charging the fees of the whole universe and related functionalities. We charge the fees on a daily Basis/ each FFinterval*

```solidity
function chargeFees() private;
```

#### rebalance

Handles the actual rebalancing mechanism.

*This function processes up to 5 scheduled rebalances per call. Different factors that will help calculating user balances are calculated here using the rebalance params.*

```solidity
function rebalance() private;
```

#### updateFeeFactor

```solidity
function updateFeeFactor() private;
```

#### dailyFeeFactorsUpdate

```solidity
function dailyFeeFactorsUpdate() public;
```

#### applyFF

should apply this to users before any interaction with the contracts

```solidity
function applyFF(address owner) public;
```

#### updateUserLastFFCount

```solidity
function updateUserLastFFCount(address owner_) public;
```

#### FFCheck

```solidity
function FFCheck(address user) private;
```

#### applyRebalance

Applies rebalance to an account

*This function adjusts the balance of smart tokens(RiskON/RiskOFF) according to the rollOverValue. This function can only be called when rebalance is stopped. It also calculates and applies management fees.*

```solidity
function applyRebalance(address owner_) public stopRebalance;
```

**Parameters**

| Name     | Type      | Description                                                        |
| -------- | --------- | ------------------------------------------------------------------ |
| `owner_` | `address` | The address of the account to which the rebalance will be applied. |

#### underlyingTransfer

```solidity
function underlyingTransfer(address receiver_, uint256 amount_) external onlySmartTokens;
```

#### underlyingReturn

```solidity
function underlyingReturn(address sender_, uint256 amount_, uint256 premium) external onlySmartTokens;
```

#### calculateRollOverValue

Calculates the rollover value(Units of RiskON/OFF) for an account

*This function calculates the net balance(Units of RiskON/OFF) of a user after rebalance and management fees are applied.*

```solidity
function calculateRollOverValue(address owner_) public view returns (uint256, uint256);
```

**Parameters**

| Name     | Type      | Description              |
| -------- | --------- | ------------------------ |
| `owner_` | `address` | The address of the owner |

**Returns**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `<none>` | `uint256` | The calculated roll over value. |
| `<none>` | `uint256` |                                 |

#### updateUserLastRebalanceCount

Updates the last rebalance count of a user.

*This function sets the last rebalance count for a user if their unscaled balances for both smart tokens(RiskON/RiskOFF) are zero. We may use this in cases where a receiever is new to the system*

```solidity
function updateUserLastRebalanceCount(address owner_) public;
```

**Parameters**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `owner_` | `address` | The address of the user |

#### verifyAndDecode

Verifies the provided signature and decodes the encoded data into `ScheduledRebalance` struct.

*It recovers the address from the Ethereum signed message hash and the provided `signature`. If the recovered address doesn't match the `signersAddress`, it reverts the transaction. If the signature is valid, it decodes the `encodedData` into a `ScheduledRebalance` struct and returns it.*

```solidity
function verifyAndDecode(bytes memory signature, bytes memory encodedData)
    public
    view
    returns (Shared.ScheduledRebalance memory);
```

**Parameters**

| Name          | Type    | Description                                                |
| ------------- | ------- | ---------------------------------------------------------- |
| `signature`   | `bytes` | The signature to be verified.                              |
| `encodedData` | `bytes` | The data to be decoded into a `ScheduledRebalance` struct. |

**Returns**

| Name     | Type                        | Description                                                     |
| -------- | --------------------------- | --------------------------------------------------------------- |
| `<none>` | `Shared.ScheduledRebalance` | data A `ScheduledRebalance` struct containing the decoded data. |

#### setSignersAddress

Update the address authorized to sign rebalance transactions.

*This function can only be called by the owner of the contract. It updates the `signersAddress` address with the provided `addr` address.*

```solidity
function setSignersAddress(address addr) external onlyOwner;
```

**Parameters**

| Name   | Type      | Description     |
| ------ | --------- | --------------- |
| `addr` | `address` | The new address |

#### removeSigner

```solidity
function removeSigner(address signer) external onlyOwner;
```

#### setManagementFeeRate

Updates the rate of management fees.

*It updates the `managementFeesRate` state variable with the provided `rate` value, if the rate is within a valid range, otherwise, it reverts the transaction. The rate is in terms of percentage per day scaling factor is 10E18 Example 5% per day = 0.05*10E18\*

```solidity
function setManagementFeeRate(uint256 rate) external onlyOwner returns (bool);
```

**Parameters**

| Name   | Type      | Description                                       |
| ------ | --------- | ------------------------------------------------- |
| `rate` | `uint256` | The new rate of management fees. It is DAILY RATE |

**Returns**

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| `<none>` | `bool` | A boolean value |

#### setManagementFeeState

Toggles the state of management fee collection.

*This function can only be called by the contract owner. It either enables or disables the management fee collection*

```solidity
function setManagementFeeState(bool state) external onlyOwner returns (bool);
```

**Parameters**

| Name    | Type   | Description                                 |
| ------- | ------ | ------------------------------------------- |
| `state` | `bool` | The new state of management fee collection. |

**Returns**

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| `<none>` | `bool` | A boolean value |

#### setTreasuryWallet

```solidity
function setTreasuryWallet(address wallet) external onlyOwner returns (bool);
```

#### calculateManagementFee

Calculates the management fee for a given amount over a particular time span.

*It computes the management fee either using the default management fee rate or a provided fee rate. This function can be used both for deposit and withdrawal scenarios.*

```solidity
function calculateManagementFee(uint256 amount, uint256 mgmtFee) public view returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                                    |
| --------- | --------- | -------------------------------------------------------------- |
| `amount`  | `uint256` | The amount of RiskON/OFF to calculate the fee against.         |
| `mgmtFee` | `uint256` | The management fee rate to use if `isDefault` is set to false. |

**Returns**

| Name     | Type      | Description                            |
| -------- | --------- | -------------------------------------- |
| `<none>` | `uint256` | userFees The calculated management fee |

#### rebalanceCheck

Checks if a user is an existing user and applies user rebalance when needed.

*This function is triggered to ensure a user's balances are updated with any rebalances that have occurred since their last interaction with the contract.*

```solidity
function rebalanceCheck(address user) private;
```

**Parameters**

| Name   | Type      | Description             |
| ------ | --------- | ----------------------- |
| `user` | `address` | The address of the user |

#### removeRebalance

Removes a rebalance entry from the `scheduledRebalances` mapping at the given sequence number.

*It deletes the entry at the given sequence number and decrements the `scheduledRebalancesLength` variable. It is also guarded by 'nonReentrant' modifier.*

```solidity
function removeRebalance(uint256 sequenceNumber) private nonReentrant;
```

**Parameters**

| Name             | Type      | Description                                                        |
| ---------------- | --------- | ------------------------------------------------------------------ |
| `sequenceNumber` | `uint256` | The sequenceNumber of the `scheduledRebalances` mapping to remove. |

#### isValidSigner

Verifies if a signer is valid

*Verifies if a signer is valid*

```solidity
function isValidSigner(address addr) public view returns (bool);
```

**Parameters**

| Name   | Type      | Description               |
| ------ | --------- | ------------------------- |
| `addr` | `address` | The address of the signer |

**Returns**

| Name     | Type   | Description             |
| -------- | ------ | ----------------------- |
| `<none>` | `bool` | true if signer is valid |

#### withdrawLimitMod

ratelimits

```solidity
function withdrawLimitMod(uint256 amount) external onlySmartTokens returns (bool);
```

#### depositLimitMod

```solidity
function depositLimitMod(uint256 amount) external onlySmartTokens returns (bool);
```

#### updatePeriod

```solidity
function updatePeriod(
    address user,
    mapping(address => uint256) storage currentPeriodEnd,
    mapping(address => uint256) storage currentPeriodAmount
) internal;
```

#### updateWithdrawLimit

```solidity
function updateWithdrawLimit(uint256 newLimit) external onlyOwner;
```

#### updateDepositLimit

```solidity
function updateDepositLimit(uint256 newLimit) external onlyOwner;
```

#### updateLimitPeriod

```solidity
function updateLimitPeriod(uint256 newPeriod) external onlyOwner;
```

#### toggleWithdrawLimit

```solidity
function toggleWithdrawLimit() external onlyOwner;
```

#### toggleDepositLimit

```solidity
function toggleDepositLimit() external onlyOwner;
```

#### setPremiumPercentage

```solidity
function setPremiumPercentage(uint16 percentage) external onlyOwner;
```

#### drainFlashloanPremiums

```solidity
function drainFlashloanPremiums(address receiver) external onlyOwner;
```

#### setRedemptionFee

```solidity
function setRedemptionFee(uint256 fee) external onlyOwner;
```

#### updateLastRebalanceTimeStamp

```solidity
function updateLastRebalanceTimeStamp(uint256 newTimeStamp) external onlyOwner;
```

#### getScheduledRebalances

Retrieves the `scheduledRebalance` struct at the given sequence number.

*This function is a getter for a single `scheduledRebalance` struct.*

```solidity
function getScheduledRebalances(uint256 sequenceNumber) public view returns (Shared.ScheduledRebalance memory);
```

**Parameters**

| Name             | Type      | Description                                                           |
| ---------------- | --------- | --------------------------------------------------------------------- |
| `sequenceNumber` | `uint256` | The sequence number of the `scheduledRebalances` mapping to retrieve. |

**Returns**

| Name     | Type                        | Description                                                   |
| -------- | --------------------------- | ------------------------------------------------------------- |
| `<none>` | `Shared.ScheduledRebalance` | The `scheduledRebalance` struct at the given sequence number. |

#### getNextSequenceNumber

Retrieves the nextSequenceNumber

*This function is a getter for the `nextSequenceNumber` variable.*

```solidity
function getNextSequenceNumber() public view returns (uint256);
```

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `uint256` | The anextSequenceNumber |

#### getLastTimeStamp

Retrieves the lastTimeStamp

*This function is a getter for the `lastTimeStamp` variable.*

```solidity
function getLastTimeStamp() external view onlyOwner returns (uint256);
```

**Returns**

| Name     | Type      | Description       |
| -------- | --------- | ----------------- |
| `<none>` | `uint256` | The lastTimeStamp |

#### getManagementFeeRate

```solidity
function getManagementFeeRate() public view returns (uint256);
```

#### getManagementFeeState

Retrieves the managementFeeEnabled

*This function is a getter for the `managementFeeEnabled` variable.*

```solidity
function getManagementFeeState() public view returns (bool);
```

**Returns**

| Name     | Type   | Description              |
| -------- | ------ | ------------------------ |
| `<none>` | `bool` | The managementFeeEnabled |

#### getRebalanceNumber

```solidity
function getRebalanceNumber() public view returns (uint256);
```

#### getUserLastRebalanceCount

```solidity
function getUserLastRebalanceCount(address userAddress) public view returns (uint256);
```

#### getSmartTokenAddress

Retrieves the interval

*This function is a getter for the `interval` variable.*

```solidity
function getSmartTokenAddress(uint8 index) public view returns (SmartToken);
```

**Parameters**

| Name    | Type    | Description                                           |
| ------- | ------- | ----------------------------------------------------- |
| `index` | `uint8` | The index of the SmartToken in the `smartTokenArray`. |

**Returns**

| Name     | Type         | Description  |
| -------- | ------------ | ------------ |
| `<none>` | `SmartToken` | The interval |

#### getTreasuryAddress

```solidity
function getTreasuryAddress() public view returns (address);
```

#### getInterval

Retrieves the interval

*This function is a getter for the `interval` variable.*

```solidity
function getInterval() public view returns (uint256);
```

**Returns**

| Name     | Type      | Description  |
| -------- | --------- | ------------ |
| `<none>` | `uint256` | The interval |

#### insufficientUnderlying

Validates if the amount of underlying locked in the token factory is

*This function is used the smartoken modifer*

```solidity
function insufficientUnderlying() external view returns (bool);
```

**Returns**

| Name     | Type   | Description                |
| -------- | ------ | -------------------------- |
| `<none>` | `bool` | true if underlying is less |

#### withdrawLimitStatus

```solidity
function withdrawLimitStatus() public view returns (bool);
```

#### depositLimitStatus

```solidity
function depositLimitStatus() public view returns (bool);
```

#### getWithdrawLimit

```solidity
function getWithdrawLimit() public view returns (uint256);
```

#### getDepositLimit

```solidity
function getDepositLimit() public view returns (uint256);
```

#### getLimitPeriod

```solidity
function getLimitPeriod() public view returns (uint256);
```

#### getUserLimitPerPeriod

```solidity
function getUserLimitPerPeriod(address user, bool isWithdraw)
    public
    view
    returns (uint256 periodEnd, uint256 currentAmount);
```

#### getLastFFTimeStamp

Getters for the new fees mechanisms

```solidity
function getLastFFTimeStamp() external view returns (uint256);
```

#### getDailyFeeFactorNumber

```solidity
function getDailyFeeFactorNumber() public view returns (uint256);
```

#### getUserLastFFCount

```solidity
function getUserLastFFCount(address userAddress) public view returns (uint256);
```

#### getIsNativeToken

```solidity
function getIsNativeToken() public view returns (bool);
```

#### getFlashloanPremium

```solidity
function getFlashloanPremium() public view returns (uint16);
```

#### getAccumulatedFlashLoanPremium

```solidity
function getAccumulatedFlashLoanPremium() public view returns (uint256);
```

#### getRedemptionFee

```solidity
function getRedemptionFee() external view returns (uint256);
```

### Events

#### RebalanceApplied

```solidity
event RebalanceApplied(address userAddress, uint256 rebalanceCount);
```

#### Rebalance

```solidity
event Rebalance(uint256 rebalanceCount);
```

#### Deposit

```solidity
event Deposit(address caller, address receiver, uint256 assets, uint256 shares);
```

#### Withdraw

```solidity
event Withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares);
```

#### PremiumDrained

```solidity
event PremiumDrained(address receiver, uint256 amount);
```

#### WithdrawLimitToggled

```solidity
event WithdrawLimitToggled(bool enabled);
```

#### DepositLimitToggled

```solidity
event DepositLimitToggled(bool enabled);
```

### Errors

#### TokenFactory\_\_MethodNotAllowed

```solidity
error TokenFactory__MethodNotAllowed();
```

#### TokenFactory\_\_InvalidDivision

```solidity
error TokenFactory__InvalidDivision();
```

#### TokenFactory\_\_InvalidRebalanceParams

```solidity
error TokenFactory__InvalidRebalanceParams();
```

#### TokenFactory\_\_InvalidSequenceNumber

```solidity
error TokenFactory__InvalidSequenceNumber();
```

#### TokenFactory\_\_InvalidNaturalRebalance

```solidity
error TokenFactory__InvalidNaturalRebalance();
```

#### TokenFactory\_\_AlreadyInitialized

```solidity
error TokenFactory__AlreadyInitialized();
```

#### TokenFactory\_\_InvalidSignature

```solidity
error TokenFactory__InvalidSignature();
```

#### TokenFactory\_\_InvalidSignatureLength

```solidity
error TokenFactory__InvalidSignatureLength();
```

#### TokenFactory\_\_InvalidManagementFees

```solidity
error TokenFactory__InvalidManagementFees();
```

#### TokenFactory\_\_SmartTokenArrayOutOfBounds

```solidity
error TokenFactory__SmartTokenArrayOutOfBounds();
```

#### TokenFactory\_\_NoPremiumsToDrain

```solidity
error TokenFactory__NoPremiumsToDrain();
```

### Structs

#### RebalanceElements

```solidity
struct RebalanceElements {
    uint256 BalanceFactorXY;
    uint256 BalanceFactorUx;
    uint256 BalanceFactorUy;
}
```

#### UserRebalanceElements

```solidity
struct UserRebalanceElements {
    uint256 netX;
    uint256 netY;
    uint256 Ux;
    uint256 Uy;
}
```


# SmartTokens

The rON/rOFF

## SmartToken

[Git Source](https://github.com/RiskProtocol/core-protocol/blob/d59ee719f0b8aa5daeb239f6468bda6d3a1b56be/contracts/vaults/SmartToken.sol)

**Inherits:** Initializable, UUPSUpgradeable, OwnableUpgradeable, ERC20Upgradeable, ERC20PermitUpgradeable, BaseContract, IERC4626Upgradeable, ReentrancyGuardUpgradeable, FlashloanSpecifics

*This is a rebalancing token, part of Risk Protocol's system The same contract is used by both RiskON and RiskOFF Whenever a user deposit a unit of underlying in the Vault(TokenFactory), the user is expected to recieve a unit of both RiskON and RiskOFF. At every rebalance operation, the user RiskOn/OFF balances will be aligned with respect to the rebalance math.*

### State Variables

#### tokenFactory

The tokenFactory instance

```solidity
TokenFactory private tokenFactory;
```

#### underlyingToken

The underlyingToken instance

```solidity
IERC20Update private underlyingToken;
```

#### isX

```solidity
bool private isX;
```

#### isNativeToken

```solidity
bool private isNativeToken;
```

#### weth

```solidity
IWETH private weth;
```

#### premiumDenominator

```solidity
uint16 private constant premiumDenominator = 10000;
```

### Functions

#### onlyTokenFactory

*Ensures that the function is only callable by the TokenFactory contract. Calls the helper function `_onlyTokenFactory` to check the caller.*

```solidity
modifier onlyTokenFactory();
```

#### onlyAssetOwner

*Ensures that the function is only callable by the token owner/holder. Calls the helper function `_onlyAssetOwner` to check the caller against the provided token owner/holder address.*

```solidity
modifier onlyAssetOwner(address assetOwner);
```

**Parameters**

| Name         | Type      | Description                            |
| ------------ | --------- | -------------------------------------- |
| `assetOwner` | `address` | The address of the token owner/holder. |

#### validateDepositAmount

*Validates the deposit amount to ensure it is not 0 or more than the receiver can get. Calls the helper function `_validateDepositAmount` to check the deposit amount and receiver.*

```solidity
modifier validateDepositAmount(uint256 assets, address receiver);
```

**Parameters**

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `assets`   | `uint256` | The amount of token to deposit.    |
| `receiver` | `address` | The address receiving the deposit. |

#### insufficientUnderlying

*Validates if the underlying locked is always >= than the total supply of riskON/OFF reverts if not*

```solidity
modifier insufficientUnderlying();
```

#### depositLimitHit

*Validates if the user has hit the periodic deposit limit prevents the user from depositing more if hit*

```solidity
modifier depositLimitHit(uint256 amount);
```

**Parameters**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `amount` | `uint256` | The amount of token to deposit. |

#### withdrawLimitHit

*Validates if the user has hit the periodic withdraw limit prevents the user from withdrawing more if hit*

```solidity
modifier withdrawLimitHit(uint256 amount);
```

**Parameters**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `amount` | `uint256` | The amount of token to withdraw. |

#### dailyFFUpdate

```solidity
modifier dailyFFUpdate();
```

#### expiryDateCheck

```solidity
modifier expiryDateCheck(uint256 expiryDate);
```

#### constructor

**Note:** oz-upgrades-unsafe-allow: constructor

```solidity
constructor();
```

#### initialize

Initializes(replacement for the constructor) the SmartToken contract with specified parameters.

*This function sets up the initial state of the SmartToken contract. Callable only once. It initializes inherited contracts and sets the initial values for `tokenFactory` and `underlyingToken`.*

```solidity
function initialize(
    string memory tokenName,
    string memory tokenSymbol,
    address factoryAddress,
    address sanctionsContract_,
    bool isX_,
    address owner_
) public initializer;
```

**Parameters**

| Name                 | Type      | Description                                |
| -------------------- | --------- | ------------------------------------------ |
| `tokenName`          | `string`  | The name of the token.                     |
| `tokenSymbol`        | `string`  | The symbol of the token.                   |
| `factoryAddress`     | `address` | The address of the TokenFactory contract.  |
| `sanctionsContract_` | `address` | The address of the SanctionsList contract. |
| `isX_`               | `bool`    |                                            |
| `owner_`             | `address` |                                            |

#### receive

```solidity
receive() external payable;
```

#### drain

method to drain contracts of any ethers

*This function can only be called by the contract owner.*

```solidity
function drain(address receiver) external onlyOwner;
```

**Parameters**

| Name       | Type      | Description                                              |
| ---------- | --------- | -------------------------------------------------------- |
| `receiver` | `address` | The address of the account that will receive the ethers. |

#### \_authorizeUpgrade

Authorizes an upgrade to a new contract implementation.

*This function can only be called by the contract owner. It overrides the `_authorizeUpgrade` function from the `UUPSUpgradeable` contract to include the `onlyOwner` modifier, ensuring only the owner can authorize upgrades.*

```solidity
function _authorizeUpgrade(address) internal override onlyOwner;
```

#### mintAsset

Mints the specified amount of tokens to the receiver.

*This function can only be called by the TokenFactory contract.*

```solidity
function mintAsset(address receiver, uint256 amount) external onlyTokenFactory;
```

**Parameters**

| Name       | Type      | Description                                                     |
| ---------- | --------- | --------------------------------------------------------------- |
| `receiver` | `address` | The address of the account that will receive the minted tokens. |
| `amount`   | `uint256` | The amount of tokens to mint.                                   |

#### burn

Burns the specified amount of tokens from the account.

*This function can only be called by the TokenFactory contract.*

```solidity
function burn(address account, uint256 amount) external onlyTokenFactory;
```

**Parameters**

| Name      | Type      | Description                                                  |
| --------- | --------- | ------------------------------------------------------------ |
| `account` | `address` | The address of the account from which tokens will be burned. |
| `amount`  | `uint256` | The amount of tokens to burn.                                |

#### transfer

Transfers the specified amount of tokens to the specified recipient.

*Overrides the `transfer` function from `ERC20Upgradeable` and `IERC20Upgradeable` contracts. If the sender or receiver has a pending rebalance, it is handled before the transfer. This function can only be called when transfers are not stopped, and neither the sender nor the recipient are on the sanctions list.*

```solidity
function transfer(address recipient, uint256 amount)
    public
    override(ERC20Upgradeable, IERC20Upgradeable)
    stopTransfer
    insufficientUnderlying
    onlyNotSanctioned(recipient)
    onlyNotSanctioned(_msgSender())
    dailyFFUpdate
    returns (bool);
```

**Parameters**

| Name        | Type      | Description                                      |
| ----------- | --------- | ------------------------------------------------ |
| `recipient` | `address` | The address to which tokens will be transferred. |
| `amount`    | `uint256` | The amount of tokens to transfer.                |

**Returns**

| Name     | Type   | Description                        |
| -------- | ------ | ---------------------------------- |
| `<none>` | `bool` | Always return true unless reverted |

#### smartTreasuryTransfer

```solidity
function smartTreasuryTransfer(address treasuryAddress, uint256 amount) external onlyTokenFactory;
```

#### smartBalanceAdjust

```solidity
function smartBalanceAdjust(address account, uint256 amount) external onlyTokenFactory;
```

#### balanceOf

Returns the balance of the specified account

*Overrides the `balanceOf` function from the inherited `ERC20Upgradeable` and `IERC20Upgradeable` contracts. If the account has a pending rebalance, the function calculates the calculated balance post rebalance using the 'calculateRollOverValue' method. Otherwise, it returns the erc20 balance using `unScaledbalanceOf` method.*

```solidity
function balanceOf(address account) public view override(ERC20Upgradeable, IERC20Upgradeable) returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                                 |
| --------- | --------- | ----------------------------------------------------------- |
| `account` | `address` | The address of the account whose balance will be retrieved. |

**Returns**

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `<none>` | `uint256` | The balance of the specified account. |

#### unScaledbalanceOf

Returns the unscaled(unaffected by pending rebalances) balance of the specified account.

*This function returns the ERC20 balance(unaffected by pending rebalances) of the account.*

```solidity
function unScaledbalanceOf(address account) public view returns (uint256);
```

**Parameters**

| Name      | Type      | Description                 |
| --------- | --------- | --------------------------- |
| `account` | `address` | The address of the account. |

**Returns**

| Name     | Type      | Description                                                                      |
| -------- | --------- | -------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The unscaled(unaffected by pending rebalances) balance of the specified account. |

#### hasPendingRebalance

Checks if the specified account has a pending rebalance.

*Compares the account's last rebalance count with the current scalingfactor length to determine if a rebalance is pending.*

```solidity
function hasPendingRebalance(address account) public view returns (bool);
```

**Parameters**

| Name      | Type      | Description                |
| --------- | --------- | -------------------------- |
| `account` | `address` | The address of the account |

**Returns**

| Name     | Type   | Description                                                                       |
| -------- | ------ | --------------------------------------------------------------------------------- |
| `<none>` | `bool` | A boolean value indicating whether the specified account has a pending rebalance. |

#### getTokenFactory

Retrieves the address of the Vault (TokenFactory) contract.

*This function casts the `tokenFactory` variable to an address and returns it.*

```solidity
function getTokenFactory() public view returns (address);
```

**Returns**

| Name     | Type      | Description                                       |
| -------- | --------- | ------------------------------------------------- |
| `<none>` | `address` | The address of the Vault (TokenFactory) contract. |

#### transferFrom

Transfers the specified amount of tokens from the sender to the recipient.

*Overrides the `transferFrom` function from the inherited `ERC20Upgradeable` and `IERC20Upgradeable` contracts. If the sender or recipient has a pending rebalance, it is handled before the transfer. This function can only be called when transfers are not stopped, and neither the sender nor the recipient are on the sanctions list.*

```solidity
function transferFrom(address sender, address recipient, uint256 amount)
    public
    override(ERC20Upgradeable, IERC20Upgradeable)
    stopTransfer
    insufficientUnderlying
    dailyFFUpdate
    onlyNotSanctioned(recipient)
    onlyNotSanctioned(sender)
    returns (bool);
```

**Parameters**

| Name        | Type      | Description                                        |
| ----------- | --------- | -------------------------------------------------- |
| `sender`    | `address` | The address from which tokens will be transferred. |
| `recipient` | `address` | The address to which tokens will be transferred.   |
| `amount`    | `uint256` | The amount of tokens to transfer.                  |

**Returns**

| Name     | Type   | Description                                                 |
| -------- | ------ | ----------------------------------------------------------- |
| `<none>` | `bool` | A boolean value indicating whether the operation succeeded. |

#### handlePendingRebalance

Handles pending rebalances for the sender and receiver addresses.

*This function checks if the sender or receiver has a pending rebalance and applies the rebalance if needed.*

```solidity
function handlePendingRebalance(address sender, address receiver) public;
```

**Parameters**

| Name       | Type      | Description                                                   |
| ---------- | --------- | ------------------------------------------------------------- |
| `sender`   | `address` | The address of the sender involved in a transfer operation.   |
| `receiver` | `address` | The address of the receiver involved in a transfer operation. |

#### asset

Retrieves the address of the underlying token.

*It overrides the `asset` function from the `IERC4626Upgradeable` interface.*

```solidity
function asset() public view virtual override returns (address);
```

**Returns**

| Name     | Type      | Description                          |
| -------- | --------- | ------------------------------------ |
| `<none>` | `address` | The address of the underlying token. |

#### totalAssets

Retrieves the total amount of assets held by the TokenFactory.

*It overrides the `totalAssets` function from the `IERC4626Upgradeable` interface.*

```solidity
function totalAssets() public view virtual override returns (uint256);
```

**Returns**

| Name     | Type      | Description                                                 |
| -------- | --------- | ----------------------------------------------------------- |
| `<none>` | `uint256` | The total amount of assets held by the Vault(TokenFactory). |

#### convertToShares

Converts a specified amount of underlying assets to shares(RiskOn/Off).

*It overrides the `convertToShares` function from the `IERC4626Upgradeable` interface.*

```solidity
function convertToShares(uint256 assets) public view virtual override returns (uint256 shares);
```

**Parameters**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `assets` | `uint256` | The amount of assets to convert to shares. |

**Returns**

| Name     | Type      | Description                                                |
| -------- | --------- | ---------------------------------------------------------- |
| `shares` | `uint256` | The amount of shares(RiskOn/Off) for the amount of assets. |

#### convertToAssets

Converts a specified amount of shares(RiskOn/Off) to underlying assets.

*It overrides the `convertToAssets` function from the `IERC4626Upgradeable` interface.*

```solidity
function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets);
```

**Parameters**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `shares` | `uint256` | The amount of shares to convert to assets. |

**Returns**

| Name     | Type      | Description                                                |
| -------- | --------- | ---------------------------------------------------------- |
| `assets` | `uint256` | The amount of assets for the amount of shares(RiskOn/Off). |

#### maxDeposit

Calculates the maximum amount of assets that can be deposited by a specific account.

*It overrides the `maxDeposit` function from the `IERC4626Upgradeable` interface.*

```solidity
function maxDeposit(address account) public view virtual override returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                                                   |
| --------- | --------- | ----------------------------------------------------------------------------- |
| `account` | `address` | The address of the account for which to calculate the maximum deposit amount. |

**Returns**

| Name     | Type      | Description                                                        |
| -------- | --------- | ------------------------------------------------------------------ |
| `<none>` | `uint256` | The maximum amount of assets that can be deposited by the account. |

#### previewDeposit

Provides a preview of the number of shares(RiskOn/Off) that would be received for a amount of assets.

*It overrides the `previewDeposit` function from the `IERC4626Upgradeable` interface.*

```solidity
function previewDeposit(uint256 assets) public view virtual override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                                  |
| -------- | --------- | -------------------------------------------- |
| `assets` | `uint256` | The amount of assets to preview the deposit. |

**Returns**

| Name     | Type      | Description                                                          |
| -------- | --------- | -------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount of shares(RiskOn/Off) for the specified amount of assets. |

#### deposit

Deposits an amount of underlying assets, crediting the shares(RiskON/OFF) to the receiver.

*It overrides the `deposit` function from the `IERC4626Upgradeable` interface. The `stopDeposit` circuit breaker can be used to freeze deposits and `validateDepositAmount` modifier to validate the deposit amount*

```solidity
function deposit(uint256 assets, address receiver)
    public
    virtual
    override
    stopDeposit
    insufficientUnderlying
    dailyFFUpdate
    depositLimitHit(assets)
    validateDepositAmount(assets, receiver)
    returns (uint256);
```

**Parameters**

| Name       | Type      | Description                      |
| ---------- | --------- | -------------------------------- |
| `assets`   | `uint256` | The amount of assets to deposit. |
| `receiver` | `address` | The receiver address.            |

**Returns**

| Name     | Type      | Description                                             |
| -------- | --------- | ------------------------------------------------------- |
| `<none>` | `uint256` | The amount of shares(RiskOn/Off) the receiver will get. |

#### depositWithPermit

Deposits an amount of underlying assets, crediting the shares(RiskON/OFF) to the receiver with an EIP-2612 permit for approval.

*It overrides the `deposit` function from the `IERC4626Upgradeable` interface. The `stopDeposit` circuit breaker can be used to freeze deposits and `validateDepositAmount` modifier to validate the deposit amount then calls `permit` on the `underlyingToken` to set the allowance,*

```solidity
function depositWithPermit(uint256 assets, address receiver, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
    public
    stopDeposit
    insufficientUnderlying
    dailyFFUpdate
    depositLimitHit(assets)
    validateDepositAmount(assets, receiver)
    returns (uint256);
```

**Parameters**

| Name       | Type      | Description                                                             |
| ---------- | --------- | ----------------------------------------------------------------------- |
| `assets`   | `uint256` | The amount of underlying assets to deposit.                             |
| `receiver` | `address` | The address of the receiver                                             |
| `deadline` | `uint256` | The deadline for the permit signature to be valid, as a UNIX timestamp. |
| `v`        | `uint8`   | The recovery byte of the signature.                                     |
| `r`        | `bytes32` | part of the ECDSA signature pair.                                       |
| `s`        | `bytes32` | part of the ECDSA signature pair.                                       |

**Returns**

| Name     | Type      | Description                                            |
| -------- | --------- | ------------------------------------------------------ |
| `<none>` | `uint256` | The amount of shares(RiskOn/Off) the receiber will get |

#### depositWithExpiry

Deposits an amount of underlying assets, crediting the shares(RiskON/OFF) to the receiver.

*It overrides the `deposit` function from the `IERC4626Upgradeable` interface. The `stopDeposit` circuit breaker can be used to freeze deposits and `validateDepositAmount` modifier to validate the deposit amount*

```solidity
function depositWithExpiry(uint256 assets, address receiver, uint256 expiryDate)
    public
    virtual
    expiryDateCheck(expiryDate)
    stopDeposit
    insufficientUnderlying
    dailyFFUpdate
    depositLimitHit(assets)
    validateDepositAmount(assets, receiver)
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                      |
| ------------ | --------- | -------------------------------- |
| `assets`     | `uint256` | The amount of assets to deposit. |
| `receiver`   | `address` | The receiver address.            |
| `expiryDate` | `uint256` | The expiry date for the deposit. |

**Returns**

| Name     | Type      | Description                                             |
| -------- | --------- | ------------------------------------------------------- |
| `<none>` | `uint256` | The amount of shares(RiskOn/Off) the receiver will get. |

#### depositWithNative

Deposits an amount of underlying (NATIVE) assets, crediting the shares(RiskON/OFF) to the receiver.

*It uses msg.value as the deposit amount. The `stopDeposit` circuit breaker can be used to freeze deposits and `validateDepositAmount` modifier to validate the deposit amount*

```solidity
function depositWithNative(address receiver)
    public
    payable
    virtual
    nonReentrant
    stopDeposit
    insufficientUnderlying
    dailyFFUpdate
    depositLimitHit(msg.value)
    validateDepositAmount(msg.value, receiver)
    returns (uint256);
```

**Parameters**

| Name       | Type      | Description           |
| ---------- | --------- | --------------------- |
| `receiver` | `address` | The receiver address. |

**Returns**

| Name     | Type      | Description                                             |
| -------- | --------- | ------------------------------------------------------- |
| `<none>` | `uint256` | The amount of shares(RiskOn/Off) the receiver will get. |

#### maxMint

Calculates the maximum amount of shares(RiskOn/Off) that can be minted for a user.

*It overrides the `maxMint` function from the `IERC4626Upgradeable` interface.*

```solidity
function maxMint(address account) public view virtual override returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                                                         |
| --------- | --------- | ----------------------------------------------------------------------------------- |
| `account` | `address` | The address of user for which to calculate the maximum mintable shares(RiskOn/Off). |

**Returns**

| Name     | Type      | Description                                                               |
| -------- | --------- | ------------------------------------------------------------------------- |
| `<none>` | `uint256` | The maximum amount of shares(RiskOn/Off) that can be minted for the user. |

#### previewMint

Provides a preview of the amount of underlying assets required to mint a number of shares(RiskOn/Off).

*It overrides the `previewMint` function from the `IERC4626Upgradeable` interface.*

```solidity
function previewMint(uint256 shares) public view virtual override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                               |
| -------- | --------- | ----------------------------------------- |
| `shares` | `uint256` | The number of shares(RiskOn/Off) to mint. |

**Returns**

| Name     | Type      | Description                                                                                  |
| -------- | --------- | -------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount of underlying assets required to mint the specified number of shares(RiskOn/Off). |

#### mint

mints an amount of shares, crediting the shares(RiskON/OFF) to the receiver.

*It overrides the `deposit` function from the `IERC4626Upgradeable` interface. The `stopDeposit` circuit breaker can be used to freeze minting. As opposed to deposit, minting is allowed even if the vault is in a state where the price of a share is zero. In this case, the shares will be minted without requiring any assets to be deposited.*

```solidity
function mint(uint256 shares, address receiver)
    public
    virtual
    override
    stopDeposit
    insufficientUnderlying
    dailyFFUpdate
    depositLimitHit(shares)
    returns (uint256);
```

**Parameters**

| Name       | Type      | Description                               |
| ---------- | --------- | ----------------------------------------- |
| `shares`   | `uint256` | The amount of shares(RiskON/OFF) to mint. |
| `receiver` | `address` | The receiver address.                     |

**Returns**

| Name     | Type      | Description                                                                                  |
| -------- | --------- | -------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount of assets that were deposited to mint the specified number of shares(RiskON/OFF). |

#### maxWithdraw

Calculates the maximum amount of underlying assets that can be withdrawn by a specified owner.

*It overrides the `maxWithdraw` function from the `IERC4626Upgradeable` interface.*

```solidity
function maxWithdraw(address owner_) public view virtual override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                                                                                 |
| -------- | --------- | ------------------------------------------------------------------------------------------- |
| `owner_` | `address` | The address of the owner for which to calculate the maximum underlying withdrawable assets. |

**Returns**

| Name     | Type      | Description                                                                |
| -------- | --------- | -------------------------------------------------------------------------- |
| `<none>` | `uint256` | The maximum amount of assets that can be withdrawn by the specified owner. |

#### previewWithdraw

Provide a preview of number of shares(RiskOn/Off) required to withdraw an amount of underlying assets.

*It overrides the `previewWithdraw` function from the `IERC4626Upgradeable` interface.*

```solidity
function previewWithdraw(uint256 assets) public view virtual override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `assets` | `uint256` | The amount of assets to withdraw. |

**Returns**

| Name     | Type      | Description                                                                           |
| -------- | --------- | ------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The number of shares(RiskOn/Off) required to withdraw the specified amount of assets. |

#### withdraw

Allows an owner to withdraw a specified amount of underlying assets, transferring them to a receiver.

*This function overrides the `withdraw` function from the `IERC4626Upgradeable` interface, and is guarded by the `stopWithdraw`, `onlyAssetOwner`, and `nonReentrant` modifiers.*

```solidity
function withdraw(uint256 assets, address receiver, address owner_)
    public
    virtual
    override
    stopWithdraw
    insufficientUnderlying
    dailyFFUpdate
    withdrawLimitHit(assets)
    onlyAssetOwner(owner_)
    nonReentrant
    returns (uint256);
```

**Parameters**

| Name       | Type      | Description                                            |
| ---------- | --------- | ------------------------------------------------------ |
| `assets`   | `uint256` | The amount of underlying assets to withdraw.           |
| `receiver` | `address` | The address to which the assets should be transferred. |
| `owner_`   | `address` | The address of the owner making the withdrawal.        |

**Returns**

| Name     | Type      | Description                                                             |
| -------- | --------- | ----------------------------------------------------------------------- |
| `<none>` | `uint256` | The number of shares(RiskON/OFF) corresponding to the withdrawn assets. |

#### withdrawWithExpiry

Allows an owner to withdraw a specified amount of underlying assets, transferring them to a receiver.

*This function overrides the `withdraw` function from the `IERC4626Upgradeable` interface, and is guarded by the `stopWithdraw`, `onlyAssetOwner`, and `nonReentrant` modifiers.*

```solidity
function withdrawWithExpiry(uint256 assets, address receiver, address owner_, uint256 expiryDate)
    public
    virtual
    expiryDateCheck(expiryDate)
    stopWithdraw
    insufficientUnderlying
    dailyFFUpdate
    withdrawLimitHit(assets)
    onlyAssetOwner(owner_)
    nonReentrant
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                            |
| ------------ | --------- | ------------------------------------------------------ |
| `assets`     | `uint256` | The amount of underlying assets to withdraw.           |
| `receiver`   | `address` | The address to which the assets should be transferred. |
| `owner_`     | `address` | The address of the owner making the withdrawal.        |
| `expiryDate` | `uint256` | The expiry date for the withdrawal.                    |

**Returns**

| Name     | Type      | Description                                                             |
| -------- | --------- | ----------------------------------------------------------------------- |
| `<none>` | `uint256` | The number of shares(RiskON/OFF) corresponding to the withdrawn assets. |

#### flashLoan

Allows user to take flashloans from the tokenFactory (Vault/POOL)

*This function is guarded by the `nonReentrant` and `stopFlashLoan` modifiers. It makes use of AAVE's flashloan interface to provide backwards compatibility for ease of use*

```solidity
function flashLoan(address receiver, uint256 amount, bytes memory params)
    external
    nonReentrant
    stopFlashLoan
    onlyNotSanctioned(receiver)
    onlyNotSanctioned(_msgSender());
```

**Parameters**

| Name       | Type      | Description                                                                       |
| ---------- | --------- | --------------------------------------------------------------------------------- |
| `receiver` | `address` | The address of the receiver.                                                      |
| `amount`   | `uint256` | The amount of underlying assets to flashloan.                                     |
| `params`   | `bytes`   | The parameters for the flashloan. Used by the receiver contract(Aave's interface) |

#### maxRedeem

Computes the maximum amount of underlying assets that can be redeemed by owner.

*It overrides the `maxRedeem` function from the `IERC4626Upgradeable` interface.*

```solidity
function maxRedeem(address owner_) public view virtual override returns (uint256);
```

**Parameters**

| Name     | Type      | Description               |
| -------- | --------- | ------------------------- |
| `owner_` | `address` | The address of the owner. |

**Returns**

| Name     | Type      | Description                                                        |
| -------- | --------- | ------------------------------------------------------------------ |
| `<none>` | `uint256` | The maximum amount of underlying assets that the owner can redeem. |

#### previewRedeem

Provides a preview of the amount of underlying assets that would be received when redeeming a number of shares(RiskON/OFF).

*It overrides the `previewRedeem` function from the `IERC4626Upgradeable` interface.*

```solidity
function previewRedeem(uint256 shares) public view virtual override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                                                                             |
| -------- | --------- | --------------------------------------------------------------------------------------- |
| `shares` | `uint256` | The number of shares(RiskON/OFF) to compute the equivalent underlying asset amount for. |

**Returns**

| Name     | Type      | Description                                                             |
| -------- | --------- | ----------------------------------------------------------------------- |
| `<none>` | `uint256` | The equivalent asset amount for the given number of shares(RiskON/OFF). |

#### redeem

Allows a user to redeem some amount of underlying assets based on an input amount of shares(RiskON/OFF).

*See IERC4626-redeem.*

*It overrides the `redeem` function from the `IERC4626Upgradeable` interface. and is guarded by the `stopWithdraw`, `onlyAssetOwner`, and `nonReentrant` modifiers.*

```solidity
function redeem(uint256 shares, address receiver, address owner_)
    public
    virtual
    override
    stopWithdraw
    insufficientUnderlying
    dailyFFUpdate
    withdrawLimitHit(shares)
    onlyAssetOwner(owner_)
    nonReentrant
    returns (uint256);
```

**Parameters**

| Name       | Type      | Description                                                       |
| ---------- | --------- | ----------------------------------------------------------------- |
| `shares`   | `uint256` | The number of shares(RiskON/OFF) to redeem for underlying assets. |
| `receiver` | `address` | The address of receiver.                                          |
| `owner_`   | `address` | The address of the owner.                                         |

**Returns**

| Name     | Type      | Description                               |
| -------- | --------- | ----------------------------------------- |
| `<none>` | `uint256` | The amount of underlying assets redeemed. |

#### \_onlyTokenFactory

Helpers for modifiers to reduce size

Checks if the caller is the Vault (tokenFactory)

*This function is utilized by the `onlyTokenFactory` modifier to ensure that only the token factory can call certain functions.*

```solidity
function _onlyTokenFactory() private view;
```

#### \_onlyAssetOwner

Checks if the caller is the asset owner.

*This function is utilized by the `onlyAssetOwner` modifier to ensure that only the asset owner can call certain functions.*

```solidity
function _onlyAssetOwner(address assetOwner) private view;
```

**Parameters**

| Name         | Type      | Description                     |
| ------------ | --------- | ------------------------------- |
| `assetOwner` | `address` | The address of the asset owner. |

#### \_validateDepositAmount

Validates the deposit amount.

*This function is utilized by the `validateDepositAmount` modifier to ensure that the deposit amount is neither zero nor exceeds the maximum allowed deposit for the receiver.*

```solidity
function _validateDepositAmount(uint256 assets, address receiver) private view;
```

**Parameters**

| Name       | Type      | Description                                      |
| ---------- | --------- | ------------------------------------------------ |
| `assets`   | `uint256` | The amount of underlying assets being deposited. |
| `receiver` | `address` | The address of the receiver                      |

#### hasPendingFF

```solidity
function hasPendingFF(address account) public view returns (bool);
```

#### handlePendingFF

```solidity
function handlePendingFF(address sender, address receiver) public;
```

#### \_handleDeposit

```solidity
function _handleDeposit(uint256 assets, address receiver) private returns (uint256);
```

**Parameters**

| Name       | Type      | Description                                                                                             |
| ---------- | --------- | ------------------------------------------------------------------------------------------------------- |
| `assets`   | `uint256` | The amount of underlying assets to deposit.\@note WE can use SHARES as well since it's a 1:1 conversion |
| `receiver` | `address` | The address to which the assets should be transferred.                                                  |

#### \_handleWithdraw

```solidity
function _handleWithdraw(uint256 assets, address receiver, address owner_) private returns (uint256);
```

**Parameters**

| Name       | Type      | Description                                                                                              |
| ---------- | --------- | -------------------------------------------------------------------------------------------------------- |
| `assets`   | `uint256` | The amount of underlying assets to withdraw. @note WE can use SHARES as well since it's a 1:1 conversion |
| `receiver` | `address` | The address to which the assets should be transferred.                                                   |
| `owner_`   | `address` | The address of the owner making the withdrawal.                                                          |

#### getFlashLoanPool

Retrieves the address of the flashloan POOL (TokenFactory) contract.

*This function casts the `tokenFactory` variable to an address and returns it.*

```solidity
function getFlashLoanPool() public view returns (address);
```

**Returns**

| Name     | Type      | Description                                                |
| -------- | --------- | ---------------------------------------------------------- |
| `<none>` | `address` | The address of the flashloan POOL (TokenFactory) contract. |

### Errors

#### SmartToken\_\_NotTokenFactory

```solidity
error SmartToken__NotTokenFactory();
```

#### SmartToken\_\_MethodNotAllowed

```solidity
error SmartToken__MethodNotAllowed();
```

#### SmartToken\_\_DepositMoreThanMax

```solidity
error SmartToken__DepositMoreThanMax();
```

#### SmartToken\_\_MintMoreThanMax

```solidity
error SmartToken__MintMoreThanMax();
```

#### SmartToken\_\_WithdrawMoreThanMax

```solidity
error SmartToken__WithdrawMoreThanMax();
```

#### SmartToken\_\_RedeemMoreThanMax

```solidity
error SmartToken__RedeemMoreThanMax();
```

#### SmartToken\_\_OnlyAssetOwner

```solidity
error SmartToken__OnlyAssetOwner();
```

#### SmartToken\_\_ZeroDeposit

```solidity
error SmartToken__ZeroDeposit();
```

#### SmartToken\_\_InsufficientUnderlying

```solidity
error SmartToken__InsufficientUnderlying();
```

#### SmartToken\_\_DepositLimitHit

```solidity
error SmartToken__DepositLimitHit();
```

#### SmartToken\_\_WithdrawLimitHit

```solidity
error SmartToken__WithdrawLimitHit();
```

#### SmartToken\_\_ExpiryDateReached

```solidity
error SmartToken__ExpiryDateReached();
```

#### SmartToken\_\_WithdrawNativeFailed

```solidity
error SmartToken__WithdrawNativeFailed();
```


# Wrapped SmartTokens

Wrapped rON/rOFF

## wrappedSmartToken

[Git Source](https://github.com/RiskProtocol/core-protocol/blob/d59ee719f0b8aa5daeb239f6468bda6d3a1b56be/contracts/vaults/wrapped/WrappedSmartToken.sol)

**Inherits:** UnbuttonToken, UUPSUpgradeable, OwnableUpgradeable, FlashloanSpecifics, BaseContract

### State Variables

#### sellingToken

```solidity
address private sellingToken;
```

#### isWrappedX

```solidity
bool private isWrappedX;
```

#### timeout

```solidity
uint256 private timeout;
```

#### SCALING\_FACTOR

```solidity
uint256 private constant SCALING_FACTOR = 10 ** 18;
```

#### orchestrator

```solidity
address private orchestrator;
```

#### premiumPercentage

```solidity
uint16 private premiumPercentage;
```

#### premiumDenominator

```solidity
uint16 private constant premiumDenominator = 10000;
```

#### signers

This is the signers address of RP api's that generate encoded params for rebalance

```solidity
mapping(address => bool) private signers;
```

#### currentDiscountRates

```solidity
DiscountRates private currentDiscountRates;
```

#### \_activeLoan

```solidity
LoanType private _activeLoan;
```

### Functions

#### onlyOrchestrator

```solidity
modifier onlyOrchestrator();
```

#### CustomNonReentrant

```solidity
modifier CustomNonReentrant(LoanType loanType);
```

#### constructor

**Note:** oz-upgrades-unsafe-allow: constructor

```solidity
constructor();
```

#### riskInitialize

```solidity
function riskInitialize(
    address underlying_,
    address sellingToken_,
    string memory name_,
    string memory symbol_,
    uint256 initialRate,
    bool isWrappedX_,
    address owner_,
    address signer,
    uint256 timeout_,
    address sanctionsContract_,
    address orchestrator_
) public initializer;
```

#### initialize

```solidity
function initialize(address underlying_, string memory name_, string memory symbol_, uint256 initialRate)
    public
    pure
    override;
```

#### \_authorizeUpgrade

```solidity
function _authorizeUpgrade(address newImplementation) internal override onlyOwner;
```

#### flashLoanAlt

Allows user to take flashloans from the wrapper

*This function is guarded by the `nonReentrant` modifiers. we offer unwanted tokens (sellingToken) in exchange of underlying tokens*

```solidity
function flashLoanAlt(
    address receiver,
    uint256 amount,
    bytes memory encodedData,
    bytes memory signature,
    bytes memory params
)
    external
    CustomNonReentrant(LoanType.FLASHLOANALT)
    stopFlashLoan
    onlyNotSanctioned(receiver)
    onlyNotSanctioned(_msgSender());
```

**Parameters**

| Name          | Type      | Description                                                                       |
| ------------- | --------- | --------------------------------------------------------------------------------- |
| `receiver`    | `address` | The address of the receiver.                                                      |
| `amount`      | `uint256` | The amount of underlying assets to flashloan.                                     |
| `encodedData` | `bytes`   |                                                                                   |
| `signature`   | `bytes`   |                                                                                   |
| `params`      | `bytes`   | The parameters for the flashloan. Used by the receiver contract(Aave's interface) |

#### flashLoan

Allows user to take flashloans from the wrapper (Vault/POOL)

*This function is guarded by the `nonReentrant` and `stopFlashLoan` modifiers. It makes use of AAVE's flashloan interface to provide backwards compatibility for ease of use*

```solidity
function flashLoan(address receiver, uint256 amount, bytes memory params)
    external
    CustomNonReentrant(LoanType.FLASHLOAN)
    stopFlashLoan
    onlyNotSanctioned(receiver)
    onlyNotSanctioned(_msgSender());
```

**Parameters**

| Name       | Type      | Description                                                                       |
| ---------- | --------- | --------------------------------------------------------------------------------- |
| `receiver` | `address` | The address of the receiver.                                                      |
| `amount`   | `uint256` | The amount of underlying assets to flashloan.                                     |
| `params`   | `bytes`   | The parameters for the flashloan. Used by the receiver contract(Aave's interface) |

#### setTimeout

```solidity
function setTimeout(uint256 timeout_) external onlyOwner;
```

#### discountRateSetter

```solidity
function discountRateSetter(uint256 startTime, uint256 endTime, uint256 discountMin, uint256 discountMax)
    private
    returns (bool);
```

#### setDiscountRateOrchestrator

```solidity
function setDiscountRateOrchestrator(uint256 startTime, uint256 endTime, uint256 discountMin, uint256 discountMax)
    external
    onlyOrchestrator
    returns (bool);
```

#### setDiscountRate

```solidity
function setDiscountRate(uint256 startTime, uint256 endTime, uint256 discountMin, uint256 discountMax)
    external
    onlyOwner
    returns (bool);
```

#### setSigners

```solidity
function setSigners(address signer, bool status) external onlyOwner;
```

#### setPremiumPercentage

```solidity
function setPremiumPercentage(uint16 percentage) external onlyOwner;
```

#### setOrchestator

```solidity
function setOrchestator(address orchestrator_) external onlyOwner;
```

#### getFlashloanPremium

```solidity
function getFlashloanPremium() public view returns (uint16);
```

#### getIsWrappedX

```solidity
function getIsWrappedX() external view returns (bool);
```

#### getTimeout

```solidity
function getTimeout() external view returns (uint256);
```

#### getDiscountRate

```solidity
function getDiscountRate() external view returns (DiscountRates memory);
```

#### getSigners

```solidity
function getSigners(address signer) external view returns (bool);
```

#### calculateUserShare

```solidity
function calculateUserShare() private view returns (uint256);
```

#### refundUnwantedTokens

```solidity
function refundUnwantedTokens(address user) private;
```

#### getConversionRate

```solidity
function getConversionRate(PriceFeed memory priceFeed, uint256 t1, uint256 t2, uint256 x1, uint256 x2)
    private
    view
    returns (uint256, uint256);
```

#### getOrchestrator

```solidity
function getOrchestrator() external view returns (address);
```

#### verifyAndDecode

Verifies the provided signature and decodes the encoded data into `ScheduledRebalance` struct.

*It recovers the address from the Ethereum signed message hash and the provided `signature`. If the recovered address doesn't match the `signersAddress`, it reverts the transaction. If the signature is valid, it decodes the `encodedData` into a `ScheduledRebalance` struct and returns it.*

```solidity
function verifyAndDecode(bytes memory signature, bytes memory encodedData) private view returns (PriceFeed memory);
```

**Parameters**

| Name          | Type    | Description                                                |
| ------------- | ------- | ---------------------------------------------------------- |
| `signature`   | `bytes` | The signature to be verified.                              |
| `encodedData` | `bytes` | The data to be decoded into a `ScheduledRebalance` struct. |

**Returns**

| Name     | Type        | Description                                                     |
| -------- | ----------- | --------------------------------------------------------------- |
| `<none>` | `PriceFeed` | data A `ScheduledRebalance` struct containing the decoded data. |

#### burn

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function burn(uint256 amount) public override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `amount` | `uint256` | The amount of wrapper tokens to burn. |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### burnTo

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens to the specified beneficiary.

```solidity
function burnTo(address to, uint256 amount) public override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `to`     | `address` | The beneficiary account.              |
| `amount` | `uint256` | The amount of wrapper tokens to burn. |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### burnAll

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function burnAll() public override returns (uint256);
```

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### burnAllTo

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function burnAllTo(address to) public override returns (uint256);
```

**Parameters**

| Name | Type      | Description              |
| ---- | --------- | ------------------------ |
| `to` | `address` | The beneficiary account. |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### withdraw

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function withdraw(uint256 uAmount) public override returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                  |
| --------- | --------- | -------------------------------------------- |
| `uAmount` | `uint256` | The amount of underlying tokens to withdraw. |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

#### withdrawTo

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens back to the specified beneficiary.

```solidity
function withdrawTo(address to, uint256 uAmount) public override returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                  |
| --------- | --------- | -------------------------------------------- |
| `to`      | `address` | The beneficiary account.                     |
| `uAmount` | `uint256` | The amount of underlying tokens to withdraw. |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

#### withdrawAll

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function withdrawAll() public override returns (uint256);
```

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

#### withdrawAllTo

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function withdrawAllTo(address to) public override returns (uint256);
```

**Parameters**

| Name | Type      | Description              |
| ---- | --------- | ------------------------ |
| `to` | `address` | The beneficiary account. |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

### Errors

#### WrappedSmartToken\_\_Not\_Implemented

```solidity
error WrappedSmartToken__Not_Implemented();
```

#### WrappedSmartToken\_\_PriceFeedOutdated

```solidity
error WrappedSmartToken__PriceFeedOutdated();
```

#### WrappedSmartToken\_\_InvalidSigner

```solidity
error WrappedSmartToken__InvalidSigner();
```

#### WrappedSmartToken\_\_InvalidDiscount

```solidity
error WrappedSmartToken__InvalidDiscount();
```

#### WrappedSmartToken\_\_InvalidOrchestrator

```solidity
error WrappedSmartToken__InvalidOrchestrator();
```

#### WrappedSmartToken\_\_ReEntrantCall

```solidity
error WrappedSmartToken__ReEntrantCall();
```

### Structs

#### PriceFeed

```solidity
struct PriceFeed {
    uint256 smartTokenXValue;
    uint256 smartTokenYValue;
    uint256 timestamp;
}
```

#### DiscountRates

```solidity
struct DiscountRates {
    uint256 startTime;
    uint256 endTime;
    uint256 discountMin;
    uint256 discountMax;
}
```

### Enums

#### LoanType

```solidity
enum LoanType {
    NONE,
    FLASHLOAN,
    FLASHLOANALT
}
```


# SDK

## SDK

The Risk Protocol SDK is a TypeScript library for interacting with Risk Protocol's core smart contracts and services. Built on ethers.js v6, it provides a complete interface for token management, vault operations, rebalancing, and price estimation.

### Installation

```bash
npm install risk-contracts
# or
yarn add risk-contracts
## Note that it's not published yet, the above is a placeholder
```

### Quick Start

#### Server-Side (Node.js)

```typescript
import { RiskContracts, RiskSdkConfig } from 'risk-contracts';

const config: RiskSdkConfig = {
  serverProvider: {
    rpcUrl: "https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY",
    privateKey: "YOUR_PRIVATE_KEY"
  },
  network: {
    name: "sepolia",
    chainId: 11155111
  },
  tokenFactory: {
    address: "0x8888cF3da8E6Fb30bEEcD9dC1dd220060c2969DC"
  },
  smartToken: {
    one: "0x...",  // RiskON token address
    two: "0x..."   // RiskOFF token address
  },
  orchestrator: {
    address: "0x..."
  },
  apiUrl: "https://api.riskprotocol.com"
};

const sdk = new RiskContracts(config);
```

#### Client-Side (Browser with Wallet)

```typescript
import { RiskContracts, RiskSdkConfig } from 'risk-contracts';
import { ethers } from 'ethers';

// Connect to user's wallet
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

const config: RiskSdkConfig = {
  clientProvider: {
    provider: provider,
    signer: signer
  },
  network: {
    name: "sepolia",
    chainId: 11155111
  },
  tokenFactory: {
    address: "0x..."
  },
  smartToken: {
    one: "0x...",
    two: "0x..."
  },
  orchestrator: {
    address: "0x..."
  },
  apiUrl: "https://api.riskprotocol.com"
};

const sdk = new RiskContracts(config);
```

### Configuration

The SDK requires a configuration object that specifies network settings, contract addresses, and provider details.

```typescript
interface RiskSdkConfig {
  // Provider (choose one)
  serverProvider?: {
    rpcUrl: string;
    privateKey: string;
  };
  clientProvider?: {
    provider: ethers.BrowserProvider;
    signer: ethers.JsonRpcSigner;
  };

  // Network configuration
  network: {
    name: string;
    chainId: number;
  };

  // Contract addresses
  tokenFactory: {
    address: string;
  };
  smartToken: {
    one: string;    // RiskON address
    two: string;    // RiskOFF address
  };
  orchestrator: {
    address: string;
  };

  // Optional: API URL for NTV price estimates
  apiUrl?: string;
}
```

**Important:** Provide either `serverProvider` or `clientProvider`, not both.

### Core Concepts

#### SDK Structure

The SDK exposes five main modules:

* **tokenFactory** - Core token operations, management fees, and rebalancing
* **smartToken** - ERC-4626 vault operations (deposits, withdrawals, transfers)
* **orchestrator** - Scheduled operations and Balancer pool management
* **balancerHelper** - Balancer pool calculations and swap estimations
* **priceEstimates** - Price discovery and slippage calculations

#### Working with Amounts

All token amounts in the SDK use **wei units** (BigInt). Use ethers.js utilities for conversion:

```typescript
import { ethers } from 'ethers';

// Convert to wei
const amount = ethers.parseEther("1.5");  // 1500000000000000000n

// Convert from wei
const readable = ethers.formatEther(amount);  // "1.5"

// For tokens with different decimals
const usdcAmount = ethers.parseUnits("100", 6);  // 6 decimals
```

#### Smart Tokens

Risk Protocol uses two smart tokens: **RiskON** (index 0) and **RiskOFF** (index 1). Most SmartToken methods accept an optional `contract` parameter:

```typescript
// RiskON 
await sdk.smartToken.balanceOf(address, 0);

// RiskOFF 
await sdk.smartToken.balanceOf(address, 1);
```

### Common Workflows

#### 1. Deposit Tokens

```typescript
import { ethers } from 'ethers';

const depositAmount = ethers.parseEther("100");
const userAddress = "0x...";

// 1. Preview the deposit
const sharesReceived = await sdk.smartToken.transaction.previewDeposit(
  depositAmount.toString(),
  0  // RiskON
);

console.log(`Will receive ${ethers.formatEther(sharesReceived)} shares`);

// 2. Approve token spending (get smart token address first)
const baseToken = await sdk.tokenFactory.getBaseToken();
const riskOnAddress = await sdk.tokenFactory.getSmartTokenAddress(0);
const erc20 = new ethers.Contract(
  baseToken,
  ['function approve(address,uint256) returns (bool)'],
  signer
);

const approveTx = await erc20.approve(
  riskOnAddress,
  depositAmount
);
await approveTx.wait();

// 3. Execute deposit
const depositTx = await sdk.smartToken.transaction.deposit(
  depositAmount.toString(),
  userAddress,
  0
);
await depositTx.wait();

console.log('Deposit successful!');
```

#### 2. Withdraw Tokens

```typescript
import { ethers } from 'ethers';

const withdrawAmount = ethers.parseEther("50");
const userAddress = "0x...";

// 1. Preview withdrawal
const assetsReceived = await sdk.smartToken.transaction.previewWithdraw(
  withdrawAmount.toString(),
  0
);

console.log(`Will receive ${ethers.formatEther(assetsReceived)} assets`);

// 2. Execute withdrawal
const withdrawTx = await sdk.smartToken.transaction.withdraw(
  withdrawAmount.toString(),
  userAddress,
  userAddress,
  0
);
await withdrawTx.wait();

console.log('Withdrawal successful!');
```

#### 3. Check Balances and Fees

```typescript
import { ethers } from 'ethers';

const userAddress = "0x...";

// Get share balance (RiskON)
const shares = await sdk.smartToken.balanceOf(userAddress, 0);
console.log(`Shares: ${ethers.formatEther(shares)}`);

// Get management fee rate
const feeRate = await sdk.tokenFactory.managementFees.getRate();
const feeRateBps = Number(feeRate) / 1e14;  // Convert to basis points
console.log(`Management fee: ${feeRateBps} bps`);

// Check if fees are active
const isActive = await sdk.tokenFactory.managementFees.isFeeActive();
console.log(`Fees active: ${isActive}`);
```

#### 4. Estimate Swap Outputs

```typescript
import { ethers } from 'ethers';

const poolAddress = "0x...";
const riskOnAddress = await sdk.tokenFactory.getSmartTokenAddress(0);
const riskOffAddress = await sdk.tokenFactory.getSmartTokenAddress(1);
const amountIn = ethers.parseEther("10");

// Estimate swap output (RiskON → RiskOFF)
const expectedOut = await sdk.balancerHelper.getExpectedAmountOut(
  poolAddress,
  riskOnAddress,   // RiskON
  riskOffAddress,  // RiskOFF
  amountIn
);

console.log(`Swapping 10 RiskON`);
console.log(`Expected output: ${ethers.formatEther(expectedOut)} RiskOFF`);

```

####

### Error Handling

Always wrap SDK calls in try-catch blocks:

```typescript
try {
  const tx = await sdk.smartToken.transaction.deposit(
    amount.toString(),
    recipient,
    0
  );
  await tx.wait();
} catch (error) {
  if (error.code === 'INSUFFICIENT_FUNDS') {
    console.error('Insufficient funds for gas');
  } else if (error.code === 'CALL_EXCEPTION') {
    console.error('Transaction reverted:', error.reason);
  } else {
    console.error('Transaction failed:', error.message);
  }
}
```

### Best Practices

#### 1. Always Preview Before Executing

```typescript
// Always preview first to show users what they'll receive
const preview = await sdk.smartToken.transaction.previewDeposit(amount, 0);
console.log(`You will receive ${ethers.formatEther(preview)} shares`);

```

#### 2. Check Maximum Limits

```typescript
const maxDeposit = await sdk.smartToken.transaction.maxDeposit(address, 0);

if (BigInt(amount) > maxDeposit) {
  throw new Error(`Amount exceeds maximum: ${ethers.formatEther(maxDeposit)}`);
}
```

### TypeScript Support

The SDK is fully typed. Import types as needed:

```typescript
import { RiskContracts, RiskSdkConfig } from 'risk-contracts';
import type { ethers } from 'ethers';

// All methods return properly typed values
const balance: bigint = await sdk.smartToken.balanceOf(address, 0);
```

### Next Steps

* See the API Reference for complete method documentation


# FAQs

## The Product

1. **What is The Risk Protocol (TRP)?**

The Risk Protocol is a risk marketplace that allows you to turn risk itself into a programmable, tradeable token–you can price, tokenize, hedge, and trade different kinds of risks in crypto. The core idea is simple yet powerful: “if risk is abundant in crypto, why not make it tradable?” By turning risk into a tradable asset, TRP enables users to adjust their risk exposure according to their risk appetite, filling a critical infrastructure gap.

2. **What can I actually do with TRP today?**

Initially at launch, you can deposit BTC or ETH and split it into two fully-collateralized SMART Tokens: a low-volatility “RiskOFF” token and a leveraged “RiskON” token. Hold whichever token matches your market view, swap between them as conditions change, or provide liquidity to earn fees. In practice, this allows you to move smoothly between defense (RiskOFF) and alpha-seeking (RiskON), without needing to build complex derivatives trades yourself. The underlying derivatives are abstracted away, allowing you to focus on the payoff that is of interest to you instead of the mechanics of how to implement it.&#x20;

3. **What are SMART Tokens, RiskON, and RiskOFF?**

Using our proprietary SMART mechanism, we can split an underlying asset into two SMART Tokens with defined risk/return payoffs. These SMART Tokens represent fully collateralized claims on the underlying asset with payoff structures implemented using synthetic derivatives. RiskOFF is designed to reduce drawdowns, sacrificing upside beyond a cap; RiskON is designed to capture more upside. Together, RiskON + RiskOFF always add back up to the value of the underlying asset, as the value is simply redistributed to RiskON and RiskOFF according to the payoff formula. We have designed several types of SMART Tokens; the RiskON/RiskOFF pair is one type, and it is the one we initially launched.&#x20;

4. **What do you mean by “risk tokenization” and “trading risk”?**

Instead of trading only the underlying coin, we separate its risk into distinct buckets and turn each bucket into an ERC-20/ERC-4626-compatible token. You can then trade these buckets directly: sell downside, buy upside, or sit in a cushioned profile, all by moving between SMART Tokens rather than building your own derivative structures.&#x20;

5. **How do you create a secondary market for these SMART Tokens?**&#x20;

For SMART Tokens to be genuinely useful, you need to be able to get in and out of positions at fair prices, which means deep, continuous secondary markets. TRP ships with its own internal DEX, where RiskON, RiskOFF, and the underlying assets trade against each other in dedicated pools, so you do not have to rely on external venues for basic liquidity. We will bootstrap and deepen these pools by aligning incentives for LPs: they earn trading fees from SMART Token flow, and, on top of that, we will direct protocol incentives to the key pairs to make it attractive to park capital there. LPs also benefit from dynamic fees–we scale fees up or down based on underlying volatility. Over time, as usage grows, this internal DEX becomes the natural liquidity hub for the SMART Token ecosystem, with aggregators and other venues routing into it. We might supplement the DEX with market-maker-driven liquidity in the future as well.

6. **Can I create customized SMART Tokens beyond RiskON/RiskOFF?**

At launch, SMART Tokens will be curated by us to concentrate liquidity and to ensure parameters are fully collateralized and easy to understand. Over time, we plan to launch different types of SMART Tokens and, eventually, more customizable paths that allow advanced users to create bespoke payoff designs that still pass our risk and collateral checks.

## How does it work?

7. **How does the basic mechanism work under the hood?**

When you deposit an asset (say, 1 BTC) into TRP, the protocol mints a pair of SMART Tokens: 1 RiskON BTC and 1 RiskOFF BTC, each starting with half the deposit's economic value. Under the hood, the contracts set up a synthetic, fully collateralized costless options collar between these two tokens: RiskOFF is given a downside floor and an upside cap (implemented as a long down and out put plus a short call), and RiskON takes the exact opposite side of that deal, absorbing losses beyond the floor and receiving upside beyond the cap. The two tokens are therefore direct counterparts to each other in an internal “risk swap”, not to any external market-maker. A proprietary risk engine continuously values these embedded payoffs and publishes a Net Token Value for each token. At any time, 1 RiskON + 1 RiskOFF can be redeemed back into 1 unit of the underlying, which keeps their combined value anchored to the underlying asset. At the end of each epoch (or earlier in extreme market crashes), the system rebalances and resets a fresh 50/50 pair for the next period, so the protocol itself never takes directional market risk—only redistributes it between RiskON and RiskOFF holders. For further details on rebalancing, please visit “Rebalances” in protocol documentation.

8. **What are Split, Swap, Redeem, and Liquidity in the dApp?**

“Split” mints RiskON and RiskOFF from your underlying; “Swap” lets you trade between the underlying and any SMART Token or between SMART Tokens themselves via AMM pools; “Redeem” lets you burn a matched set of RiskON and RiskOFF to get back the underlying asset; and “Liquidity” allows you to deposit (or withdraw) into our liquidity pools (for example, RiskON/RiskOFF/BTC or RiskON/RiskOFF/ETH) so that traders have deep markets and you earn fees and incentives.

9. **What are Epochs?**

Epochs are fixed, predefined time intervals during which a protocol applies a consistent set of rules, calculations, and state updates before recalculating for the next interval.

In the context of The Risk Protocol, an epoch is the period over which the risk profile of SMART Tokens is defined and enforced. For example, the cap and floor of RiskON and RiskOFF apply to returns over that specific epoch.

At the end of each epoch:

* The settlement prices of RiskON and RiskOFF are calculated
* The payoff logic embedded in the smart contracts is applied to determine how much of the underlying collateral each holder of RiskON and RiskOFF is entitled to
* New caps and floors for RiskON and RiskOFF are set for the next epoch
* New starting prices for RiskON and RiskOFF are established
* All holders of RiskON and RiskOFF from the expiring epoch are seamlessly rolled into the corresponding tokens for the new epoch (no need for active management)

10. **How does rebalancing work?**

Simultaneously with the end of an Epoch, a new Epoch begins. New RiskON/RiskOFF tokens are created such that the embedded options again form a zero-cost collar at the new Epoch start price. Each trader's USD value of expiring tokens is used to determine their holdings in the new tokens. The token balances are adjusted ("rebased") such that the trader's combined USD NTV in the new tokens equals their expiring USD NTV.

Specific details on the rebalancing mechanism, along with illustrative examples, can be found in the [Rebalance](/protocol-design-and-specifications/smart-tokens/rebalance) section.    &#x20;

11. **Where do the SMART Tokens' returns or yield come from?**

There is no magic external yield. Returns come from how upside and downside in the underlying asset are shared between RiskON and RiskOFF. All SMART Tokens are fully collateralized; we are redistributing risk and return from the underlying asset, not creating yield out of thin air.

12. **Can you walk through one numerical example of an up-only market?**

Let's assume a SMART Token design in which RiskOFF is capped at an 8% upside for the epoch (and, in return, gets downside protection beyond a −5% loss), and any upside beyond that accrues to the benefit of RiskON. Start with 1 BTC at $100,000 and mint 2 SMART Tokens worth $50,000 each: one RiskOFF BTC and one RiskON BTC. If BTC finishes the epoch 30% higher at $130,000, the combined value of RiskON and RiskOFF must still sum to $130,000. We know that RiskOFF is capped at 8% ($54,000). The remainder, $76,000, is the value of RiskON which ends the epoch up 52%. Holding one SMART Token each is equivalent to simply holding BTC and it replicates the 30% move of spot BTC. Tilting more of your position into RiskON gives you a steeper payoff than BTC in a strong up-only environment, while tilting more into RiskOFF lets you stay in BTC but with a smoother, partially capped profile even when the market rips higher.

13. **Can you walk through one numerical example of a sharp drawdown?**

Continuing with the hypothetical example above, let's assume that RiskOFF is designed to be cushioned against a drop below −5% (with losses beyond that borne by RiskON). Again, start with 1 BTC at $100,000, split into $50,000 of RiskOFF BTC and $50,000 of RiskON BTC. Now assume BTC finishes the epoch 30% lower at $70,000. The pair still has to add up to $70,000. RiskOFF is designed to end the epoch down by at most 5%, so it ends the period at $47,500. RiskOFF's share of the downside beyond −5% is borne by RiskON. Since the two tokens are designed to add up to the underlying, RiskON's value at the end of the period is $22,500 ($70,000 − $47,500) or down 55%. Holding one of each SMART Token again replicates the −30% move of spot BTC. A portfolio mostly in RiskOFF experiences a drawdown closer to −5% rather than −30%, while a portfolio that leans into RiskON takes a leveraged hit. In both directions, TRP simply redistributes a fully collateralized BTC stack between a defensive and a leveraged bucket according to the payoff rules.

14. **If I dynamically shifted between RiskON and RiskOFF, would I have outperformed holding just BTC or ETH?**

The answer depends on a) how frequently you shifted between RiskON/RiskOFF (e.g. every week, month or quarter) and b) your success in picking the right token for a particular period. With perfect hindsight and timing, dynamically switching between RiskON and RiskOFF would have massively outperformed passive BTC/ETH in our backtests. For BTC, a scenario where you picked the right token every epoch (30 days, i.e., rotating across RiskON/RiskOFF roughly monthly) would have turned:

* A 28% loss in BTC into a 15% gain for the dynamic strategy over the last 1 year (1.6X spot wealth)
* A 132% increase in BTC into a 1,921% increase for the dynamic strategy over the last 3 years (8.7X spot wealth)
* A 13% increase in BTC into a 17,222% increase for the dynamic strategy over the last 5 years (153X spot wealth)

For ETH, the same exercise turns:

* A 20% increase in ETH into a 309% increase for the dynamic strategy over the last 1 year (3.4X spot wealth)
* A 14% increase in ETH into a 2,121% increase for the dynamic strategy over the last 3 years (19.5X spot wealth)
* A 19% loss in ETH into a 38,440% gain for the dynamic strategy over the last 5 years (479X spot wealth)

Now, of course no one will trade perfectly in reality, but the sheer magnitude of the outperformance possible by rotating into the right token for a particular period indicates the alpha potential of such a dynamic strategy, even for lower levels of token selection accuracy.

15. **Can a token go to zero or even negative?**

A SMART Token’s payoff cannot go negative. Each RiskON/RiskOFF token is a fully collateralized claim on the underlying, so its on-chain payoff has a floor at zero—you can lose your stake, but you never owe more than what you put in. In extreme crashes, the RiskON token is intentionally the shock absorber. It can be written down to near-zero (for example, for a token design with a -5% strike on the put, in a \~52.5% intra-epoch crash, RiskON may be taken to pennies so that RiskOFF’s put protection is made whole), but it still does not go negative.

## Utility and Benefits

16. **Why should I care about SMART Tokens as a BTC/ETH holder?**

Because SMART Tokens let you turn a blunt spot position into two precise tools instead of one all-or-nothing bet. With RiskOFF BTC/ETH, you can park most of your stack in a cushioned profile that is designed to soften big drawdowns while still keeping meaningful upside, so your core holdings ride the cycle without getting smashed by every 30–40% dip. With RiskON BTC/ETH, you can concentrate risk and upside into a smaller slice of your capital, effectively “leveraging your conviction” without managing margin, liquidations, or options rolls. Together, they let you stay in BTC/ETH the whole time, but decide how much of your exposure lives in a defensive bucket and how much lives in a high-octane, upside-heavy bucket as market conditions and your views change. RiskON & RiskOFF are designed to be used tactically as your risk mode shifts between RiskON and RiskOFF. In fact, dynamically shifting between RiskON & RiskOFF can dramatically boost your returns vs just holding the underlying BTC or ETH.   &#x20;

17. **How do SMART Tokens help me reduce drawdowns?**

Imagine BTC starts an epoch at $100,000 and you deposit 1 BTC to mint 2 SMART Tokens, each worth $50,000: RiskOFF and RiskON. You then sell your RiskON so that you are holding only RiskOFF. Suppose now BTC falls 40% to $60,000. In an illustrative design where RiskOFF is cushioned beyond a 5% loss, RiskOFF will end the epoch at $47,500 (−5%), while RiskON takes the remaining pain and ends around $12,500 (−75%); together, they still add to $60,000. If you had held spot BTC, you would be down 40%; by holding RiskOFF, you have obtained downside protection by shifting most of the downside to RiskON instead.

18. **How do SMART Tokens help me take a high-conviction bullish view?**

Using the same starting point—1 BTC at $100,000 split into $50,000 RiskOFF and $50,000 RiskON—suppose BTC rallies 50% to $150,000. In an illustrative design where upside above +8% is redirected to RiskON, RiskOFF will end at $54,000 (+8%) while RiskON will end at $96,000 (+92%). Again, the two add to $150,000, but most of the upside has been transferred to RiskON. If you are bullish, you can swap your RiskOFF or BTC for RiskON in order to tilt your portfolio towards that leveraged upside.

19. **What’s the utility of TRP from the perspective of a lending platform?**

Lenders want collateral that is stable, predictable, and unlikely to blow up during market stress.\
TRP’s RiskOFF tokens give them exactly that:

* Lower volatility than BTC/ETH
* Fully collateralized, on-chain, transparent payoff structure
* No hidden leverage or oracle dependencies
* Reduced risk of cascading liquidations

The net benefit is that lending platforms can safely raise LTVs or reduce liquidation thresholds, which leads to higher utilization, more borrowers, and more fees. Fewer liquidation failures = safer lending markets = higher TVL without more risk.

This makes RiskOFF a fundamentally superior version of collateral for lending protocols.

20. **How would a DAO or treasury use TRP in practice?**

Take a DAO with 100 BTC in its treasury. Instead of holding raw BTC, it could allocate the entire stack into RiskOFF BTC, parking its core reserves in a cushioned profile that softens large drawdowns while still keeping some upside. The complementary RiskON leg is effectively sold to market participants seeking leveraged upside, so the DAO ends up holding only RiskOFF BTC in its treasury. This way, if macro turns ugly, the treasury is equipped to ride out the BTC volatility, without needing to negotiate bespoke structured notes or maintain an active derivatives book.

21. **How is this better than just moving into stablecoins or trading perps/options?**

Moving everything into stablecoins kills your upside and forces you to time re-entry. Perps provide leverage, but users’ funds are subject to margin calls and automatic liquidations. Perps also give you linear exposure—gains and losses increase in a straight line as prices move—so you can scale risk up or down, but you cannot change how the position behaves in different market conditions.

Options allow more flexible, non-linear payoffs but require active management, rolling, margin, and expertise, and are subject to counterparty risk. TRP bakes these sophisticated, non-linear risk profiles directly into simple, fully collateralized, non-custodial, tradeable payoffs: instead of managing a derivatives book, you select the SMART Token that matches your risk view and hold it.

## Who is it for?

22. **Who is the target user for RiskON/RiskOFF?**

RiskON/RiskOFF is built for a broad range of users: crypto-native traders and alpha hunters who want clean, on-chain ways to flip between risk-on and risk-off for maximal gains; longer-term BTC/ETH holders who wish to stay in their preferred asset but hate big drawdowns; lending platforms looking for lower-risk, more efficient collateral; DAOs and on-chain treasuries that need systematic, rule-based risk buckets instead of all-or-nothing exposure; and institutions—such as funds, market makers, and family offices—seeking fully collateralized, transparent payoffs they can plug into portfolios, products, or treasury stacks without building the derivatives machinery themselves.

23. **Do I need expertise in derivatives to use TRP?**

No. TRP abstracts away the options and structured-product complexity under the hood, and showcases only simplified SMART Tokens on the surface. You never have to pick strikes, expiries, margin, or worry about Greeks—you just choose between clearly illustrated payoff profiles, then split, swap, provide liquidity, or redeem. If you can think in terms of “more cushioned BTC/ETH” versus “more aggressive BTC/ETH”, you already have the right mental model; the derivatives machinery and risk engine simply ensure those profiles stay fully collateralized and behave as advertised.

24. **Is TRP suitable only for short-term traders or also for long-term holders?**

It works for both. Traders can actively rotate between RiskON and RiskOFF within and across epochs. At the same time, long-term holders can maintain a preferred profile (for example, RiskOFF BTC or ETH) across multiple epochs to smooth the ride without leaving their BTC or ETH holdings. It should be noted that while RiskOFF is a suitable long-term investment, RiskON is better held for shorter periods while switching between risk regimes.&#x20;

## Differentiators

25. **Is this the same as Pendle or yield tokenization protocols?**

No–Pendle tokenizes yield. The Risk Protocol tokenizes risk. Pendle and similar protocols split a yield-bearing position into a principal token and a yield token, so you are mainly trading interest-rate exposure and maximizing APY. The underlying asset must produce a yield for Pendle to work.&#x20;

TRP, on the other hand, splits market risk itself—primarily price volatility—into two tradable buckets or “risk flavors”:

* *RiskOFF*: dampened volatility, drawdown protection, low-risk exposure
* *RiskON*: leveraged volatility exposure, convex upside during high-vol markets

TRP does not need the underlying token to be yield-producing.&#x20;

26. **How are TRP’s SMART Tokens different from other derivative instruments?**

TRP offers a new primitive, not another derivative instrument: With a derivative, you bet on an asset. With TRP, you hold a transformed version of the asset itself. A primitive behaves like a simple asset you own, not a contract you must maintain and monitor. It can be:

* Sent
* Traded
* Used as collateral
* Composed into other protocols
* LP’d or staked in DeFi

Most options and perp platforms (Deribits, GMX, Hyperliquid, Synthetix, etc.), on the other hand, expose positions that are:

* Account-based, not tokenized
* Dependent on margin and liquidation engines
* Non-transferable
* Not ERC-20 assets

27. **How are TRP’s SMART Tokens different from perps?** &#x20;

*Unique Risk Profile*: Perps give you linear leverage with funding-rate risk and liquidations. TRP’s SMART Tokens, on the other hand, provide non-linear exposure and the ability to “bend” the underlying risk/return profile. There are no liquidations, no funding-rate payments, and no margin management. You’re holding a fully collateralized payoff that automatically adjusts to market volatility. Instead of managing leverage, you select a risk flavor (RiskON or RiskOFF) and hold it like any other token.

*Portability*: Because perp positions live inside the protocol’s accounting system, they cannot be moved, cannot be used as collateral elsewhere, and cannot be LP’d or staked like a simple token. Perps aren’t composable across DeFi, and in most cases, they carry all the risks inherent in off-chain, centralized liquidity venues.

*Costs: Perpetuals also incur ongoing funding rate costs, and these rates can significantly eat into your returns—we are talking high single-digit to low double-digit annualized percentages in many cases.* Our SMART Tokens are structured as what's called a "costless collar" under the hood. What that means is that neither one of them pays any premium to the other - the cost is zero. Essentially, RiskOFF is given downside protection (a synthetic put) and gives up upside beyond a cap (a synthetic short call), while RiskON takes the opposite side of that trade. There's no continuous funding bleed—it's a one-time split where RiskON and RiskOFF are direct counterparties to each other in an internal risk swap, not paying rolling interest to maintain their positions.

*Trading Vol*: One can’t really use perps to trade volatility. Perps are linear payoffs and directional—you have to choose direction. You can get high leverage, but you have to bet direction, and you get liquidated if you guess wrong. Our tokens, on the other hand, allow you to trade volatility irrespective of direction—if you are long vol, as long as crypto swings up or down, your position makes a profit. In fact, long vol/short vol is a specific type of SMART Token that we will be offering post-launch.

*Designed for both traders and non-traders*: Finally, TRP products don’t require a derivatives background. They behave like simple tokens you can hold in a wallet, LP into, use as collateral, or integrate into other DeFi protocols’ structured strategies—without ever touching an options chain or perp exchange.

28. **How are TRP’s SMART Tokens different from options?**&#x20;

Options are powerful but complex—implied vols, Greeks, expiries, strikes, premium decay, etc. TRP abstracts away all of that. No constructing various option legs, no rolling positions. You simply choose the level of risk you want, and the protocol handles the mechanics behind the scenes. As a result, SMART Tokens democratize access and expand the market of derivative users in crypto.

29. **How are SMART Tokens different from leveraged tokens?**

Leveraged tokens are good for daily bets but suffer from volatility decay if held for longer periods. Whereas leveraged tokens suffer from volatility, our Smart Tokens are actually built around volatility. Plus, we can create smart tokens over any duration–1 week, 1 month, 1 quarter, etc.

30. **What do you mean when you say crypto lacks risk infrastructure, and what space does TRP occupy?**

Traditional markets have a rich ecosystem of risk products: volatility futures & options, volatility ETNs and ETFs, volatility indices, defined-outcome ETFs, tail-risk hedging, risk-parity strategies, structured products, hedging overlays, etc. Crypto mostly offers spot and perps, with only pockets of structured risk solutions. TRP is building a native on-chain risk layer: programmable ways to isolate, measure, transfer, and warehouse risk that can plug into wallets, treasuries, protocols, and exchanges as a core primitive.

## Safety & Risks&#x20;

31. **Who is building TRP?**

We are a small team that blends deep crypto-native experience with decades of institutional finance expertise. Our team members bring highly specialized backgrounds in DeFi and CeFi protocol design, GTM strategy, quantitative trading, risk management, derivatives structuring and valuation, and volatility modeling and research.&#x20;

Unlike the $18T+ risk market in traditional finance, the team understands there is a significant market gap in decentralized finance and is therefore committed to developing an on-chain risk market in crypto. Learn more under “Our Story” here: <https://www.riskprotocol.io/about>&#x20;

We are supported by senior advisers across risk, trading, engineering, and protocol design & architecture, and we intend to progressively hand more control to the community as governance and the product set mature.

32. **How do the smart contracts, upgrades, and multisig work? Are my funds safe?**

The Risk Protocol is implemented entirely through on-chain smart contracts that enforce predefined, transparent rules. These contracts control how collateral is locked, how SMART Tokens are minted and redeemed, how rebalancing occurs, and how liquidity pools function.

At launch, some core contracts will remain upgradeable for a limited period. This is intentional: TRP is introducing new primitives for on-chain risk transfer, and upgradeability allows us to fix bugs, address edge cases, or refine parameters if something does not behave as intended under real market conditions.

Upgrades and other sensitive protocol actions are governed by a multisig composed of core TRP contributors and independent third parties with aligned incentives. This structure prevents unilateral control by any single actor, including the TRP team itself.

Once the system has been sufficiently battle-tested and we are confident in its long-term behavior, the protocol is designed to transition toward immutable contracts and increasingly on-chain governance, reducing trust assumptions over time.

At all times, user funds remain governed by smart-contract rules rather than human discretion.

33. **Who actually holds my BTC/ETH when I deposit collateral?**

No one takes custody of your funds.

When you deposit BTC or ETH into The Risk Protocol, your assets are locked into on-chain smart contracts. These contracts enforce the rules for minting, trading, rebalancing, and redeeming SMART Tokens. Neither TRP nor any third party can arbitrarily move, freeze, or access your assets.

Your wallet receives SMART Tokens that represent your fully collateralized, on-chain claim on the underlying collateral. Redemption is available anytime and always governed by transparent protocol logic.

34. **What are the main smart contracts involved, and who controls them?**

*Vault*: The Vault is responsible for locking and unlocking collateral. When you deposit, e.g., BTC or ETH, ownership of the underlying asset is transferred to the Vault contract in accordance with fixed rules. No funds are held in discretionary custody. When the required SMART Tokens are redeemed, the Vault releases the corresponding collateral back to the user.&#x20;

*RiskON*: The RiskON contract is an ERC-20/ERC-4626 compatible token contract that tracks ownership of RiskON SMART Tokens. It is open-source and rule-based, and it does not grant special privileges to TRP or any other party.

*RiskOFF*: The RiskOFF contract mirrors RiskON in structure and permissions. It is also ERC-20/ERC-4626-compatible, open-source, and governed entirely by its code.

TRP authors the code but does not have discretionary control over these contracts. All interactions—including those by TRP—are subject to the same rules as any other user.

35. **Is my collateral rehypothecated, lent out, or used elsewhere?**

No. Your collateral is not rehypothecated or lent out. To increase utility for users and facilitate arbitrage, the protocol may allow atomic flashloans of SMART Tokens that must be repaid in the same transaction; otherwise, the transaction fails. These flashloans do not introduce counterparty risk and do not affect users’ ability to redeem their assets at any time. See the “[Trading Bots](/protocol-design-and-specifications/trading-bots)” section in the protocol documentation for more details.&#x20;

36. **What risks still exist even if you don’t have custody of funds?**

Removing custody eliminates a major class of risk, but some risks remain in theory, including:

* *Smart contract risk*: Bugs or vulnerabilities could lead to unintended behavior or exploitation by hackers, even after rigorous audits.
* *Market risk*: RiskON and RiskOFF deliberately redistribute market risk. Choosing the wrong exposure for a given market regime can result in losses.
* *Liquidity risk*: Under extreme conditions, secondary-market liquidity may be thinner, increasing slippage.

These risks are transparent, on-chain, and opt-in.

## New to DeFi? Start here&#x20;

37. &#x20;**Who am I actually trusting when I use this protocol?**

You are not trusting a company, broker, or intermediary. You are interacting directly with on-chain, fully open-sourced smart contracts that operate according to predefined, transparent rules.

Once deployed, these contracts execute automatically and cannot make discretionary decisions. The protocol does not take custody of funds, approve transactions, or intervene in user positions.

38. **Do I still own my assets after I use the platform?**

Yes. You retain full economic ownership of your assets at all times.

When you deposit collateral, it is locked into a smart contract and represented by on-chain tokens that belong to your wallet. The protocol cannot access, move, or reuse your assets outside of the rules you explicitly agree to.

39. **Can the platform freeze, block, or reverse my transactions?**

No. The Risk Protocol is permissionless. It cannot freeze accounts, block users, or reverse transactions. Once a transaction is confirmed on-chain, it is final and enforced by the blockchain itself.

40. **If something goes wrong, who is responsible?**

Unlike centralized platforms, decentralized finance (“DeFi”) protocols do not provide guarantees, refunds, or discretionary intervention. This is the norm and best practice in DeFi.

Users are responsible for understanding how the protocol works and the risks they choose to take. These risks—such as smart-contract risk or market risk—are transparent, predefined, and opt-in, rather than hidden or discretionary.

41. **Why would someone choose this over a centralized platform?**

DeFi offers transparency, predictability, and user control. There is no custody of user assets, no hidden leverage, no off-balance-sheet activity, and no discretionary decision-making. All rules are visible on-chain and apply equally to all users.

For many users, this trade-off—more control and transparency in exchange for greater personal responsibility—is the core value of DeFi.


# Points Program

Real Usage. Real Rewards.

The Points Program is how The Risk Protocol rewards the people who make it work and grow—traders, liquidity providers, referrers, and community contributors who choose to build the protocol alongside us.

Most crypto points programs reward mercenary farming and vanity metrics. RISK Points reward genuine contribution. They accrue across four categories: real protocol usage, referrals that bring in actual users, skill in our monthly Trading Competition, and discretionary recognition for education, feedback, and community building.

The three pages below cover the program in detail:

**Points Principles**—the design philosophy and how points are earned across all four categories.

{% content-ref url="/pages/xkBMJYPsGp6T0S7BoN8E" %}
[Points Principles](/resources/points-program/points-principles)
{% endcontent-ref %}

**Referral Rewards**—rebates for bringing in users who actually trade. People you refer get rewarded too.

{% content-ref url="/pages/00m6gh0Yf5a6N9gxr2JT" %}
[Referral Rewards](/resources/points-program/referral-rewards)
{% endcontent-ref %}

**Trading Competition**—monthly rounds, scoring methodology, and the path to the Risk Championship.

{% content-ref url="/pages/KbhnwaM5H7Z3DCrCE3tI" %}
[Trading Competition](/resources/points-program/trading-competition)
{% endcontent-ref %}


# Points Principles

While many crypto points programs devolve into short-term, extractive farming games, we are returning to first principles to align users with the protocol's long-term health. The program is guided by a transparent set of core principles.

#### Guiding Design Principles

* Reward real, productive protocol usage that strengthens long-term health.
* Reward sustained participation rather than one-off actions.
* Incentivize genuine contribution and disincentivize short-term speculation or system gaming.
* Protect real users by safeguarding against sybil attacks and whale domination.
* Favor early contributors, as early participation holds greater value.
* Treat points as earned reflections of contribution, not entitlements.

#### How Points Are Earned

Points accrue across four primary categories:

**Actual Protocol Usage**

Points are driven by net productive capital, calculated as (Splits - Redeems) + Swaps + (Liquidity Provided - Liquidity Withdrawn). Long-term, net committed capital matters more than short-term flows. Greater weight is placed on net splitting activity and net liquidity provision.

**Referrals**

Rewards are based on real economic contribution, measured by the revenue generated by referred users. Vanity metrics and superficial activity are not rewarded.

**Trading Competition**

This serves as an educational mechanism to help users understand the utility of SMART Tokens in a hands-on environment. It is designed to be interactive, accelerate protocol adoption, and put RiskFi on the DeFi map.

**Discretionary**

Contributions that strengthen the ecosystem in other ways, including user education and feedback, constructive participation, and community building.

***

*The Risk Protocol reserves the right to modify the points program as needed to ensure it remains aligned with these principles and continues to protect genuine contributors.*


# Referral Rewards

Grow the Community. Share in the Value.

The Risk Protocol's Referral Rewards program rewards you for referring users who actually trade and generate protocol revenue. No empty sign-ups. No fake wallets. If your referral produces real revenue for the protocol, both of you earn.

#### How It Works

Generate your referral link during testnet or mainnet. Share it with anyone. When someone joins through your link and makes their first trade, the referral relationship locks in. From that point, every trade your referral makes on mainnet generates rewards for both of you—for a full 12 months.

As a **Referee** (the person who joins), you receive a rebate equivalent to 15% of the protocol fees you generate. Your referrer doesn't eat into your rewards—this 15% is exclusively yours.

As a **Referrer**, you earn a rebate equivalent to 25% of the protocol fees your referral generates, calculated on the net fee after the referee's 15% rebate. Make 30 or more qualified referrals within any rolling 30-day period, and you unlock **Affiliate** status—which boosts your rate to 40%. Once earned, Affiliate status is yours permanently.

These rebates for Referrer and Referee are ultimately converted into RISK points. Individual caps might apply, if needed, to ensure that rewards are distributed fairly and widely across the community.

#### What Counts as a Valid Referral

Your referral must make their first mainnet trade within 30 days and reach a cumulative volume of at least $100 during that period. For referrals that are made during the testnet phase, the 30-day period is measured from the mainnet launch. Until both conditions are met, no rewards accrue to either party. This ensures the program rewards genuine onboarding rather than link spam. If either condition is not met within the 30-day window, the referral relationship is permanently invalidated.

#### Your Referral Dashboard

Track everything in real time: how many referrals you've made, which ones have qualified, the volume they're generating, your accumulated rebates, and your current tier status.


# Trading Competition

Prove Your Edge. Climb the Leaderboard.

The Risk Protocol's Trading Competition is a series of monthly rounds designed to identify and reward the most skilled SMART Token traders. This isn't about who has the deepest pockets—it's about who trades the smartest.

Each round runs for one month. At the end of every round, the top 100 traders become eligible for RISK Points based on their ranking. Points from every round you compete in accumulate toward the **Risk Championship**—a season-long standings of the protocol's most consistent performers.

#### How You're Ranked

Your ranking is determined by two factors: your investment performance and how well you managed your risk. Over each round, we measure your returns ("P\&L Percentage") and your maximum drawdown ("Max Drawdown" or "MDD")—the deepest dip your portfolio took from its peak. For each measure, you are scored against every other eligible participant in the round to determine your percentile rank (the "P\&L Score" and the "Risk Awareness Score", respectively). These scores combine to form a single Final Score. In determining the Final Score, P\&L Score carries a 60% weight, and Risk Awareness carries a 40% weight. The highest Final Score wins. A trader who earned 30% returns but suffered a 25% drawdown might be ranked lower than a trader who earned 20% returns with only a 5% drawdown.

#### [Two Leaderboards](https://app.riskprotocol.io/dashboard), Two Ways to Win

The **Trading Competition Leaderboard** shows a running tally of the top 100 traders, including their returns, drawdowns, and Final Score. Only the top 100 earn RISK Points for that round—but your position within the top 100 determines how much you earn. Rank 1 earns the most. Rank 100 earns the least.

The **Risk Championship Leaderboard** tracks cumulative performance across all competition rounds. Only the top 10 are displayed. Making the Championship requires sustained excellence—one great month won't be enough. The traders who show up round after round, managing risk while generating returns, are the ones who rise to the top. The traders who are on the Risk Championship leaderboard at the end of the points program earn additional RISK Points on top of their monthly haul.

#### Eligibility

To be eligible for any round, you must achieve a minimum net trading volume of $10,000 on testnet and $1,000 on mainnet and be trading on at least 3 separate days during that round. This ensures the leaderboard reflects genuine traders, not bots or one-trade wonders.

The competition is based exclusively on SMART Token performance. As new SMART Tokens launch beyond RiskON/RiskOFF, they'll be added to the eligible asset list.


# General Risk Disclosures

*Coming soon....*


# Privacy Policy

*Coming soon....*


# Terms of Service

*Coming soon....*


