diff --git a/contracts/secret_contract/src/contract.rs b/contracts/secret_contract/src/contract.rs index 6d91eef..8e17970 100644 --- a/contracts/secret_contract/src/contract.rs +++ b/contracts/secret_contract/src/contract.rs @@ -14,6 +14,10 @@ pub fn instantiate( _info: MessageInfo, msg: InstantiateMsg, ) -> Result { + if !MY_KEYS.is_empty(deps.storage) { + return Err(ContractError::AlreadyInitialized); + } + create_keys(deps, env, msg.end_time)?; Ok(Response::default()) @@ -57,7 +61,9 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result Result { - let my_keys = MY_KEYS.load(deps.storage)?; + let my_keys = MY_KEYS + .load(deps.storage) + .map_err(|_| ContractError::NotInitialized)?; let private = (env.block.time > my_keys.end_time).then(|| my_keys.private_key); Ok(KeysResponse { diff --git a/contracts/secret_contract/src/error.rs b/contracts/secret_contract/src/error.rs index c9f8d4c..4611838 100644 --- a/contracts/secret_contract/src/error.rs +++ b/contracts/secret_contract/src/error.rs @@ -8,4 +8,10 @@ pub enum ContractError { #[error("Invalid End Time")] InvalidEndTime, + + #[error("Already initialized")] + AlreadyInitialized, + + #[error("Not initialized yet")] + NotInitialized, } diff --git a/contracts/secret_contract/src/tests.rs b/contracts/secret_contract/src/tests.rs index 34fe4f8..c340bcd 100644 --- a/contracts/secret_contract/src/tests.rs +++ b/contracts/secret_contract/src/tests.rs @@ -3,6 +3,7 @@ use cosmwasm_std::{testing::*, Timestamp}; use secp256k1::{PublicKey, Secp256k1}; use crate::contract::{instantiate, query}; +use crate::error::ContractError; use crate::msg::{InstantiateMsg, KeysResponse, QueryMsg}; fn setup_contract( @@ -43,6 +44,43 @@ fn proper_initialization() { assert!(PublicKey::from_slice(&value.public).is_ok()); } +#[test] +fn user_cant_reinitialize() { + let time = Timestamp::from_seconds(500); + let mut mock_env = mock_env(); + + mock_env.block.time = time.minus_seconds(5); + + let mut deps = setup_contract(time, mock_env.clone()); + + let info = mock_info( + "creator", + &[Coin { + denom: "earth".to_string(), + amount: Uint128::new(1000), + }], + ); + + let res = query(deps.as_ref(), mock_env.clone(), QueryMsg::GetKeys {}).unwrap(); + let init: KeysResponse = from_binary(&res).unwrap(); + + assert_eq!( + instantiate( + deps.as_mut(), + mock_env.clone(), + info, + InstantiateMsg { + end_time: time.plus_seconds(10), + }, + ), + Err(ContractError::AlreadyInitialized) + ); + let res = query(deps.as_ref(), mock_env, QueryMsg::GetKeys {}).unwrap(); + let upd: KeysResponse = from_binary(&res).unwrap(); + + assert_eq!(init, upd); +} + #[test] fn invalid_time_is_failure() { let time = Timestamp::from_seconds(500); @@ -60,7 +98,10 @@ fn invalid_time_is_failure() { let init_msg = InstantiateMsg { end_time: time }; - instantiate(deps.as_mut(), mock_env, info, init_msg).expect_err("Should fail"); + assert_eq!( + instantiate(deps.as_mut(), mock_env, info, init_msg), + Err(ContractError::InvalidEndTime) + ); } #[test] @@ -92,3 +133,14 @@ fn secret_revealed_after_time_pass() { PublicKey::from_slice(&value.public).unwrap() ); } + +#[test] +fn cannot_fetch_uninitialized_contract() { + let deps = mock_dependencies(); + let mock_env = mock_env(); + + assert_eq!( + query(deps.as_ref(), mock_env, QueryMsg::GetKeys {}), + Err(ContractError::NotInitialized) + ); +}