Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Proposal with Title and Description fields #44

Merged
merged 2 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading