Introduction

Blizzard.finance is a Balancer-like DEX (Decentralized Exchange) running on the Secret Network. It has been created with an emphasis on:

  • Offering competitive rates to traders.
  • Fostering a zero-inflation growth model that pays sustainable returns over time to all stakeholders: traders, LPs, and liquid stakers.
  • Giving all users a simple and elegant trading experience, but optionally exposing advanced features to those who want them.

While other DEXes exist on the Secret Network, they suffer from a number of issues.

Traders experience:

  • Frequently failed trades
  • Laggy routing or outright lack of routing capabilities
  • High slippage on trades

Similarly, liquidity providers experience:

  • "Performance Blindness" - Inability to track the growth of their deposited assets
  • Unsustainable LP rewards that dry up after a few months
  • High impermanent loss for Uniswap-style pools
  • Thin trading volume due to low network adoption, resulting in low yields

Pools

Blizzard.finance is an AMM (Automated Market Maker), not an orderbook exchange. What this means is that instead of placing limit orders, liquidity providers are incentivized to seed liquidity pools with different assets, which can be exchanged by swapping through the liquidity pool.

After providing liquidity to a pool, a user can collect fees from trades across the pool they deposited into (proportional to the share of the pool that their assets account for).

The exchange rates offered by liquidity pools will almost always be the same as market rates due to traders and arbitrageurs bringing the rates Blizzard and other exchanges to market equilibrium.

Blizzard offers Balancer-style weighted pools and Curve-style stable pools.

Pool Usage

Approving the Vault Contract (Required)

Calling increase_allowance lets the vault contract create token transactions on your behalf, making it so that you don't have to manually ensure the exact ratio sent to the pool. This does not raise any trust issues, because:

  • The vault contract's behavior is detailed in the publicly-available source code.
  • Every transaction that the vault contract sends is manually approved by you.

The increase_allowance handlemsg structure is as follows (note that 340282366920938463463374607431768211454 is MAX_INT for possible token balances):

{
    "increase_allowance": {
        "spender": "<vault address>",
        "amount": "340282366920938463463374607431768211454"
    }
}

Calling increase_allowance looks like:

secretcli tx compute execute <token address> \
'{"increase_allowance": { "spender": "<vault addr>", "amount": "..." }}' \
--from <sender account> -b block -y --gas 1500000

Weighted Pool Creation

The create_weighted_pool handlemsg structure is as follows:

{
    "create_weighted_pool": {
        "assets": [
            { "address": "secret123...", "token_code_hash": "..." },
            { "address": "secret123...", "token_code_hash": "..." }
        ],
        "weights": [1, 1],
        "balances": ["100", "100"]
    }
}

Calling create_weighted_pool looks like:

secretcli tx compute execute <vault address> \
'{"create_weighted_pool": {"assets": [...], "weights": [...], "balances": [...] }}' \
--from <deployer account> -b block -y --gas 1500000

Stable Pool Creation

The create_stable_pool handlemsg structure is as follows:

{
    "create_stable_pool": {
        "assets": [
            { "address": "secret123...", "token_code_hash": "abc" },
            { "address": "secret456...", "token_code_hash": "xyz" }
        ],
        "balances": ["100", "100"]
    }
}

Calling create_stable_pool looks like:

secretcli tx compute execute <vault address> \
'{"create_stable_pool": {"assets": [...], "balances": [...] }}' \
--from <deployer account> -b block -y --gas 1500000

Provide Liquidity

The provide_liquidity handlemsg structure is as follows:

{
    "provide_liquidity": {
        "pool_id": 1,
        "pool_amount_out": "100"
    }
}

...where:

  • pool_id is the ID of the pool you're depositing into
  • pool_amount_out is the number of LP shares being minted (for most users, this is calculated client-side in the exchange interface)

Weighted Pools

Blizzard.finance offers weighted pools like those on Balancer.fi, allowing users to control exposure ratios to various assets. The swap math used by weighted pools is only slightly more complicated than traditional 50/50 pools, with the spot price \(SP_i\) being calculated following the equation:

\[ SP_i = \frac{\frac{B_i}{Wi}}{\frac{B_o}{W_o}} \]

Where:

  • \(B_i\) - is the amount of base currency that is being swapped
  • \(W_i\) - is the weight of the base currency
  • \(B_o\) - is the amount of base currency that is being swapped
  • \(W_o\) - is the weight of the quote currency

This adjusted exchange ensures that due to market forces and the exchange rate curve, the token supply in the pool will always reach market equilibrium at the ratio specified by the pool weights .

Stable Pools

Stable pools are meant to hold assets that have a 1-to-1 exchange rate. Examples might include WBTC-SBTC or DAI-USDC. The exchange rate math they use is based on that of the StableSwap pools offered by both Balancer and Curve.fi.

Stable pools have a more "lenient" swap curve, in that they maintain an exchange rate closer to 1:1 for larger amounts, rather than tapering off like a traditional 50/50 or weighted curve. A simple example comparison of a stable pool exchange curve and a traditional swap curve is shown below:

Comparison Image Source: Curve.fi

Miguel Mota has written a very understandable explanation of StableSwap math that can be found here.

Vault Optimization

For both gas efficiency and security reasons, Blizzard pools are created not by deploying individual pool contracts, but rather by instantiating hardcoded structs within the vault contract. As such, there is much lower overhead (i.e. no cross-contract calls required) to execute a swap. The core swap flow is detailed below:

flowchart TB
subgraph Users
u1(Alice)
u2(Bob)
end

subgraph vc[Vault Contract]
direction BT
v[(User Balance Store)]
p1{{Pool}}
p2{{Pool}}
end

u1 --> |Conduct Swap| vc
u2 --> |Conduct Withdraw| vc

p1 -.- |Check price| v
p2 -.- |Check price| v

p1 --> |Routed Swap| p2

v --> |Update balance| v

Query Permits

For DEXes running on most public blockchains, it's simply assumed that all individual user information like LP balances and swap history will be public. However, because Secret Network encrypts its smart contracts and performs all contract operations in a secure compute enclave, this information is shielded.

In order to view sensitive data like LP balances, a query permit must be generated with your signing key. This costs zero gas.

Swaps

Swaps executed within the vault contract by calling the swap handlemsg. In a normal use case, routes are calculated client-side, and passed in as an array of swaps to the endpoint. An overview of the vault contract's process of executing a swap is detailed below:

flowchart 

subgraph User entities
wc[Web client]
u1(secret1...)
end

subgraph Vault
subgraph API
h[Handle Endpoint]
q[Query Endpoint]
end

subgraph Pools
p1((USDC-USDT))
p2((SCRT-USDC))
p1 -- Execute route --> p2
end

end

fdc{{SNO Fee Distributor}}

wc -. Request .-> q
wc -. "Request (permit)" .-> q
q -. Simulate swap .-> Pools

u1 -- Swap tx --> h
u1 -- Deposit tx --> h
u1 -- Withdraw tx --> h
h -- Allocate balances --> Pools
h -- Execute swaps --> Pools
Pools -- "Send fees (sSCRT)" --> fdc

Due to the gas optimizations detailed here, swaps on Blizzard are quite efficient.

Swap Routing

Blizzard's frontend includes a client-side router that routes trades across liquidity pools. This enables users to swap two assets even if a desired asset pair does not exist in one pool, or to find a better exchange rate if existing pool pairs don't offer a favorable amount out.

Conceptual Example Case

Consider a slimmed-down version of Blizzard that only has two pools:

  • Pool 1: USDC, USDT
  • Pool 2: USDC, DAI

If a user wants to swap from USDT to DAI, there's no one pool they can swap through. To make this USDT to DAI exchange happen, the user will first swap through Pool 1 for USDC, then swap the amount out through Pool 2 for DAI. In effect, this provides an equivalent to directly swapping USDT for DAI.

Slippage & Fees

Slippage

As with any AMM that relies on liquidity pools, trades across Blizzard incur slippage (discrepancy between the pool exchange rate and the market rate). Slippage is reduced by swapping through pools with higher liquidity and, in the case of 1:1 trades, swapping through stable pools. When executing a swap, forced slippage can be mitigated by specifying a min_amount_out, which will cause the swap to fail if slippage is too high.

Fees

Swaps across each pool on Blizzard incur a small fee of about 0.35 and are paid as fees to liquidity providers and to SNO holders as referral fees. Blizzard's fee breakdown is as follows:

AmountAllocation
0.125%SNO Holders
0.225%Liquidity Providers (left behind in liquidity pool)

SNO Token

SNO is the token Blizzard ues as its DEX token. Users holding $SNO tokens can choose to trade them, or receive referral fees directly from dex users as detailed in Blizzard's fee model. The SNO token conforms to the SNIP-24 standard for private tokens.

SNO Supply

SNO's supply breakdown is as follows:

PercentUse CaseVesting
8.5%Secret Network airdrop to incentivize new users. Include SCRT Stakers SecretDAO NFTs, Ample agent holders, and OG anons.Phased
4%Launch costsInstant, at launch
15%Seeding SNO/SCRT, SNO/?, ?, ? exchange poolsN/A, owned by the protocol
38%Liquidity MiningDistributed linearly across 10 years after launch. Fixed supply, no continuous minting.
27%Development Fund12% upfront, 12% locked with linear vesting, spread across 4 years.
7.5%Private Raise2 years.

Bridging

Blizzard was created with bridging in mind, and aims to make bridging to and from Secret Network easier. The "Bridge" page in the exchange frontend allows users to bring over assets from other blockchains, wrap them as secret tokens, and LP or swap them.

IBC Bridging

The Cosmos assets listed on Blizzard run on blockchain are running on chains with IBC enabled. This effectively allows said assets to be transferred from their native chains to Secret Network without any sort of multisig or threshold signature solution. To deposit or withdraw IBC assets, clicking the deposit/withdraw buttons on the "Bridge" page will open a IBC transfer dialog that allows users to send their assets to and from Secret Network over IBC.

EVM Bridge

Blizzard.finance lists EVM/ERC20 assets bridged from Axelar, an EVM bridge to Cosmos chains. Assets from the legacy EVM bridge are listed and specified as such, but available liquidity for those is dwindling due to the legacy bridge being gradually phased out. Using the legacy bridge is not recommended for bridging in new assets.

Monero Bridge

Monero (XMR), a private cryptocurrency with shielded senders and amounts, can be bridged to Secret Network as a SNIP-20 token and deposited in Blizzard as liquidity to earn yields.

The bridge, which is not associated with Blizzard.finance, can be found on IPFS here.

(Direct link: ipns://k2k4r8l576wm2szxbondf3zs9nqlroz32jccdkbb1j4p130uzz7jnacr)

Deploys

Blizzard.finance is deployed on:

Mainnet Release

Blizzard.finance has yet to release on Secret Network mainnet.

Testnet Version

⚠️ NOTE: the testnet version will be redeployed after final updates in Q4! ⚠️

Old Testnet Information

The testnet frontend can be found at beta.blizzard.finance. It's running on pulsar-2, which can be added to Keplr here.

Basic Usage

  1. Add pulsar-2 to Keplr. (Link)
  2. Get testnet SCRT from the pulsar-2 faucet. (Link)
  3. Decide which testnet mock tokens you want to try using and add them to Keplr. This is most easily done through the testnet exchange interface's bridge page.
  4. Try swapping! beta.blizzard.finance

Initial Secretcli Setup (only if using CLI)

secretcli config chain-id pulsar-2
secretcli config keyring-backend test
secretcli config node https://pulsar-2.api.trivium.network:26657

secretcli keys add a --recover

# Then input your backup phrase and password

Contract Deployments

Vault

  • Label: 0.tfatk9ka2pd
  • Address: secret1xl9stuagfxj3q0yzjn5j9508ytfge56d6gq36n
  • Code Hash: 70c0dc73b4241a314ce13e36e43c8a7515fba2017fee2774cadd79757ec88c1c

Testnet SSCRT

  • Address: secret18vd8fpwxzck93qlwghaj6arh4p7c5n8978vsyg
  • Code Hash: 9587D60B8E6B078ACE12014CEEEE089530B9FABCD76535D93666A6C127AD8813

Test Token 5 (DAI)

  • Address: secret1ksuh2j2mjxgl0z9xzzpre0kydadmjekkw7qnyk
  • Code Hash: 07630bbdf378273a0ef0d9a59900d4edf19f61dba6c754eb118511e2dbc8b4e9

Test Token 4 (SXMR)

  • Address: secret1anvyj3kcf4a4zlfshp8pfj6qn6y7n9fgrltgwc
  • Code Hash: 07630bbdf378273a0ef0d9a59900d4edf19f61dba6c754eb118511e2dbc8b4e9

Test Token 3 (ALTER)

  • Address: secret1d2qzqud0rvasgsxrnzmlftk5a365jwe8hxs6ln
  • Code Hash: 07630bbdf378273a0ef0d9a59900d4edf19f61dba6c754eb118511e2dbc8b4e9

Test Token 2 (SAXLUSDC)

  • Address: secret10exul2zpl0w8rfsjl4mdf04dzpxlxjgmy5rfh8
  • Code Hash: 07630bbdf378273a0ef0d9a59900d4edf19f61dba6c754eb118511e2dbc8b4e9

Test Token 1 (SATOM)

  • Address: secret17g2z9n9wjvvtvnf9kymyauzgmrfau524qfauna
  • Code Hash: 07630bbdf378273a0ef0d9a59900d4edf19f61dba6c754eb118511e2dbc8b4e9