diff --git a/src/contract.rs b/src/contract.rs index 78878c4..a2dd427 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -13,14 +13,14 @@ use cw_storage_plus::Bound; use cw_utils::{NativeBalance, PaymentError}; use fuzion_flows::{FlowCreate, FlowSchedule, FlowType}; use fuzion_utilities::{Asset, AssetList, DenomUnit, LogoURIs}; -use kujira::{DenomMsg, KujiraMsg, KujiraQuery, Precision}; +use kujira::{DenomMsg, KujiraMsg, KujiraQuerier, KujiraQuery, Precision}; use kujira_orca::BidPoolsResponse; -use kujira_pilot::Status; +use kujira_pilot::{CreateOrca, CreateSale, Status}; use crate::launch::Launch; use crate::msg::{ - Bow, CallbackType, CategoryTypes, Config, Fin, LaunchStatus, Pilot, ReplyInfo, ReplyTypes, - Token, Tokenomics, + BidDenoms, Bow, CallbackType, CategoryTypes, Config, Fin, LaunchStatus, Pilot, ReplyInfo, + ReplyTypes, Token, Tokenomics, TokenomicsCategories, }; use crate::state::{launch, CONFIG, REPLY}; use crate::{ContractError, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; @@ -28,6 +28,43 @@ use crate::{ContractError, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; const CONTRACT_NAME: &str = "fuzion-kujira-keiko"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +pub fn assert_min_sale_amount( + kujira_querier: &KujiraQuerier, + config: &Config, + bid_denom: &BidDenoms, + sale_category: &TokenomicsCategories, + sale: &CreateSale, + orca: &CreateOrca, +) -> Result<(), ContractError> { + let oracle_price = kujira_querier.query_exchange_rate( + bid_denom + .oracle_symbol + .clone() + .unwrap_or(bid_denom.symbol.to_string()), + )?; + let normalized_usd_price = oracle_price.normalize(bid_denom.decimals); + let launch_min_raise_amount = sale_category.recipients[0] + .amount + .mul(sale.price) + .mul( + Decimal::one().sub( + Decimal::from_str(&orca.max_slot.to_string()) + .unwrap() + .mul(orca.premium_rate_per_slot), + ), + ) + .mul(normalized_usd_price); + + ensure!( + launch_min_raise_amount > config.pilot.min_raise_amount, + ContractError::InvalidRaiseAmount( + launch_min_raise_amount.to_string(), + config.pilot.min_raise_amount.to_string() + ) + ); + Ok(()) +} + #[entry_point] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; @@ -389,7 +426,10 @@ pub fn execute( .iter() .find(|d| d.denom == orca.bid_denom.clone()); - ensure!(bid_denom.is_some(), ContractError::InvalidBidDenom {}); + ensure!( + bid_denom.clone().is_some(), + ContractError::InvalidBidDenom {} + ); let categories = launch.clone().tokenomics.unwrap().categories; @@ -398,19 +438,14 @@ pub fn execute( .find(|c| c.category_type == CategoryTypes::Sale) .unwrap(); - let launch_min_raise_amount = sale_category.recipients[0].amount.mul(sale.price).mul( - Decimal::from_str(&orca.max_slot.to_string()) - .unwrap() - .mul(orca.premium_rate_per_slot), - ); - - ensure!( - launch_min_raise_amount > config.pilot.min_raise_amount, - ContractError::InvalidRaiseAmount( - launch_min_raise_amount.to_string(), - config.pilot.min_raise_amount.to_string() - ) - ); + assert_min_sale_amount( + &KujiraQuerier::new(&deps.querier), + &config, + bid_denom.unwrap(), + sale_category, + &sale, + &orca, + )?; let mut pilot = Pilot { idx: None, @@ -501,13 +536,21 @@ pub fn execute( launch.pilot.clone().unwrap().sale }; + let orca = launch.pilot.clone().unwrap().orca; + + assert_min_sale_amount( + &KujiraQuerier::new(&deps.querier), + &config, + bid_denom.unwrap(), + sale_category, + &sale, + &orca, + )?; + messages.push(SubMsg::reply_on_success( CosmosMsg::Wasm(wasm_execute( config.pilot.pilot_contract, - &kujira_pilot::ExecuteMsg::Create { - sale, - orca: launch.pilot.clone().unwrap().orca, - }, + &kujira_pilot::ExecuteMsg::Create { sale, orca }, vec![pilot_config.deposit, sale_funds], )?), ReplyTypes::Create as u64, diff --git a/src/msg.rs b/src/msg.rs index 50c6c84..38e7a2f 100644 --- a/src/msg.rs +++ b/src/msg.rs @@ -214,6 +214,7 @@ impl fmt::Display for LaunchStatus { pub struct BidDenoms { pub denom: Denom, pub symbol: String, + pub oracle_symbol: Option, pub decimals: u8, } diff --git a/src/tests.rs b/src/tests.rs index 33960df..a3a278e 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -194,6 +194,7 @@ fn launch_new_token() { allowed_bid_denoms: vec![BidDenoms { denom: Denom::from("bid"), symbol: "bid".to_string(), + oracle_symbol: None, decimals: 6, }], min_raise_amount: Uint128::from(100_000_000_000u128), @@ -749,6 +750,7 @@ fn launch_own_token() { allowed_bid_denoms: vec![BidDenoms { denom: Denom::from("bid"), symbol: "bid".to_string(), + oracle_symbol: None, decimals: 6, }], min_raise_amount: Uint128::from(100_000_000_000u128), @@ -1249,6 +1251,7 @@ fn launch_own_token_18_decimals() { allowed_bid_denoms: vec![BidDenoms { denom: Denom::from("bid"), symbol: "bid".to_string(), + oracle_symbol: None, decimals: 6, }], min_raise_amount: Uint128::from(100_000_000_000u128),