diff --git a/contracts/auction/auctions_manager/src/contract.rs b/contracts/auction/auctions_manager/src/contract.rs index 280d8cd1..6d037101 100644 --- a/contracts/auction/auctions_manager/src/contract.rs +++ b/contracts/auction/auctions_manager/src/contract.rs @@ -16,7 +16,7 @@ use valence_package::event_indexing::ValenceEvent; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}; -use crate::state::AUCTION_CODE_ID; +use crate::state::{AUCTION_CODE_ID, SERVER_ADDR}; const CONTRACT_NAME: &str = "crates.io:auctions-manager"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -33,6 +33,7 @@ pub fn instantiate( set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; ADMIN.save(deps.storage, &info.sender)?; + SERVER_ADDR.save(deps.storage, &deps.api.addr_validate(&msg.server_addr)?)?; AUCTION_CODE_ID.save(deps.storage, &msg.auction_code_id)?; for min_amount in msg.min_auction_amount { @@ -93,6 +94,7 @@ pub fn execute( Ok(Response::default().add_message(msg)) } ExecuteMsg::Admin(admin_msg) => admin::handle_msg(deps, env, info, *admin_msg), + ExecuteMsg::Server(server_msg) => server::handle_msg(deps, env, info, server_msg), ExecuteMsg::ApproveAdminChange {} => { let event = ValenceEvent::AuctionManagerApproveAdminChange {}; Ok(approve_admin_change(deps, &env, &info)?.add_event(event.into())) @@ -100,6 +102,40 @@ pub fn execute( } } +mod server { + use cosmwasm_std::{ensure, to_json_binary, WasmMsg}; + + use crate::msg::ServerMsgs; + + use super::*; + + pub fn handle_msg( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: ServerMsgs, + ) -> Result { + // Verify that the sender is the server + let server_addr = SERVER_ADDR.load(deps.storage)?; + ensure!(info.sender == server_addr, ContractError::NotServer); + + match msg { + ServerMsgs::OpenAuction { pair, params } => { + let pair_addr = PAIRS.load(deps.storage, pair)?; + let msg = WasmMsg::Execute { + contract_addr: pair_addr.to_string(), + msg: to_json_binary(&auction::msg::ExecuteMsg::Admin(Box::new( + auction::msg::AdminMsgs::StartAuction(params), + )))?, + funds: vec![], + }; + + Ok(Response::default().add_message(msg)) + } + } + } +} + mod admin { use auction_package::helpers::{cancel_admin_change, start_admin_change, verify_admin}; use cosmwasm_std::{to_json_binary, SubMsg, WasmMsg}; @@ -179,18 +215,6 @@ mod admin { Ok(Response::default().add_message(msg)) } - AdminMsgs::OpenAuction { pair, params } => { - let pair_addr = PAIRS.load(deps.storage, pair)?; - let msg = WasmMsg::Execute { - contract_addr: pair_addr.to_string(), - msg: to_json_binary(&auction::msg::ExecuteMsg::Admin(Box::new( - auction::msg::AdminMsgs::StartAuction(params), - )))?, - funds: vec![], - }; - - Ok(Response::default().add_message(msg)) - } AdminMsgs::UpdateAuctionId { code_id } => { AUCTION_CODE_ID.save(deps.storage, &code_id)?; @@ -268,6 +292,13 @@ mod admin { Ok(Response::default().add_event(event.into())) } + AdminMsgs::ChangeServerAddr { addr } => { + SERVER_ADDR.save(deps.storage, &deps.api.addr_validate(&addr)?)?; + + let event = ValenceEvent::AuctionManagerChangeServerAddr { addr }; + + Ok(Response::default().add_event(event.into())) + } AdminMsgs::StartAdminChange { addr, expiration } => { let event = ValenceEvent::AuctionManagerStartAdminChange { admin: addr.clone(), @@ -317,6 +348,7 @@ pub fn query(deps: Deps, _env: Env, msg: AuctionsManagerQueryMsg) -> StdResult to_json_binary(&ADMIN.load(deps.storage)?), + AuctionsManagerQueryMsg::GetServerAddr => to_json_binary(&SERVER_ADDR.load(deps.storage)?), } } diff --git a/contracts/auction/auctions_manager/src/error.rs b/contracts/auction/auctions_manager/src/error.rs index 9e40825c..980e3011 100644 --- a/contracts/auction/auctions_manager/src/error.rs +++ b/contracts/auction/auctions_manager/src/error.rs @@ -32,6 +32,9 @@ pub enum ContractError { #[error("Not the new admin")] NotNewAdmin, + #[error("Sender is not the server")] + NotServer, + #[error("Not the new admin")] AdminChangeExpired, } diff --git a/contracts/auction/auctions_manager/src/msg.rs b/contracts/auction/auctions_manager/src/msg.rs index 54fe0429..f32de7f4 100644 --- a/contracts/auction/auctions_manager/src/msg.rs +++ b/contracts/auction/auctions_manager/src/msg.rs @@ -9,6 +9,7 @@ use cw_utils::Expiration; pub struct InstantiateMsg { pub auction_code_id: u64, pub min_auction_amount: Vec<(String, MinAmount)>, + pub server_addr: String, } #[cw_serde] @@ -18,6 +19,7 @@ pub enum ExecuteMsg { FinishAuction { pair: Pair, limit: u64 }, ApproveAdminChange {}, Admin(Box), + Server(ServerMsgs), } #[cw_serde] @@ -26,6 +28,14 @@ pub enum MigrateMsg { ToV1 {}, } +#[cw_serde] +pub enum ServerMsgs { + OpenAuction { + pair: Pair, + params: NewAuctionParams, + }, +} + #[cw_serde] pub enum AdminMsgs { NewAuction { @@ -33,10 +43,6 @@ pub enum AdminMsgs { label: String, min_amount: Option, }, - OpenAuction { - pair: Pair, - params: NewAuctionParams, - }, PauseAuction { pair: Pair, }, @@ -70,6 +76,9 @@ pub enum AdminMsgs { code_id: u64, msg: auction::msg::MigrateMsg, }, + ChangeServerAddr { + addr: String, + }, StartAdminChange { addr: String, expiration: Expiration, diff --git a/contracts/auction/auctions_manager/src/state.rs b/contracts/auction/auctions_manager/src/state.rs index 70544bec..f1916940 100644 --- a/contracts/auction/auctions_manager/src/state.rs +++ b/contracts/auction/auctions_manager/src/state.rs @@ -1,3 +1,5 @@ +use cosmwasm_std::Addr; use cw_storage_plus::Item; +pub const SERVER_ADDR: Item = Item::new("server_addr"); pub const AUCTION_CODE_ID: Item = Item::new("auction_code_id"); diff --git a/packages/auction-package/src/msgs.rs b/packages/auction-package/src/msgs.rs index eeda1781..11c6735d 100644 --- a/packages/auction-package/src/msgs.rs +++ b/packages/auction-package/src/msgs.rs @@ -38,4 +38,7 @@ pub enum AuctionsManagerQueryMsg { #[returns(Addr)] GetAdmin, + + #[returns(Addr)] + GetServerAddr, } diff --git a/packages/valence-package/src/event_indexing.rs b/packages/valence-package/src/event_indexing.rs index a39740a3..124d50e4 100644 --- a/packages/valence-package/src/event_indexing.rs +++ b/packages/valence-package/src/event_indexing.rs @@ -114,6 +114,9 @@ where AuctionManagerStartAdminChange { admin: String, }, + AuctionManagerChangeServerAddr { + addr: String, + }, AuctionManagerCancelAdminChange {}, AuctionManagerApproveAdminChange {}, @@ -325,6 +328,9 @@ impl fmt::Display for ValenceGenericEvent { ValenceGenericEvent::AuctionManagerApproveAdminChange {} => { write!(f, "auction-manager-approve-admin-change") } + ValenceGenericEvent::AuctionManagerChangeServerAddr { .. } => { + write!(f, "auction-manager-change-server-addr") + } // auctions ValenceGenericEvent::AuctionInit { .. } => write!(f, "auction-init"), diff --git a/tests/rust-tests/src/suite/instantiates/auctions_manager.rs b/tests/rust-tests/src/suite/instantiates/auctions_manager.rs index 85244e20..0c776907 100644 --- a/tests/rust-tests/src/suite/instantiates/auctions_manager.rs +++ b/tests/rust-tests/src/suite/instantiates/auctions_manager.rs @@ -14,11 +14,11 @@ impl From for auctions_manager::msg::InstantiateMsg } impl AuctionsManagerInstantiate { - pub fn default(auction_code_id: u64) -> Self { - Self::new(auction_code_id) + pub fn default(auction_code_id: u64, server_addr: String) -> Self { + Self::new(auction_code_id, server_addr) } - pub fn new(auction_code_id: u64) -> Self { + pub fn new(auction_code_id: u64, server_addr: String) -> Self { let min_auction_amount = vec![ ( ATOM.to_string(), @@ -47,6 +47,7 @@ impl AuctionsManagerInstantiate { msg: auctions_manager::msg::InstantiateMsg { auction_code_id, min_auction_amount, + server_addr, }, } } diff --git a/tests/rust-tests/src/suite/suite_auction.rs b/tests/rust-tests/src/suite/suite_auction.rs index ebca2a50..27038ac3 100644 --- a/tests/rust-tests/src/suite/suite_auction.rs +++ b/tests/rust-tests/src/suite/suite_auction.rs @@ -113,17 +113,17 @@ impl Suite { end_block: u64, ) -> Result { self.app.execute_contract( - self.admin.clone(), + self.mm.clone(), self.auctions_manager_addr.clone(), - &auctions_manager::msg::ExecuteMsg::Admin(Box::new( - auctions_manager::msg::AdminMsgs::OpenAuction { + &auctions_manager::msg::ExecuteMsg::Server( + auctions_manager::msg::ServerMsgs::OpenAuction { pair, params: NewAuctionParams { start_block, end_block, }, }, - )), + ), &[], ) } @@ -626,6 +626,23 @@ impl Suite { self.astro_swap(pool_addr, coin) } + + pub fn change_server_addr(&mut self, addr: Addr) -> &mut Self { + self.app + .execute_contract( + self.admin.clone(), + self.auctions_manager_addr.clone(), + &auctions_manager::msg::ExecuteMsg::Admin(Box::new( + auctions_manager::msg::AdminMsgs::ChangeServerAddr { + addr: addr.to_string(), + }, + )), + &[], + ) + .unwrap(); + + self + } } // Queries @@ -771,6 +788,16 @@ impl Suite { .unwrap(); total_got / Decimal::from_atomics(multiply, 0).unwrap() } + + pub fn query_server_addr(&self) -> Addr { + self.app + .wrap() + .query_wasm_smart( + self.auctions_manager_addr.clone(), + &auction_package::msgs::AuctionsManagerQueryMsg::GetServerAddr {}, + ) + .unwrap() + } } // Helpers diff --git a/tests/rust-tests/src/suite/suite_builder.rs b/tests/rust-tests/src/suite/suite_builder.rs index 37e0e9c3..44d53c77 100644 --- a/tests/rust-tests/src/suite/suite_builder.rs +++ b/tests/rust-tests/src/suite/suite_builder.rs @@ -232,7 +232,7 @@ impl SuiteBuilder { // init Auctions manager contract let auctions_manager_addr = self.init_auctions_manager( app, - AuctionsManagerInstantiate::new(self.auction_code_id).into(), + AuctionsManagerInstantiate::new(self.auction_code_id, self.mm.to_string()).into(), ); // init price_oracle contract diff --git a/tests/rust-tests/src/tests_auctions/test_auction.rs b/tests/rust-tests/src/tests_auctions/test_auction.rs index cebf63df..eed3318c 100644 --- a/tests/rust-tests/src/tests_auctions/test_auction.rs +++ b/tests/rust-tests/src/tests_auctions/test_auction.rs @@ -1,6 +1,9 @@ use core::panic; -use auction::state::{ActiveAuction, ActiveAuctionStatus}; +use auction::{ + msg::NewAuctionParams, + state::{ActiveAuction, ActiveAuctionStatus}, +}; use auction_package::{error::AuctionError, states::TWAP_PRICES}; use cosmwasm_std::{ coin, coins, from_json, testing::mock_env, Addr, Binary, Decimal, Timestamp, Uint128, @@ -976,3 +979,40 @@ fn test_all_pairs_query() { let pairs = suite.query_auctions_manager_all_pairs(); assert!(!pairs.is_empty()) } + +#[test] +fn test_only_server_can_open_auction() { + let mut suite = Suite::default(); + + suite.auction_funds( + suite.get_account_addr(0), + suite + .auction_addrs + .get(&suite.pair.clone().into()) + .unwrap() + .clone(), + &coins(10_u128, suite.pair.0.clone()), + ); + + let err = suite + .app + .execute_contract( + suite.admin.clone(), + suite.auctions_manager_addr.clone(), + &auctions_manager::msg::ExecuteMsg::Server( + auctions_manager::msg::ServerMsgs::OpenAuction { + pair: suite.pair, + params: NewAuctionParams { + start_block: None, + end_block: suite.app.block_info().height + 1000, + }, + }, + ), + &[], + ) + .unwrap_err() + .downcast::() + .unwrap(); + + assert_eq!(err, auctions_manager::error::ContractError::NotServer) +} diff --git a/tests/rust-tests/src/tests_auctions/test_auctions_manager.rs b/tests/rust-tests/src/tests_auctions/test_auctions_manager.rs index 00829015..f3ede2d1 100644 --- a/tests/rust-tests/src/tests_auctions/test_auctions_manager.rs +++ b/tests/rust-tests/src/tests_auctions/test_auctions_manager.rs @@ -307,3 +307,14 @@ fn test_update_admin_fails() { ) .unwrap_err(); } + +#[test] +fn test_change_server_addr() { + let mut suite = Suite::default(); + let new_server_addr = Addr::unchecked("new_server_addr"); + + suite.change_server_addr(new_server_addr.clone()); + + let server_addr = suite.query_server_addr(); + assert_eq!(server_addr, new_server_addr); +} diff --git a/tests/rust-tests/src/tests_auctions/test_instantiates.rs b/tests/rust-tests/src/tests_auctions/test_instantiates.rs index 713c267e..0d928484 100644 --- a/tests/rust-tests/src/tests_auctions/test_instantiates.rs +++ b/tests/rust-tests/src/tests_auctions/test_instantiates.rs @@ -17,7 +17,7 @@ fn test_instantiate_auction_manager() { let manager_addr = builder.init_auctions_manager( app.borrow_mut(), - AuctionsManagerInstantiate::default(builder.auction_code_id).into(), + AuctionsManagerInstantiate::default(builder.auction_code_id, builder.mm.to_string()).into(), ); let admin_addr = SuiteBuilder::query_wasm_raw_item(&app, manager_addr.clone(), ADMIN); @@ -39,7 +39,7 @@ fn test_instantiate_oracle() { let manager_addr = builder.init_auctions_manager( app.borrow_mut(), - AuctionsManagerInstantiate::default(builder.auction_code_id).into(), + AuctionsManagerInstantiate::default(builder.auction_code_id, builder.mm.to_string()).into(), ); let oracle_addr = builder.init_oracle(