Skip to content

Commit

Permalink
Extend Proposal with Title and Description fields (#44)
Browse files Browse the repository at this point in the history
* Extend Proposal with Title and Description fields

* CR fix
  • Loading branch information
dusan-maksimovic authored Jul 16, 2024
1 parent 4c1f458 commit d4fa931
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 5 deletions.
31 changes: 29 additions & 2 deletions contracts/atom_wars/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

pub const MAX_LOCK_ENTRIES: usize = 100;

pub const MIN_PROP_TITLE_LENGTH: usize = 3;
pub const MAX_PROP_TITLE_LENGTH: usize = 256;
pub const MAX_PROP_DESC_LENGTH: usize = 10000;

#[entry_point]
pub fn instantiate(
deps: DepsMut,
Expand Down Expand Up @@ -111,8 +115,10 @@ pub fn execute(
ExecuteMsg::UnlockTokens {} => unlock_tokens(deps, env, info),
ExecuteMsg::CreateProposal {
tranche_id,
title,
description,
covenant_params,
} => create_proposal(deps, env, tranche_id, covenant_params),
} => create_proposal(deps, env, tranche_id, title, description, covenant_params),
ExecuteMsg::Vote {
tranche_id,
proposal_id,
Expand Down Expand Up @@ -363,6 +369,8 @@ fn create_proposal(
deps: DepsMut,
env: Env,
tranche_id: u64,
title: String,
description: String,
covenant_params: CovenantParams,
) -> Result<Response, ContractError> {
TRANCHE_MAP.load(deps.storage, tranche_id)?;
Expand All @@ -371,11 +379,15 @@ fn create_proposal(
let round_id = compute_current_round_id(&env, &constants)?;
let proposal_id = PROP_ID.load(deps.storage)?;

// Create proposal in PropMap
let title = sanitize_input_string(title, MIN_PROP_TITLE_LENGTH, MAX_PROP_TITLE_LENGTH)?;
let description = sanitize_input_string(description, 0, MAX_PROP_DESC_LENGTH)?;

let proposal = Proposal {
round_id,
tranche_id,
proposal_id,
title,
description,
covenant_params,
power: Uint128::zero(),
percentage: Uint128::zero(),
Expand Down Expand Up @@ -959,3 +971,18 @@ fn get_lock_count(deps: Deps, user_address: Addr) -> usize {
.range(deps.storage, None, None, Order::Ascending)
.count()
}

// Trims the input string and validates its minimum and maximum length
fn sanitize_input_string(input: String, min_length: usize, max_length: usize) -> StdResult<String> {
let input = input.trim().to_string();
let input_length = input.len();

if input_length < min_length || input_length > max_length {
return Err(StdError::generic_err(format!(
"Invalid string length, got {}, expected length to be between {} and {}",
input, min_length, max_length
)));
}

Ok(input)
}
3 changes: 2 additions & 1 deletion contracts/atom_wars/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum ExecuteMsg {
UnlockTokens {},
CreateProposal {
tranche_id: u64,
title: String,
description: String,
covenant_params: CovenantParams,
},
Vote {
Expand All @@ -40,5 +42,4 @@ pub enum ExecuteMsg {
RemoveFromWhitelist {
covenant_params: CovenantParams,
},
// ExecuteProposal { proposal_id: u64 },
}
2 changes: 2 additions & 0 deletions contracts/atom_wars/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub struct Proposal {
pub round_id: u64,
pub tranche_id: u64,
pub proposal_id: u64,
pub title: String,
pub description: String,
pub covenant_params: CovenantParams,
pub power: Uint128,
pub percentage: Uint128,
Expand Down
88 changes: 86 additions & 2 deletions contracts/atom_wars/src/testing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::contract::{query_whitelist, query_whitelist_admins, MAX_LOCK_ENTRIES};
use crate::contract::{
query_whitelist, query_whitelist_admins, MAX_LOCK_ENTRIES, MAX_PROP_DESC_LENGTH,
MAX_PROP_TITLE_LENGTH, MIN_PROP_TITLE_LENGTH,
};
use crate::state::Tranche;
use crate::{
contract::{
Expand Down Expand Up @@ -219,18 +222,22 @@ fn create_proposal_basic_test() {
let covenant_params_1 = get_default_covenant_params();
let msg1 = ExecuteMsg::CreateProposal {
tranche_id: 1,
title: "proposal title 1".to_string(),
description: "proposal description 1".to_string(),
covenant_params: covenant_params_1.clone(),
};
let res = execute(deps.as_mut(), env.clone(), info.clone(), msg1.clone());
assert!(res.is_ok());

let mut covenant_params_2 = get_default_covenant_params().clone();
let mut covenant_params_2 = get_default_covenant_params();
covenant_params_2.pool_id = "pool_id_2".to_string();
covenant_params_2.outgoing_channel_id = "outgoing_channel_id_2".to_string();
covenant_params_2.funding_destination_name = "funding_destination_name_2".to_string();

let msg2 = ExecuteMsg::CreateProposal {
tranche_id: 1,
title: "proposal title 2".to_string(),
description: "proposal description 2".to_string(),
covenant_params: covenant_params_2.clone(),
};
let res = execute(deps.as_mut(), env.clone(), info.clone(), msg2.clone());
Expand All @@ -252,6 +259,71 @@ fn create_proposal_basic_test() {
assert_eq!(covenant_params_2, proposal.covenant_params);
}

#[test]
fn proposal_title_and_desc_validation_test() {
let user_address = "addr0000";
let user_token = Coin::new(1000, STATOM.to_string());

let (mut deps, env, info) = (
mock_dependencies(),
mock_env(),
mock_info(user_address, &[user_token.clone()]),
);
let msg = get_default_instantiate_msg();

let res = instantiate(deps.as_mut(), env.clone(), info.clone(), msg.clone());
assert!(res.is_ok());

let too_long_title = String::from("too long title ".repeat(20).trim());
let too_long_desc = "a".repeat(10001);

let test_cases = vec![
(
"proposal title too short",
"".to_string(),
"proposal description".to_string(),
format!(
"Invalid string length, got {}, expected length to be between {} and {}",
"", MIN_PROP_TITLE_LENGTH, MAX_PROP_TITLE_LENGTH
),
),
(
"proposal title too long",
too_long_title.clone(),
"proposal description".to_string(),
format!(
"Invalid string length, got {}, expected length to be between {} and {}",
too_long_title, MIN_PROP_TITLE_LENGTH, MAX_PROP_TITLE_LENGTH
),
),
(
"proposal description too long",
"proposal title".to_string(),
too_long_desc.clone(),
format!(
"Invalid string length, got {}, expected length to be between {} and {}",
too_long_desc, 0, MAX_PROP_DESC_LENGTH
),
),
];

for test_case in test_cases {
println!("running test case: {}", test_case.0);

let msg = ExecuteMsg::CreateProposal {
tranche_id: 1,
title: test_case.1.to_string(),
description: test_case.2.to_string(),
covenant_params: get_default_covenant_params(),
};

let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone());
assert!(res.is_err());

assert!(res.unwrap_err().to_string().contains(test_case.3.as_str()));
}
}

#[test]
fn vote_basic_test() {
let user_address = "addr0000";
Expand All @@ -277,6 +349,8 @@ fn vote_basic_test() {
// create a new proposal
let msg = ExecuteMsg::CreateProposal {
tranche_id: 1,
title: "proposal title 1".to_string(),
description: "proposal description 1".to_string(),
covenant_params: get_default_covenant_params(),
};
let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone());
Expand Down Expand Up @@ -337,13 +411,17 @@ fn multi_tranches_test() {
// create two proposals for tranche 1
let msg1 = ExecuteMsg::CreateProposal {
tranche_id: 1,
title: "proposal title 1".to_string(),
description: "proposal description 1".to_string(),
covenant_params: get_default_covenant_params(),
};
let res = execute(deps.as_mut(), env.clone(), info.clone(), msg1.clone());
assert!(res.is_ok());

let msg2 = ExecuteMsg::CreateProposal {
tranche_id: 1,
title: "proposal title 2".to_string(),
description: "proposal description 2".to_string(),
covenant_params: get_default_covenant_params(),
};
let res = execute(deps.as_mut(), env.clone(), info.clone(), msg2.clone());
Expand All @@ -352,13 +430,17 @@ fn multi_tranches_test() {
// create two proposals for tranche 2
let msg3 = ExecuteMsg::CreateProposal {
tranche_id: 2,
title: "proposal title 3".to_string(),
description: "proposal description 3".to_string(),
covenant_params: get_default_covenant_params(),
};
let res = execute(deps.as_mut(), env.clone(), info.clone(), msg3.clone());
assert!(res.is_ok());

let msg4 = ExecuteMsg::CreateProposal {
tranche_id: 2,
title: "proposal title 4".to_string(),
description: "proposal description 4".to_string(),
covenant_params: get_default_covenant_params(),
};
let res = execute(deps.as_mut(), env.clone(), info.clone(), msg4.clone());
Expand Down Expand Up @@ -468,6 +550,8 @@ fn test_query_round_tranche_proposals_pagination() {
for i in 0..num_proposals {
let create_proposal_msg = ExecuteMsg::CreateProposal {
tranche_id: 1,
title: format!("proposal title {}", i + 1),
description: format!("proposal description {}", i + 1),
covenant_params: crate::state::CovenantParams {
pool_id: format!("Pool ID {}", i),
outgoing_channel_id: format!("Outgoing Channel ID {}", i),
Expand Down
12 changes: 12 additions & 0 deletions contracts/tribute/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ fn add_tribute_test() {
round_id: 10,
tranche_id: 0,
proposal_id: 5,
title: "proposal title 1".to_string(),
description: "proposal description 1".to_string(),
covenant_params: CovenantParams {
pool_id: "pool 1".to_string(),
outgoing_channel_id: "channel-1".to_string(),
Expand Down Expand Up @@ -294,6 +296,8 @@ fn claim_tribute_test() {
round_id: 10,
tranche_id: 0,
proposal_id: 5,
title: "proposal title 1".to_string(),
description: "proposal description 1".to_string(),
covenant_params: CovenantParams {
pool_id: "pool 1".to_string(),
outgoing_channel_id: "channel-1".to_string(),
Expand All @@ -308,6 +312,8 @@ fn claim_tribute_test() {
round_id: 10,
tranche_id: 0,
proposal_id: 5,
title: "proposal title 1".to_string(),
description: "proposal description 1".to_string(),
covenant_params: CovenantParams {
pool_id: "pool 1".to_string(),
outgoing_channel_id: "channel-1".to_string(),
Expand All @@ -320,6 +326,8 @@ fn claim_tribute_test() {
round_id: 10,
tranche_id: 0,
proposal_id: 6,
title: "proposal title 2".to_string(),
description: "proposal description 2".to_string(),
covenant_params: CovenantParams {
pool_id: "pool 2".to_string(),
outgoing_channel_id: "channel-2".to_string(),
Expand Down Expand Up @@ -505,6 +513,8 @@ fn refund_tribute_test() {
round_id: 10,
tranche_id: 0,
proposal_id: 5,
title: "proposal title 1".to_string(),
description: "proposal description 1".to_string(),
covenant_params: CovenantParams {
pool_id: "pool 1".to_string(),
outgoing_channel_id: "channel-1".to_string(),
Expand All @@ -518,6 +528,8 @@ fn refund_tribute_test() {
round_id: 10,
tranche_id: 0,
proposal_id: 6,
title: "proposal title 2".to_string(),
description: "proposal description 2".to_string(),
covenant_params: CovenantParams {
pool_id: "pool 2".to_string(),
outgoing_channel_id: "channel-2".to_string(),
Expand Down

0 comments on commit d4fa931

Please sign in to comment.