diff --git a/contracts/injective-auction-pool/src/contract.rs b/contracts/injective-auction-pool/src/contract.rs index 4ae4b51..ba106b0 100644 --- a/contracts/injective-auction-pool/src/contract.rs +++ b/contracts/injective-auction-pool/src/contract.rs @@ -1,14 +1,17 @@ -use cosmwasm_std::{attr, entry_point, to_json_binary, Attribute}; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{ + attr, entry_point, to_json_binary, Attribute, Binary, Deps, DepsMut, Env, MessageInfo, + Response, StdResult, +}; use cw2::set_contract_version; - use injective_auction::auction_pool::{Config, ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::error::ContractError; -use crate::executions::{self, settle_auction}; -use crate::helpers::{new_auction_round, validate_percentage}; -use crate::queries; -use crate::state::{Whitelisted, CONFIG, FUNDS_LOCKED, WHITELISTED_ADDRESSES}; +use crate::{ + error::ContractError, + executions::{self, settle_auction}, + helpers::{new_auction_round, validate_percentage}, + queries, + state::{Whitelisted, CONFIG, FUNDS_LOCKED, WHITELISTED_ADDRESSES}, +}; const CONTRACT_NAME: &str = "crates.io:injective-auction-pool"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/contracts/injective-auction-pool/src/error.rs b/contracts/injective-auction-pool/src/error.rs index 8be89ff..344c404 100644 --- a/contracts/injective-auction-pool/src/error.rs +++ b/contracts/injective-auction-pool/src/error.rs @@ -19,7 +19,10 @@ pub enum ContractError { rate: Decimal, }, - #[error("Invalid auction round. Current auction round: {current_auction_round}, auction round: {auction_round}")] + #[error( + "Invalid auction round. Current auction round: {current_auction_round}, auction round: \ + {auction_round}" + )] InvalidAuctionRound { current_auction_round: u64, auction_round: u64, @@ -57,7 +60,10 @@ pub enum ContractError { #[error("Missing auction winning bid")] MissingAuctionWinningBid, - #[error("Insufficient funds. Must deposit at least {min_balance} {native_denom} to instantiate the contract")] + #[error( + "Insufficient funds. Must deposit at least {min_balance} {native_denom} to instantiate \ + the contract" + )] InsufficientFunds { native_denom: String, min_balance: Uint128, diff --git a/contracts/injective-auction-pool/src/executions.rs b/contracts/injective-auction-pool/src/executions.rs index f22eccb..6732a8a 100644 --- a/contracts/injective-auction-pool/src/executions.rs +++ b/contracts/injective-auction-pool/src/executions.rs @@ -1,14 +1,17 @@ -use crate::helpers::{new_auction_round, query_current_auction, validate_percentage}; -use crate::state::{ - Whitelisted, BIDDING_BALANCE, CONFIG, FUNDS_LOCKED, UNSETTLED_AUCTION, WHITELISTED_ADDRESSES, -}; -use crate::ContractError; use cosmwasm_std::{ attr, coins, to_json_binary, BankMsg, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg, }; -use injective_auction::auction::MsgBid; -use injective_auction::auction_pool::ExecuteMsg::TryBid; +use injective_auction::{auction::MsgBid, auction_pool::ExecuteMsg::TryBid}; + +use crate::{ + helpers::{new_auction_round, query_current_auction, validate_percentage}, + state::{ + Whitelisted, BIDDING_BALANCE, CONFIG, FUNDS_LOCKED, UNSETTLED_AUCTION, + WHITELISTED_ADDRESSES, + }, + ContractError, +}; pub fn update_config( deps: DepsMut, diff --git a/contracts/injective-auction-pool/src/helpers.rs b/contracts/injective-auction-pool/src/helpers.rs index 8c8b430..77d84e1 100644 --- a/contracts/injective-auction-pool/src/helpers.rs +++ b/contracts/injective-auction-pool/src/helpers.rs @@ -1,9 +1,5 @@ use std::str::FromStr; -use crate::{ - state::{Auction, BIDDING_BALANCE, CONFIG, TREASURE_CHEST_CONTRACTS, UNSETTLED_AUCTION}, - ContractError, -}; use cosmwasm_std::{ attr, instantiate2_address, to_json_binary, Addr, Attribute, BankMsg, Binary, CodeInfoResponse, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo, OverflowError, QueryRequest, @@ -11,6 +7,11 @@ use cosmwasm_std::{ }; use injective_auction::auction::QueryCurrentAuctionBasketResponse; +use crate::{ + state::{Auction, BIDDING_BALANCE, CONFIG, TREASURE_CHEST_CONTRACTS, UNSETTLED_AUCTION}, + ContractError, +}; + /// Starts a new auction pub(crate) fn new_auction_round( deps: DepsMut, @@ -48,8 +49,9 @@ pub(crate) fn new_auction_round( let auction_winning_bid = auction_winning_bid.ok_or(ContractError::MissingAuctionWinningBid {})?; // the contract won the auction - // NOTE: this is assuming the bot is sending the correct data about the winner of the previous auction - // currently there's no way to query the auction module directly to get this information + // NOTE: this is assuming the bot is sending the correct data about the winner of the + // previous auction currently there's no way to query the auction module + // directly to get this information if deps.api.addr_validate(&auction_winner)? == env.contract.address { // update LP subdenom for the next auction round (increment by 1) let new_subdenom = unsettled_auction.lp_subdenom.checked_add(1).ok_or( @@ -89,7 +91,8 @@ pub(crate) fn new_auction_round( }); } - // reset the bidding balance to 0 if we won, otherwise keep the balance for the next round + // reset the bidding balance to 0 if we won, otherwise keep the balance for the next + // round BIDDING_BALANCE.save(deps.storage, &Uint128::zero())?; let mut messages: Vec = vec![]; @@ -124,8 +127,7 @@ pub(crate) fn new_auction_round( let denom = format!( "factory/{}/auction.{}", - env.contract.address.to_string(), - unsettled_auction.lp_subdenom + env.contract.address, unsettled_auction.lp_subdenom ); messages.push(CosmosMsg::Wasm(WasmMsg::Instantiate2 { @@ -192,11 +194,12 @@ pub(crate) fn new_auction_round( attributes.push(attr("treasure_chest_address", treasure_chest_address.to_string())); attributes.push(attr("new_subdenom", format!("auction.{}", new_subdenom))); - return Ok((messages, attributes)); + Ok((messages, attributes)) } // the contract did NOT win the auction else { - // save the current auction details to the contract state, keeping the previous LP subdenom + // save the current auction details to the contract state, keeping the previous LP + // subdenom UNSETTLED_AUCTION.save( deps.storage, &Auction { @@ -219,7 +222,7 @@ pub(crate) fn new_auction_round( unsettled_auction.auction_round.to_string(), )); attributes.push(attr("new_auction_round", current_auction_round.to_string())); - return Ok((messages, attributes)); + Ok((messages, attributes)) } }, // should only happen on instantiation, initialize LP subdenom & bidding balance to 0 @@ -243,7 +246,7 @@ pub(crate) fn new_auction_round( attributes.push(attr("new_auction_round", current_auction_round.to_string())); attributes.push(attr("lp_subdenom", "auction.0")); - return Ok((messages, attributes)); + Ok((messages, attributes)) }, } } diff --git a/contracts/injective-auction-pool/src/tests/unit_tests.rs b/contracts/injective-auction-pool/src/tests/unit_tests.rs index 7332838..de61c0e 100644 --- a/contracts/injective-auction-pool/src/tests/unit_tests.rs +++ b/contracts/injective-auction-pool/src/tests/unit_tests.rs @@ -1,23 +1,27 @@ -use cosmwasm_std::testing::{ - mock_env, mock_info, BankQuerier, MockApi, MockStorage, MOCK_CONTRACT_ADDR, -}; +use std::marker::PhantomData; + use cosmwasm_std::{ - attr, coin, coins, from_json, to_json_binary, Addr, BankMsg, Binary, CodeInfoResponse, - ContractResult as CwContractResult, CosmosMsg, Decimal, Empty, Env, HexBinary, MemoryStorage, - MessageInfo, OwnedDeps, Querier, QuerierResult, QueryRequest, Uint128, WasmMsg, WasmQuery, + attr, coin, coins, from_json, + testing::{mock_env, mock_info, BankQuerier, MockApi, MockStorage, MOCK_CONTRACT_ADDR}, + to_json_binary, Addr, BankMsg, Binary, CodeInfoResponse, ContractResult as CwContractResult, + CosmosMsg, Decimal, Empty, Env, HexBinary, MemoryStorage, MessageInfo, OwnedDeps, Querier, + QuerierResult, QueryRequest, Uint128, WasmMsg, WasmQuery, }; use cw_ownable::Ownership; -use injective_auction::auction::{Coin, MsgBid, QueryCurrentAuctionBasketResponse}; -use injective_auction::auction_pool::{ - ConfigResponse, ExecuteMsg, InstantiateMsg, QueryMsg, WhitelistedAddressesResponse, +use injective_auction::{ + auction::{Coin, MsgBid, QueryCurrentAuctionBasketResponse}, + auction_pool::{ + ConfigResponse, ExecuteMsg, InstantiateMsg, QueryMsg, WhitelistedAddressesResponse, + }, }; use prost::Message; -use std::marker::PhantomData; use treasurechest::tf::tokenfactory::TokenFactoryType; -use crate::contract::{execute, instantiate, query}; -use crate::state::{BIDDING_BALANCE, FUNDS_LOCKED}; -use crate::ContractError; +use crate::{ + contract::{execute, instantiate, query}, + state::{BIDDING_BALANCE, FUNDS_LOCKED}, + ContractError, +}; pub struct AuctionQuerier { bank: BankQuerier, @@ -33,7 +37,7 @@ impl AuctionQuerier { impl Querier for AuctionQuerier { fn raw_query(&self, bin_request: &[u8]) -> cosmwasm_std::QuerierResult { - let request: QueryRequest = from_json(&Binary::from(bin_request)).unwrap(); + let request: QueryRequest = from_json(Binary::from(bin_request)).unwrap(); match request { QueryRequest::Stargate { path, @@ -85,13 +89,12 @@ impl Querier for AuctionQuerier { pub fn mock_deps_with_querier( _info: &MessageInfo, ) -> OwnedDeps { - let deps = OwnedDeps { + OwnedDeps { storage: MockStorage::default(), api: MockApi::default(), querier: AuctionQuerier::new(), custom_query_type: PhantomData, - }; - deps + } } pub fn init() -> (OwnedDeps, Env) { @@ -131,7 +134,7 @@ pub fn init() -> (OwnedDeps, Env) { let msg = QueryMsg::WhitelistedAddresses {}; let res: WhitelistedAddressesResponse = - from_json(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(res.addresses, vec!["bot".to_string()]); (deps, env) @@ -177,7 +180,7 @@ fn update_config() { // query the config to check if it was updated let msg = QueryMsg::Config {}; - let res: ConfigResponse = from_json(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + let res: ConfigResponse = from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); let config = res.config; assert_eq!(config.rewards_fee, Decimal::percent(20)); assert_eq!(config.rewards_fee_addr, "new_rewards_addr".to_string()); @@ -208,7 +211,7 @@ fn update_ownership() { // ownership should not be updated until accepted let msg = QueryMsg::Ownership {}; - let res: Ownership = from_json(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + let res: Ownership = from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(res.owner.unwrap(), "owner"); // accept ownership as new_owner should work @@ -218,7 +221,7 @@ fn update_ownership() { // query the ownership to check if it was updated let msg = QueryMsg::Ownership {}; - let res: Ownership = from_json(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + let res: Ownership = from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(res.owner.unwrap(), "new_owner"); } @@ -267,7 +270,7 @@ fn add_whitelist_address() { // query the whitelisted addresses to check if it was updated let msg = QueryMsg::WhitelistedAddresses {}; let res: WhitelistedAddressesResponse = - from_json(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!( res.addresses, vec!["another_whitelisted".to_string(), "bot".to_string(), "new_whitelisted".to_string()] @@ -324,7 +327,7 @@ fn remove_whitelisted_address() { // query the whitelisted addresses to check if it was updated let msg = QueryMsg::WhitelistedAddresses {}; let res: WhitelistedAddressesResponse = - from_json(&query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); + from_json(query(deps.as_ref(), env.clone(), msg).unwrap()).unwrap(); assert_eq!(res.addresses, vec![Addr::unchecked("new_whitelisted").to_string()]); } @@ -412,7 +415,7 @@ fn join_pool_fails() { assert_eq!(res, ContractError::PaymentError(cw_utils::PaymentError::NoFunds {})); // join pool sending 2 different denoms should fail - let info = mock_info("robinho", &vec![coin(100, "native_denom"), coin(100, "wrong_denom")]); + let info = mock_info("robinho", &[coin(100, "native_denom"), coin(100, "wrong_denom")]); let res = execute(deps.as_mut().branch(), env.clone(), info, msg.clone()).unwrap_err(); assert_eq!(res, ContractError::PaymentError(cw_utils::PaymentError::MultipleDenoms {})); @@ -585,7 +588,8 @@ fn try_bid_works() { assert!(FUNDS_LOCKED.load(&deps.storage).unwrap()); - // try bid on a basket value that is lower than the highest bid should not fail but not bid either + // try bid on a basket value that is lower than the highest bid should not fail but not bid + // either let info = mock_info("bot", &[]); let msg = ExecuteMsg::TryBid { auction_round: 1, @@ -665,7 +669,8 @@ fn try_bid_fails() { assert_eq!(res, ContractError::PaymentError(cw_utils::PaymentError::NonPayable {})); } -// TODO: to test settle auction, need to comment the line that checks if the auction round is valid on executions.rs +// TODO: to test settle auction, need to comment the line that checks if the auction round is valid +// on executions.rs // // use crate::state::{TREASURE_CHEST_CONTRACTS, UNSETTLED_AUCTION}; // #[test] @@ -793,8 +798,8 @@ fn try_bid_fails() { // assert_eq!( // res.messages[3].msg, -// TokenFactoryType::Injective.create_denom(Addr::unchecked(MOCK_CONTRACT_ADDR), "auction.2") -// ); +// TokenFactoryType::Injective.create_denom(Addr::unchecked(MOCK_CONTRACT_ADDR), +// "auction.2") ); // assert_eq!( // res.attributes, diff --git a/packages/injective_auction/src/auction_pool.rs b/packages/injective_auction/src/auction_pool.rs index eb2f917..447844a 100644 --- a/packages/injective_auction/src/auction_pool.rs +++ b/packages/injective_auction/src/auction_pool.rs @@ -21,13 +21,15 @@ pub struct InstantiateMsg { #[cw_serde] pub enum ExecuteMsg { UpdateConfig { - /// Percentage of the rewards that the rewards fee address will take. Value is between 0 and 1 + /// Percentage of the rewards that the rewards fee address will take. Value is between 0 + /// and 1 rewards_fee: Option, /// Address to receive the rewards fee rewards_fee_addr: Option, /// Minimum next bid increment rate for the auction. Value is between 0 and 1 min_next_bid_increment_rate: Option, - /// The minimum return allowed in percentage. 5% means the contract cannot bid for more than 95% of the basket value + /// The minimum return allowed in percentage. 5% means the contract cannot bid for more + /// than 95% of the basket value min_return: Option, }, /// Updates the whitelisted addresses that can bid on or settle the auction. @@ -52,7 +54,8 @@ pub enum ExecuteMsg { }, /// Can be called by the user before T-1 day from auction's end to exit the auction. ExitPool {}, - /// Settles the auction, sending the rewards to the vault in case the contract won the auction. Called by the bot. + /// Settles the auction, sending the rewards to the vault in case the contract won the auction. + /// Called by the bot. SettleAuction { /// The auction round to settle auction_round: u64, @@ -124,6 +127,7 @@ pub struct Config { pub min_next_bid_increment_rate: Decimal, /// Treasury chest code id to instantiate a new treasury chest contract pub treasury_chest_code_id: u64, - /// The minimum return allowed in percentage. 5% means the contract cannot bid for more than 95% of the basket value + /// The minimum return allowed in percentage. 5% means the contract cannot bid for more than + /// 95% of the basket value pub min_return: Decimal, }