KUJIRA / TERRA ARCHIVE · READ-ONLY SOURCE
← Archive home

OFFICIAL RELATED CODE · APRIL 2022

Terra ORCA / BLUE interfaces

Original Rust interface bindings and utilities from Team-Kujira’s public kujira-rs repository, preserved at its 24 April 2022 commit.

These are related Terra protocol interfaces, not frontend source or complete deployed contract implementations. The BLUE module describes an order-book interface; it is not the recovered November 2021 BLUE app. All source below is escaped text and is never executed.

Repository
Team-Kujira/kujira-rs
Commit
f11b34f9d73989f6de228f0eeb2ef1f1dc9ac20a
Commit date
24 April 2022, 19:13 UTC · “Add Blue”
Crate version
kujira 0.3.1 · terra-cosmwasm 2.2.0 · CosmWasm 0.16.2
Terra provenance
ORCA’s original documentation refers to aUST, UST, Terra contract addresses and mainnet code ID 3541.
Verification
All ten tracked files match the pinned GitHub tree’s Git blob SHA-1 and byte lengths. SHA-256 values and exact URLs are recorded in the provenance manifest.
License record
Cargo.toml declares Apache-2.0. No separate LICENSE file exists in this pinned tree.

Browse the original files

//! [Kujira's](https://orca.kujira.app/) plug-and-play liquidation queue contract
//! for all CosmWASM compatible Blockchains.
//!
//! Designed to create a backstop of solvency against liquidations on your Protocol, a liquidation
//! queue provides a community-focused and decentralized way of bidding for at-risk collateral. At the same time the
//! gamification of the bidding process creates competition between bidders, allowing market forces to determine
//! a discount percentage.
//!
//! If you're interested in deploying a liquidation queue for your Protocol and having it listed on Orca in front of
//! 50,000+ bidders, reach out in our [Telegragm Group](https://t.me/team_kujira).
//!
//! # Features
//! ### Direct Orca Integration
//! Any contract initialized with this interface can be integrated into the Orca UI at <https://orca.kujira.app/>.
//!
//! The easiest way to do this is by using one of the Code IDs from the deployed contract list below.
//!
//! ### Configurable Pools
//! Full control over the discounts available for bidders. Set the number of pools, and the incremental amount
//! of discount per-pool.
//!
//! ### Closable Pools
//! Optionally close off specific pools from new bids. This can be useful when bootstrapping liquidity in a new
//! liquidation queue, for example, where you close lower percentage pools for a fixed period of time,
//! guaranteeing bidders a minimum discount percentage on liquidations in that time.
//!
//! ### Custom Swappers
//! Allow bidders to place bids in a different asset to the one your Protocol requires repayment in.
//! On Terra we use these for example to support native aUST bidding, where a market requires repayment
//! in UST. The bids can be denominated in yield-bearing aUST right up until the point that the liquidation
//! ocurrs and the market is repaid.
//!
//! ### Delegated Activation
//! No more missed liquidations! When you submit a bid, you can optionally include a delegate address,
//! which is permitted to activate the bid on your behalf. Kujira will have a bot that liquidation queues can
//! be registered with, so that bidders can have their bids automatically activated as soon as the wait_end
//! period expires.
//!
//! # Getting Started
//! ## Deploy A Contract
//! The easiest way to get up and running to to instantiate our own audited contract with the code IDs below.
//! Here is a sample JSON-encoded init message, where the bid denomination is Terra's aUST, and the collateral
//! that is being bid on is the Native Luna, and fees connected to Kujira's [sKUJI Protocol Revenue Pool](https://blue.kujira.app/).
//! ```json
//!  {
//!    "owner": "terra123...",
//!    "market": "terra123...",
//!    "bid_denom": {
//!      "cw20": "terra1ajt556dpzvjwl0kl5tzku3fc3p3knkg9mkv8jl"
//!    },
//!    "collateral_denom": {
//!      "native": "uluna"
//!    },
//!    "bid_threshold": "10000000",
//!    "max_slot": 15,
//!    "premium_rate_per_slot": "0.01",
//!    "waiting_period": 600,
//!    "liquidation_fee": "0.01",
//!    "withdrawal_fee": "0.005",
//!    "fee_address": "terra1vvj874nwtmxk0u0spj83d364xyhqk2e652jrck"
//!  }

//! ```
//!
//! ## Integrating your Market
//!
//! 1. Add the package to Cargo.toml
//!
//! `kujira = "0.2.1"`
//!
//! 2. Extend your contract config to store the address of your new liquidation queue
//! ```rust
//! pub struct Config {
//!   liquidation_contract: Addr,
//!   ..,
//! }
//! ```
//! 3. Transfer funds to the liquidation queue at the point of liquidation
//! ```rust
//! fn liquidate_collateral(deps: DepsMut, ..) -> StdResult<Response> {
//!   // ..
//!   let msg = CosmosMsg::Wasm(WasmMsg::Execute {
//!     contract: config.liquidation_contract,
//!     msg: to_binary(&kujira::orca::ExecuteMsg::ExecuteLiquidation {
//!       exchange_rate,
//!       repay_denom: Denom::Cw20("terra1ajt556dpzvjwl0kl5tzku3fc3p3knkg9mkv8jl"),
//!     }),
//!     funds: coins(collateral_amount, "uluna")
//!   });
//!
//!   Ok(Response::default().add_message(msg))
//! }
//! ```
//!
//! ### Terra
//! - Mainnet: Code ID `3541`
//! - Testnet: Code ID `52750`

use cosmwasm_std::{Addr, Decimal256, Uint128, Uint256};
use cw20::{Cw20ReceiveMsg, Denom};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Create a new liquidation queue.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg {
    /// Contract owner. Allowed to call [ExecuteMsg::UpdateConfig] .
    pub owner: Addr,

    /// Market the holds collateral to be liquidated. Only the market can
    /// call [ExecuteMsg::ExecuteLiquidation] and [Cw20HookMsg::ExecuteLiquidation]
    pub market: Addr,

    /// The denomination of the bids. This is fixed at deployment, however with custom
    /// swappers, the market can be repaid in a different denomination to the bid
    pub bid_denom: Denom,

    /// The collateral that can be liquidated using this liquidation queue
    pub collateral_denom: Denom,

    /// The threshold under which bids are automatically activated when placed
    pub bid_threshold: Uint256,
    /// The total number of pools in this queue
    pub max_slot: u8,
    /// The incremental discount offered per-pool
    pub premium_rate_per_slot: Decimal256,
    /// The amount of time in seconds that a bid must wait until it can be activated
    pub waiting_period: u64,

    /// The amount of the repay amount that is sent to [fee_address](InstantiateMsg::fee_address) when executing a liquidation
    pub liquidation_fee: Decimal256,
    /// The amount of the collateral that is sent to [fee_address](InstantiateMsg::fee_address) when a bid is claimed
    pub withdrawal_fee: Decimal256,
    /// The fee destination address
    pub fee_address: Addr,
}

/// Callable interfaces
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[allow(clippy::large_enum_variant)]
pub enum ExecuteMsg {
    /// Hook to handle (Cw20ExecuteMsg::Send)
    Receive(Cw20ReceiveMsg),

    /// Update queue configuration
    UpdateConfig {
        /// Change the owner
        owner: Option<Addr>,
        /// Change the market
        market: Option<Addr>,

        /// Change the amount of time to wait before a bid can be activated
        waiting_period: Option<u64>,
        /// Change the minimum total bid amount for a bid to require manual activation
        bid_threshold: Option<Uint256>,
        /// Change the discount received per pool
        premium_rate_per_slot: Option<Decimal256>,
        /// Close/open specific pools
        closed_slots: Option<Vec<u8>>,

        /// Update fee taken at liquidation
        liquidation_fee: Option<Decimal256>,
        /// Update fee taken at withdrawal
        withdrawal_fee: Option<Decimal256>,
        /// Update fee destination
        fee_address: Option<Addr>,
    },

    /// Called by an end-user to place a bid
    SubmitBid {
        /// The slot (and therefore discount) selected
        premium_slot: u8,
        /// An optional delegate, who can activate the bid on behalf of the user
        delegate: Option<Addr>,
    },
    /// Retract the bid and withdraw funds
    RetractBid {
        /// The bid idx to be retracted
        bid_idx: Uint128,
        /// The amount of bid to retract. IF omitted, the whole bid is retracted
        amount: Option<Uint256>,
    },

    /// Activate bids to be used for liquidation
    ActivateBids {
        /// If provided, only the selected bids will be activated.
        /// If omitted, the first 30 bids for the sending address
        /// will be activated
        bids_idx: Option<Vec<Uint128>>,
    },
    /// Claim liquidated collateral
    ClaimLiquidations {
        /// If provided, only the selected bids will be claimed.
        /// If omitted, the first 30 bids for the sending address
        /// will be claimed       
        bids_idx: Option<Vec<Uint128>>,
    },

    /// Swap liquidated collateral for the repay denomination.
    /// This is only callable by the `market` as defined in
    /// (InstantiateMsg)
    ExecuteLiquidation {
        /// Optional different address to send the repay amount to
        repay_address: Option<Addr>,

        /// The denomination that the market requires repaying in.
        /// By default this will be the [bid_denom](InstantiateMsg::bid_denom),
        /// however if a compatible Swapper has been
        /// registered with [ExecuteMsg::AddSwapper] then the market
        /// can be repaid in a different denom to that of the bids
        repay_denom: Denom,

        /// The market must provide an exchange rate between the repay
        /// denom and the collateral denom in the form `repay / collateral`
        exchange_rate: Decimal256,
    },
    /// Register a custom swapper to support different [repay](ExecuteMsg::ExecuteLiquidation::repay_denom)
    /// and [bid](InstantiateMsg::bid_denom) denoms
    AddSwapper {
        /// See [SwapperResponse::repay_denom]
        denom: Denom,

        /// See [SwapperResponse::addr]
        address: Addr,
    },

    /// Remove a previously regsitered swapper
    RemoveSwapper { denom: Denom },
}

/// Support for CW20 send messages.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum Cw20HookMsg {
    /// Functionally identical to [ExecuteMsg::ExecuteLiquidation]. Used when [collateral_denom](InstantiateMsg::collateral_denom) is a CW20 token
    ExecuteLiquidation {
        repay_address: Option<Addr>,
        repay_denom: Denom,
        exchange_rate: Decimal256,
    },

    /// Functionally identical to [ExecuteMsg::ExecuteLiquidation]. Used when [bid_denom](InstantiateMsg::bid_denom) is a CW20 token
    SubmitBid {
        premium_slot: u8,
        delegate: Option<Addr>,
    },
}

/// Standard interface to query contract state
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
    /// Current config. Returns [ConfigResponse]
    Config {},

    /// Simulate a liquidation based on the current pool balances. Returns [SimulationResponse]
    Simulate {
        collateral_amount: Uint256,
        repay_denom: Denom,
        exchange_rate: Decimal256,
    },

    /// Query a specific bid by idx. Returns [BidResponse]
    Bid { bid_idx: Uint128 },

    /// Paginate user bids. Upper limit of 30 per page. Returns [BidsResponse]
    BidsByUser {
        bidder: Addr,
        start_after: Option<Uint128>,
        limit: Option<u8>,
    },

    /// Query a specific bid pool. Returns [BidPoolResponse]
    BidPool { bid_slot: u8 },

    /// Paginate bid pools. Upper limit of 30 per page. Returns [BidPoolsResponse]
    BidPools {
        start_after: Option<u8>,
        limit: Option<u8>,
    },

    /// Paginate registered swappers. Upper limit of 30 per page. Returns [SwappersResponse]
    Swappers {
        start_after: Option<String>,
        limit: Option<u8>,
    },
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct ConfigResponse {
    /// See [InstantiateMsg::owner]
    pub owner: Addr,
    /// See [InstantiateMsg::market]
    pub market: Addr,
    /// See [InstantiateMsg::bid_denom]
    pub bid_denom: Denom,
    /// See [InstantiateMsg::collateral_denom]
    pub collateral_denom: Denom,
    /// See [InstantiateMsg::bid_threshold]
    pub bid_threshold: Uint256,
    /// See [InstantiateMsg::max_slot]
    pub max_slot: u8,
    /// See [InstantiateMsg::premium_rate_per_slot]
    pub premium_rate_per_slot: Decimal256,
    /// See [ExecuteMsg::UpdateConfig::closed_slots]
    pub closed_slots: Vec<u8>,

    /// See [InstantiateMsg::waiting_period]
    pub waiting_period: u64,

    /// See [InstantiateMsg::liquidation_fee]
    pub liquidation_fee: Decimal256,
    /// See [InstantiateMsg::withdrawal_fee]
    pub withdrawal_fee: Decimal256,
    /// See [InstantiateMsg::fee_address]
    pub fee_address: Addr,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct SimulationResponse {
    /// A confirmation of the amount of collateral consumed in this liquidation.
    /// The simulation will fail if there are insufficient bids to execute the
    /// liquidation
    pub collateral_amount: Uint256,

    /// The simulated amount repaid to the market
    pub repay_amount: Uint256,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct BidResponse {
    /// A unnique ID for the bid
    pub idx: Uint128,

    /// The premium slot selected in [ExecuteMsg::SubmitBid::premium_slot]
    pub premium_slot: u8,

    /// The address used to place the bid
    pub bidder: Addr,

    /// The remaining bid amount
    pub amount: Uint256,
    /// Allocated and unclaimed liquidated collateral
    pub pending_liquidated_collateral: Uint256,
    /// The epoch timestamp at which the bid can be activated.
    /// IF None, it's already active
    pub wait_end: Option<u64>,

    /// An optionally selected delegate address who may activate the bid
    /// on behalf of the bidder
    pub delegate: Option<Addr>,

    pub product_snapshot: Decimal256,
    pub sum_snapshot: Decimal256,
    pub epoch_snapshot: Uint128,
    pub scale_snapshot: Uint128,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct BidsResponse {
    pub bids: Vec<BidResponse>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct BidPoolResponse {
    /// Total amount of all active bids in this pool
    pub total_bid_amount: Uint256,
    /// The discount applied to bids in this pool
    pub premium_rate: Decimal256,

    /// Whether or not this pool has been closed with [ExecuteMsg::UpdateConfig::closed_slots]
    pub is_closed: bool,
    pub sum_snapshot: Decimal256,
    pub product_snapshot: Decimal256,
    pub current_epoch: Uint128,
    pub current_scale: Uint128,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct BidPoolsResponse {
    pub bid_pools: Vec<BidPoolResponse>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct SwappersResponse {
    pub swappers: Vec<SwapperResponse>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct SwapperResponse {
    /// The repay denom that the swapper swaps the bid_denom into
    pub repay_denom: Denom,
    /// The contract address that implements [SwapperQueryMsg] and [SwapperExecuteMsg]
    pub addr: Addr,
}
//! [Kujira's](https://blue.kujira.app/) order-book style decentralised exchange
//! for all CosmWASM compatible Blockchains.

use cosmwasm_std::{Addr, Decimal256, Uint128, Uint256};
use cw20::{Cw20ReceiveMsg, Denom};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Create a new liquidation queue.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg {
    /// Contract owner. Allowed to update parameters
    pub owner: Addr,

    /// The denoms of the pair
    pub denoms: [Denom; 2],

    /// Order slots are created at specific price points. To support good ranges in a
    /// performant way on a web-based UI, the price bands are trunced to a significant
    /// figure value.
    pub slot_trunc: u8,

    /// The trading fee
    pub fee_amount: Decimal256,

    /// The fee destination address
    pub fee_address: Addr,
}

/// Callable interfaces
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
    /// Hook to handle (Cw20ExecuteMsg::Send)
    Receive(Cw20ReceiveMsg),

    /// Update queue configuration
    UpdateConfig {
        /// Change the owner
        owner: Option<Addr>,

        /// Update trading fee
        fee_amount: Option<Decimal256>,

        /// Update fee destination
        fee_address: Option<Addr>,
    },

    /// Called by an end-user to place a bid
    SubmitOrder {
        /// The price of the ask asset, in terms of the offer asset provided
        ask_price: Decimal256,
    },

    /// Retract the bid and withdraw funds
    RetractOrder {
        /// The order idx to be retracted
        order_idx: Uint128,

        /// The amount of order to retract. IF omitted, the whole order is retracted
        amount: Option<Uint256>,
    },

    /// Claim filled orders
    WithdrawOrder {
        /// If provided, only the selected orders will be withdrawn.
        /// If omitted, the first 30 orders for the sending address
        /// will be withdrawn       
        order_idxs: Option<Vec<Uint128>>,
    },
}

/// Support for CW20 send messages.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum Cw20HookMsg {
    /// Called by an end-user to place a bid
    SubmitOrder {
        /// The price of the ask asset, in terms of the offer asset provided
        ask_price: Decimal256,
    },
}

/// Standard interface to query contract state
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
    /// Current config. Returns [ConfigResponse]
    Config {},

    /// Simulate an order placement based on the current order book. Returns [SimulationResponse]
    Simulate {
        offer_denom: Denom,
        offer_amount: Uint256,
    },

    /// Query a specific order by idx. Returns [OrderResponse]
    Order { order_idx: Uint128 },

    /// Paginate user orders. Upper limit of 30 per page. Returns [OrdersResponse]
    OrdersByUser {
        address: Addr,
        start_after: Option<Uint128>,
        limit: Option<u8>,
    },

    /// Query a specific price. Returns [PriceResponse]
    Price { price: Decimal256 },

    /// Paginate prices. Upper limit of 30 per page. Returns [PricesResponse]
    Prices {
        start_after: Option<Decimal256>,
        limit: Option<u8>,
    },
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct ConfigResponse {
    /// See [InstantiateMsg::owner]
    pub owner: Addr,

    /// See [InstantiateMsg::denoms]
    pub denoms: [Denom; 2],

    /// See [InstantiateMsg::fee_amount]
    pub fee_amount: Decimal256,

    /// See [InstantiateMsg::fee_address]
    pub fee_address: Addr,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct SimulationResponse {
    /// The simulated state of the order following submission, including any instant fills
    pub order: OrderResponse,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct OrderResponse {
    /// A unnique ID for the order
    pub idx: Uint128,

    /// The address used to place the bid
    pub owner: Addr,

    /// The denom provided in [ExecuteMsg::SubmitOrder] or [Cw20HookMsg::SubmitOrder]
    pub ask_denom: Denom,

    /// The ask_price selected in [ExecuteMsg::SubmitOrder::ask_price] or [Cw20HookMsg::SubmitOrder::ask_price]
    pub ask_price: Uint256,

    /// The remaining order amount
    pub offer_amount: Uint256,

    /// Amount of filled bid awaiting withdrawal
    pub ask_amount: Uint256,

    pub product_snapshot: Decimal256,
    pub sum_snapshot: Decimal256,
    pub epoch_snapshot: Uint128,
    pub scale_snapshot: Uint128,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct OrdersResponse {
    pub bids: Vec<OrderResponse>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct PoolResponse {
    /// The ask price of this pool
    pub ask_price: Decimal256,

    /// The offer denom for this pool
    pub offer_denom: Denom,

    /// Total amount of all offers in this pool
    pub total_offer_amount: Uint256,

    pub sum_snapshot: Decimal256,
    pub product_snapshot: Decimal256,
    pub current_epoch: Uint128,
    pub current_scale: Uint128,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct PriceResponse {
    /// The two offer pools for this price. The [PoolResponse::offer_denom] will match the order supplied in [InstantiateMsg::denoms]
    pub pools: [PoolResponse; 2],
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct PricesResponse {
    pub prices: Vec<PriceResponse>,
}
//! Terra-specific tax calculations

use cosmwasm_std::{Coin, Decimal256, Deps, Fraction, StdResult, Uint256};
use std::convert::TryInto;
use terra_cosmwasm::TerraQuerier;

pub fn compute_tax(deps: Deps, coin: &Coin) -> StdResult<Uint256> {
    let terra_querier = TerraQuerier::new(&deps.querier);
    let tax_rate = terra_querier.query_tax_rate()?.rate;
    let tax_rate = Decimal256::from_ratio(tax_rate.numerator(), tax_rate.denominator());
    let tax_cap = Uint256::from((terra_querier.query_tax_cap(coin.denom.to_string())?).cap);
    let amount = Uint256::from(coin.amount);

    Ok(std::cmp::min(tax_rate * amount, tax_cap))
}

pub fn deduct_tax(deps: Deps, coin: Coin) -> StdResult<Coin> {
    let tax_amount = compute_tax(deps, &coin)?;
    Ok(Coin {
        denom: coin.denom,
        amount: (Uint256::from(coin.amount) - tax_amount).try_into()?,
    })
}

src/swapper.rs

Download original ↓
//! Standardized interface to support custom Swappers in [orca](crate::orca)

use cosmwasm_std::{Decimal256, Uint256};
use cw20::Cw20ReceiveMsg;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum SwapperQueryMsg {
    SwapRate {
        /// The amount of the returned asset required for this swap.
        ask_amount: Uint256,
    },
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum SwapperExecuteMsg {
    Receive(Cw20ReceiveMsg),
    /// Execute a Native swap
    Swap {},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum SwapperReceiveMsg {
    /// Execute a CW20 Swap
    Swap {},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct SwapRateResponse {
    /// The exchange rate that the Swapper can achieve for the amount in [SwapperQueryMsg::SwapRate::ask_amount]
    pub exchange_rate: Decimal256,
}
//! Convenience functions for generically handling cw20::Denom

use crate::tax::deduct_tax;
use cosmwasm_std::{to_binary, Addr, BankMsg, Coin, CosmosMsg, Deps, StdResult, Uint128, WasmMsg};
use cw20::{Cw20ExecuteMsg, Denom};

/// Convenience function to generate relevant CosmosMsg for sending either Native or CW20 tokens
pub fn send_denom(
    deps: Deps,
    recipient: &Addr,
    denom: &Denom,
    amount: &Uint128,
) -> StdResult<CosmosMsg> {
    match denom {
        Denom::Cw20(contract_addr) => Ok(CosmosMsg::Wasm(WasmMsg::Execute {
            contract_addr: contract_addr.to_string(),
            funds: vec![],
            msg: to_binary(&Cw20ExecuteMsg::Transfer {
                recipient: recipient.to_string(),
                amount: *amount,
            })?,
        })),
        Denom::Native(native) => Ok(CosmosMsg::Bank(BankMsg::Send {
            to_address: recipient.to_string(),
            amount: vec![deduct_tax(
                deps,
                Coin {
                    denom: native.clone(),
                    amount: *amount,
                },
            )?],
        })),
    }
}
pub mod blue;
pub mod denom;
pub mod orca;
pub mod swapper;
pub mod tax;
[package]
name = "kujira"
version = "0.3.1"
authors = ["Kujira Labs"]
edition = "2018"
description = "Interfaces and utilities for Kujira cosmwasm contracts"
license = "Apache-2.0"
homepage = "https://kujira.app"
repository = "https://github.com/Team-Kujira/kujira-rs"

[features]
backtraces = ["cosmwasm-std/backtraces"]

[dependencies]
cw20 = "0.8.0"
cosmwasm-std = { version = "0.16.2" }
schemars = "0.8.3"
serde = { version = "1.0.127", default-features = false, features = ["derive"] }
terra-cosmwasm = "2.2.0"

# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"

[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
 "generic-array",
]

[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"

[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "const-oid"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"

[[package]]
name = "cosmwasm-crypto"
version = "0.16.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cfd597c4b0ed23ea499841d25169f44ada11e7f10642582d1b1a5a4ebbdebcf"
dependencies = [
 "digest",
 "ed25519-zebra",
 "k256",
 "rand_core 0.5.1",
 "thiserror",
]

[[package]]
name = "cosmwasm-derive"
version = "0.16.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a42e9f5fdb98c1e832fa5f976c14f8fd78063c745da7f62087dccbed46a5610"
dependencies = [
 "syn",
]

[[package]]
name = "cosmwasm-std"
version = "0.16.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4188d87abde650e4e283dfc6c2c17a0d84f316052e12e383254b1bbfcadae84f"
dependencies = [
 "base64",
 "cosmwasm-crypto",
 "cosmwasm-derive",
 "schemars",
 "serde",
 "serde-json-wasm",
 "thiserror",
 "uint",
]

[[package]]
name = "cpufeatures"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
dependencies = [
 "libc",
]

[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"

[[package]]
name = "crypto-bigint"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03"
dependencies = [
 "generic-array",
 "rand_core 0.6.3",
 "subtle",
 "zeroize",
]

[[package]]
name = "crypto-mac"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
dependencies = [
 "generic-array",
 "subtle",
]

[[package]]
name = "curve25519-dalek"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"
dependencies = [
 "byteorder",
 "digest",
 "rand_core 0.5.1",
 "subtle",
 "zeroize",
]

[[package]]
name = "cw0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c497f885a40918a02df7d938c81809965fa05cfc21b3dc591e9950237b5de0a9"
dependencies = [
 "cosmwasm-std",
 "schemars",
 "serde",
 "thiserror",
]

[[package]]
name = "cw20"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a11a2adbd52258f5b4ed5323f62bc6e559f2cefbe52ef0e58290016fde5bb083"
dependencies = [
 "cosmwasm-std",
 "cw0",
 "schemars",
 "serde",
]

[[package]]
name = "der"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4"
dependencies = [
 "const-oid",
]

[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
 "generic-array",
]

[[package]]
name = "dyn-clone"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf"

[[package]]
name = "ecdsa"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372"
dependencies = [
 "der",
 "elliptic-curve",
 "hmac",
 "signature",
]

[[package]]
name = "ed25519-zebra"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a128b76af6dd4b427e34a6fd43dc78dbfe73672ec41ff615a2414c1a0ad0409"
dependencies = [
 "curve25519-dalek",
 "hex",
 "rand_core 0.5.1",
 "serde",
 "sha2",
 "thiserror",
]

[[package]]
name = "elliptic-curve"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b"
dependencies = [
 "crypto-bigint",
 "ff",
 "generic-array",
 "group",
 "pkcs8",
 "rand_core 0.6.3",
 "subtle",
 "zeroize",
]

[[package]]
name = "ff"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f"
dependencies = [
 "rand_core 0.6.3",
 "subtle",
]

[[package]]
name = "generic-array"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
dependencies = [
 "typenum",
 "version_check",
]

[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
 "cfg-if",
 "libc",
 "wasi 0.9.0+wasi-snapshot-preview1",
]

[[package]]
name = "getrandom"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
dependencies = [
 "cfg-if",
 "libc",
 "wasi 0.10.2+wasi-snapshot-preview1",
]

[[package]]
name = "group"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912"
dependencies = [
 "ff",
 "rand_core 0.6.3",
 "subtle",
]

[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"

[[package]]
name = "hmac"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
dependencies = [
 "crypto-mac",
 "digest",
]

[[package]]
name = "itoa"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"

[[package]]
name = "k256"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "903ae2481bcdfdb7b68e0a9baa4b7c9aff600b9ae2e8e5bb5833b8c91ab851ea"
dependencies = [
 "cfg-if",
 "ecdsa",
 "elliptic-curve",
 "sha2",
]

[[package]]
name = "kujira"
version = "0.3.1"
dependencies = [
 "cosmwasm-std",
 "cw20",
 "schemars",
 "serde",
 "terra-cosmwasm",
]

[[package]]
name = "libc"
version = "0.2.120"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09"

[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"

[[package]]
name = "pkcs8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447"
dependencies = [
 "der",
 "spki",
]

[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
 "unicode-xid",
]

[[package]]
name = "quote"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
 "getrandom 0.1.16",
]

[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
 "getrandom 0.2.5",
]

[[package]]
name = "ryu"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"

[[package]]
name = "schemars"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3"
dependencies = [
 "dyn-clone",
 "schemars_derive",
 "serde",
 "serde_json",
]

[[package]]
name = "schemars_derive"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b"
dependencies = [
 "proc-macro2",
 "quote",
 "serde_derive_internals",
 "syn",
]

[[package]]
name = "serde"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [
 "serde_derive",
]

[[package]]
name = "serde-json-wasm"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "042ac496d97e5885149d34139bad1d617192770d7eb8f1866da2317ff4501853"
dependencies = [
 "serde",
]

[[package]]
name = "serde_derive"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_derive_internals"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_json"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
dependencies = [
 "itoa",
 "ryu",
 "serde",
]

[[package]]
name = "sha2"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [
 "block-buffer",
 "cfg-if",
 "cpufeatures",
 "digest",
 "opaque-debug",
]

[[package]]
name = "signature"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4"
dependencies = [
 "digest",
 "rand_core 0.6.3",
]

[[package]]
name = "spki"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32"
dependencies = [
 "der",
]

[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"

[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"

[[package]]
name = "syn"
version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e59d925cf59d8151f25a3bedf97c9c157597c9df7324d32d68991cc399ed08b"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-xid",
]

[[package]]
name = "terra-cosmwasm"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552f18cba2b535d1f8c0e3b3f37696820b954bc7535d2e33909f2a6342302718"
dependencies = [
 "cosmwasm-std",
 "schemars",
 "serde",
]

[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [
 "thiserror-impl",
]

[[package]]
name = "thiserror-impl"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "typenum"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"

[[package]]
name = "uint"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f"
dependencies = [
 "byteorder",
 "crunchy",
 "hex",
 "static_assertions",
]

[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"

[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"

[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"

[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

[[package]]
name = "zeroize"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"
Documentation is available at https://docs.rs/kujira
/target

Wallet connections and transactions are unavailable throughout this historical archive.

← Back to archive