Repository: DA0-DA0/dao-contracts
Pull request #532 (2022-11-10 23:31:02)

multiple choice cleanups for frontend
Some stuff that is coming up as I work on the frontend (there may be more, but want to get this in)

- fix a couple return type annotations
- simplify proposal.msgs type
- allow multiple choice options to have their own titles
- increase the max number of options

github-actions[bot]: <h1>Cosm-Orc Gas Usage</h1> 
 
 No gas diff larger than 0.5% 
 
 <details><summary>Raw Report for 4d9b81be22dd8eeaf008c906c410fe3ae6450f52 </summary><br/> 

| Contract | Op Name | Gas Used | Gas Wanted | File | 
 | --- | --- | --- | --- | --- |
| cwd_core | Instantiate__inst_dao_no_admin | 1200254 | 1775769 | ci/integration-tests/src/helpers/helper.rs:98 |
| cwd_core | Instantiate__exc_stake_create_dao | 1200230 | 1775733 | ci/integration-tests/src/helpers/helper.rs:98 |
| cwd_core | Store__Store | 45996040 | 68969420 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_core | Instantiate__inst_admin_create_dao | 1201304 | 1777343 | ci/integration-tests/src/helpers/helper.rs:98 |
| cwd_core | Execute__exc_items_rm | 192600 | 264389 | ci/integration-tests/src/tests/cw_core_test.rs:174 |
| cwd_core | Execute__exc_items_set | 194268 | 266891 | ci/integration-tests/src/tests/cw_core_test.rs:139 |
| cwd_core | Instantiate__exc_items_create_dao | 1201304 | 1777343 | ci/integration-tests/src/helpers/helper.rs:98 |
| cwd_core | Execute__exc_admin_msgs_pause_dao | 194394 | 267078 | ci/integration-tests/src/tests/cw_core_test.rs:79 |
| cwd_core | Instantiate__exc_admin_msgs_create_dao | 1200254 | 1775769 | ci/integration-tests/src/helpers/helper.rs:98 |
| cwd_core | Instantiate__exc_admin_msgs_create_dao_with_admin | 1201304 | 1777343 | ci/integration-tests/src/helpers/helper.rs:98 |
| cw20_base | Execute__exc_stake_stake_tokens | 234578 | 319223 | ci/integration-tests/src/tests/cw20_stake_test.rs:76 |
| cw20_base | Store__Store | 34543940 | 51791270 | ci/integration-tests/src/helpers/chain.rs:98 |
| cw20_stake | Store__Store | 29285060 | 43902950 | ci/integration-tests/src/helpers/chain.rs:98 |
| cw4_group | Store__Store | 23034310 | 34526825 | ci/integration-tests/src/helpers/chain.rs:98 |
| cw_admin_factory | Store__Store | 16332340 | 24473870 | ci/integration-tests/src/helpers/chain.rs:98 |
| cw_token_swap | Store__Store | 20276940 | 30390770 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_pre_propose_multiple | Store__Store | 33837080 | 50730980 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_pre_propose_single | Store__Store | 33151120 | 49702040 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_proposal_multiple | Store__Store | 52271980 | 78383330 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_proposal_single | Store__Store | 53896020 | 80819390 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_cw20_staked | Store__Store | 29905635 | 44834141 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_cw4 | Store__Store | 22062790 | 33069545 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_cw721_staked | Store__Store | 31326440 | 46965020 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_native_staked | Store__Store | 24601370 | 36877415 | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_staking_denom_staked | Store__Store | 17908970 | 26838815 | ci/integration-tests/src/helpers/chain.rs:98 |
| stake_cw20_external_rewards | Store__Store | 26120250 | 39155735 | ci/integration-tests/src/helpers/chain.rs:98 |
| stake_cw20_reward_distributor | Store__Store | 19956840 | 29910620 | ci/integration-tests/src/helpers/chain.rs:98 |
</details>
codecov-commenter: # [Codecov](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/532?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0) Report
Base: **93.95**% // Head: **93.98**% // Increases project coverage by **`+0.02%`** :tada:
> Coverage data is based on head [(`3711a13`)](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/532?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0) compared to base [(`48d9629`)](https://codecov.io/gh/DA0-DA0/dao-contracts/commit/48d962971e07ee5bb056b889b41c52c96416ff66?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0).
> Patch coverage: 100.00% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #532      +/-   ##
==========================================
+ Coverage   93.95%   93.98%   +0.02%     
==========================================
  Files          37       37              
  Lines        3589     3589              
==========================================
+ Hits         3372     3373       +1     
+ Misses        217      216       -1     
```


| [Impacted Files](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/532?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0) | Coverage Δ | |
|---|---|---|
| [...cts/proposal/cwd-proposal-multiple/src/proposal.rs](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0#diff-Y29udHJhY3RzL3Byb3Bvc2FsL2N3ZC1wcm9wb3NhbC1tdWx0aXBsZS9zcmMvcHJvcG9zYWwucnM=) | `90.24% <ø> (ø)` | |
| [...cts/proposal/cwd-proposal-multiple/src/contract.rs](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0#diff-Y29udHJhY3RzL3Byb3Bvc2FsL2N3ZC1wcm9wb3NhbC1tdWx0aXBsZS9zcmMvY29udHJhY3QucnM=) | `92.03% <100.00%> (+0.18%)` | :arrow_up: |
| [packages/cwd-voting/src/multiple\_choice.rs](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0#diff-cGFja2FnZXMvY3dkLXZvdGluZy9zcmMvbXVsdGlwbGVfY2hvaWNlLnJz) | `94.87% <100.00%> (+0.42%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/532?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0).


Patch:
diff --git a/contracts/pre-propose/cwd-pre-propose-multiple/schema/cwd-pre-propose-multiple.json b/contracts/pre-propose/cwd-pre-propose-multiple/schema/cwd-pre-propose-multiple.json
index 4e3d0670..289b399f 100644
--- a/contracts/pre-propose/cwd-pre-propose-multiple/schema/cwd-pre-propose-multiple.json
+++ b/contracts/pre-propose/cwd-pre-propose-multiple/schema/cwd-pre-propose-multiple.json
@@ -841,20 +841,22 @@
         "description": "Unchecked multiple choice option",
         "type": "object",
         "required": [
-          "description"
+          "description",
+          "msgs",
+          "title"
         ],
         "properties": {
           "description": {
             "type": "string"
           },
           "msgs": {
-            "type": [
-              "array",
-              "null"
-            ],
+            "type": "array",
             "items": {
               "$ref": "#/definitions/CosmosMsg_for_Empty"
             }
+          },
+          "title": {
+            "type": "string"
           }
         },
         "additionalProperties": false
diff --git a/contracts/proposal/cwd-proposal-multiple/schema/cwd-proposal-multiple.json b/contracts/proposal/cwd-proposal-multiple/schema/cwd-proposal-multiple.json
index 2e9cb5d4..048f7264 100644
--- a/contracts/proposal/cwd-proposal-multiple/schema/cwd-proposal-multiple.json
+++ b/contracts/proposal/cwd-proposal-multiple/schema/cwd-proposal-multiple.json
@@ -1146,20 +1146,22 @@
         "description": "Unchecked multiple choice option",
         "type": "object",
         "required": [
-          "description"
+          "description",
+          "msgs",
+          "title"
         ],
         "properties": {
           "description": {
             "type": "string"
           },
           "msgs": {
-            "type": [
-              "array",
-              "null"
-            ],
+            "type": "array",
             "items": {
               "$ref": "#/definitions/CosmosMsg_for_Empty"
             }
+          },
+          "title": {
+            "type": "string"
           }
         },
         "additionalProperties": false
@@ -1686,7 +1688,7 @@
         "additionalProperties": false
       },
       {
-        "description": "Returns the number of proposals that have been created in this module./// Returns a voters position on a propsal.",
+        "description": "Returns the number of proposals that have been created in this module.",
         "type": "object",
         "required": [
           "proposal_count"
@@ -2388,7 +2390,9 @@
           "required": [
             "description",
             "index",
+            "msgs",
             "option_type",
+            "title",
             "vote_count"
           ],
           "properties": {
@@ -2401,10 +2405,7 @@
               "minimum": 0.0
             },
             "msgs": {
-              "type": [
-                "array",
-                "null"
-              ],
+              "type": "array",
               "items": {
                 "$ref": "#/definitions/CosmosMsg_for_Empty"
               }
@@ -2412,6 +2413,9 @@
             "option_type": {
               "$ref": "#/definitions/MultipleChoiceOptionType"
             },
+            "title": {
+              "type": "string"
+            },
             "vote_count": {
               "$ref": "#/definitions/Uint128"
             }
@@ -3457,103 +3461,21 @@
     },
     "proposal": {
       "$schema": "http://json-schema.org/draft-07/schema#",
-      "title": "MultipleChoiceProposal",
+      "title": "ProposalResponse",
+      "description": "Information about a proposal returned by proposal queries.",
       "type": "object",
       "required": [
-        "allow_revoting",
-        "choices",
-        "description",
-        "expiration",
-        "proposer",
-        "start_height",
-        "status",
-        "title",
-        "total_power",
-        "votes",
-        "voting_strategy"
+        "id",
+        "proposal"
       ],
       "properties": {
-        "allow_revoting": {
-          "description": "Whether DAO members are allowed to change their votes. When disabled, proposals can be executed as soon as they pass. When enabled, proposals can only be executed after the voting perid has ended and the proposal passed.",
-          "type": "boolean"
-        },
-        "choices": {
-          "description": "The options to be chosen from in the vote.",
-          "type": "array",
-          "items": {
-            "$ref": "#/definitions/CheckedMultipleChoiceOption"
-          }
-        },
-        "description": {
-          "type": "string"
-        },
-        "expiration": {
-          "description": "The the time at which this proposal will expire and close for additional votes.",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Expiration"
-            }
-          ]
-        },
-        "min_voting_period": {
-          "description": "The minimum amount of time this proposal must remain open for voting. The proposal may not pass unless this is expired or None.",
-          "anyOf": [
-            {
-              "$ref": "#/definitions/Expiration"
-            },
-            {
-              "type": "null"
-            }
-          ]
-        },
-        "proposer": {
-          "description": "The address that created this proposal.",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Addr"
-            }
-          ]
-        },
-        "start_height": {
-          "description": "The block height at which this proposal was created. Voting power queries should query for voting power at this block height.",
+        "id": {
           "type": "integer",
           "format": "uint64",
           "minimum": 0.0
         },
-        "status": {
-          "description": "Prosal status (Open, rejected, executed, execution failed, closed, passed)",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Status"
-            }
-          ]
-        },
-        "title": {
-          "type": "string"
-        },
-        "total_power": {
-          "description": "The total power when the proposal started (used to calculate percentages)",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Uint128"
-            }
-          ]
-        },
-        "votes": {
-          "description": "The vote tally.",
-          "allOf": [
-            {
-              "$ref": "#/definitions/MultipleChoiceVotes"
-            }
-          ]
-        },
-        "voting_strategy": {
-          "description": "Voting settings (threshold, quorum, etc.)",
-          "allOf": [
-            {
-              "$ref": "#/definitions/VotingStrategy"
-            }
-          ]
+        "proposal": {
+          "$ref": "#/definitions/MultipleChoiceProposal"
         }
       },
       "additionalProperties": false,
@@ -3629,7 +3551,9 @@
           "required": [
             "description",
             "index",
+            "msgs",
             "option_type",
+            "title",
             "vote_count"
           ],
           "properties": {
@@ -3642,10 +3566,7 @@
               "minimum": 0.0
             },
             "msgs": {
-              "type": [
-                "array",
-                "null"
-              ],
+              "type": "array",
               "items": {
                 "$ref": "#/definitions/CosmosMsg_for_Empty"
               }
@@ -3653,6 +3574,9 @@
             "option_type": {
               "$ref": "#/definitions/MultipleChoiceOptionType"
             },
+            "title": {
+              "type": "string"
+            },
             "vote_count": {
               "$ref": "#/definitions/Uint128"
             }
@@ -4093,6 +4017,107 @@
             }
           ]
         },
+        "MultipleChoiceProposal": {
+          "type": "object",
+          "required": [
+            "allow_revoting",
+            "choices",
+            "description",
+            "expiration",
+            "proposer",
+            "start_height",
+            "status",
+            "title",
+            "total_power",
+            "votes",
+            "voting_strategy"
+          ],
+          "properties": {
+            "allow_revoting": {
+              "description": "Whether DAO members are allowed to change their votes. When disabled, proposals can be executed as soon as they pass. When enabled, proposals can only be executed after the voting perid has ended and the proposal passed.",
+              "type": "boolean"
+            },
+            "choices": {
+              "description": "The options to be chosen from in the vote.",
+              "type": "array",
+              "items": {
+                "$ref": "#/definitions/CheckedMultipleChoiceOption"
+              }
+            },
+            "description": {
+              "type": "string"
+            },
+            "expiration": {
+              "description": "The the time at which this proposal will expire and close for additional votes.",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Expiration"
+                }
+              ]
+            },
+            "min_voting_period": {
+              "description": "The minimum amount of time this proposal must remain open for voting. The proposal may not pass unless this is expired or None.",
+              "anyOf": [
+                {
+                  "$ref": "#/definitions/Expiration"
+                },
+                {
+                  "type": "null"
+                }
+              ]
+            },
+            "proposer": {
+              "description": "The address that created this proposal.",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Addr"
+                }
+              ]
+            },
+            "start_height": {
+              "description": "The block height at which this proposal was created. Voting power queries should query for voting power at this block height.",
+              "type": "integer",
+              "format": "uint64",
+              "minimum": 0.0
+            },
+            "status": {
+              "description": "Prosal status (Open, rejected, executed, execution failed, closed, passed)",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Status"
+                }
+              ]
+            },
+            "title": {
+              "type": "string"
+            },
+            "total_power": {
+              "description": "The total power when the proposal started (used to calculate percentages)",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Uint128"
+                }
+              ]
+            },
+            "votes": {
+              "description": "The vote tally.",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/MultipleChoiceVotes"
+                }
+              ]
+            },
+            "voting_strategy": {
+              "description": "Voting settings (threshold, quorum, etc.)",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/VotingStrategy"
+                }
+              ]
+            }
+          },
+          "additionalProperties": false
+        },
         "MultipleChoiceVotes": {
           "type": "object",
           "required": [
@@ -4658,7 +4683,9 @@
           "required": [
             "description",
             "index",
+            "msgs",
             "option_type",
+            "title",
             "vote_count"
           ],
           "properties": {
@@ -4671,10 +4698,7 @@
               "minimum": 0.0
             },
             "msgs": {
-              "type": [
-                "array",
-                "null"
-              ],
+              "type": "array",
               "items": {
                 "$ref": "#/definitions/CosmosMsg_for_Empty"
               }
@@ -4682,6 +4706,9 @@
             "option_type": {
               "$ref": "#/definitions/MultipleChoiceOptionType"
             },
+            "title": {
+              "type": "string"
+            },
             "vote_count": {
               "$ref": "#/definitions/Uint128"
             }
diff --git a/contracts/proposal/cwd-proposal-multiple/src/contract.rs b/contracts/proposal/cwd-proposal-multiple/src/contract.rs
index a74a1922..dcfc8fd0 100644
--- a/contracts/proposal/cwd-proposal-multiple/src/contract.rs
+++ b/contracts/proposal/cwd-proposal-multiple/src/contract.rs
@@ -405,32 +405,26 @@ pub fn execute_execute(
     match vote_result {
         VoteResult::Tie => Err(ContractError::Tie {}), // We don't anticipate this case as the proposal would not be in passed state, checked above.
         VoteResult::SingleWinner(winning_choice) => {
-            let response = match winning_choice.msgs {
-                Some(msgs) => {
-                    if !msgs.is_empty() {
-                        let execute_message = WasmMsg::Execute {
-                            contract_addr: config.dao.to_string(),
-                            msg: to_binary(&cwd_core::msg::ExecuteMsg::ExecuteProposalHook {
-                                msgs,
-                            })?,
-                            funds: vec![],
-                        };
-                        match config.close_proposal_on_execution_failure {
-                            true => {
-                                let masked_proposal_id =
-                                    mask_proposal_execution_proposal_id(proposal_id);
-                                Response::default().add_submessage(SubMsg::reply_on_error(
-                                    execute_message,
-                                    masked_proposal_id,
-                                ))
-                            }
-                            false => Response::default().add_message(execute_message),
-                        }
-                    } else {
-                        Response::default()
+            let response = if !winning_choice.msgs.is_empty() {
+                let execute_message = WasmMsg::Execute {
+                    contract_addr: config.dao.to_string(),
+                    msg: to_binary(&cwd_core::msg::ExecuteMsg::ExecuteProposalHook {
+                        msgs: winning_choice.msgs,
+                    })?,
+                    funds: vec![],
+                };
+                match config.close_proposal_on_execution_failure {
+                    true => {
+                        let masked_proposal_id = mask_proposal_execution_proposal_id(proposal_id);
+                        Response::default().add_submessage(SubMsg::reply_on_error(
+                            execute_message,
+                            masked_proposal_id,
+                        ))
                     }
+                    false => Response::default().add_message(execute_message),
                 }
-                None => Response::default(),
+            } else {
+                Response::default()
             };
 
             let hooks = proposal_status_changed_hooks(
diff --git a/contracts/proposal/cwd-proposal-multiple/src/msg.rs b/contracts/proposal/cwd-proposal-multiple/src/msg.rs
index 3ec9e020..aff138c6 100644
--- a/contracts/proposal/cwd-proposal-multiple/src/msg.rs
+++ b/contracts/proposal/cwd-proposal-multiple/src/msg.rs
@@ -141,7 +141,7 @@ pub enum QueryMsg {
     #[returns(crate::state::Config)]
     Config {},
     /// Gets information about a proposal.
-    #[returns(crate::proposal::MultipleChoiceProposal)]
+    #[returns(crate::query::ProposalResponse)]
     Proposal { proposal_id: u64 },
     /// Lists all the proposals that have been cast in this
     /// module.
@@ -158,7 +158,7 @@ pub enum QueryMsg {
         limit: Option<u64>,
     },
     /// Returns the number of proposals that have been created in this
-    /// module./// Returns a voters position on a propsal.
+    /// module.
     #[returns(u64)]
     ProposalCount {},
     /// Returns a voters position on a proposal.
diff --git a/contracts/proposal/cwd-proposal-multiple/src/proposal.rs b/contracts/proposal/cwd-proposal-multiple/src/proposal.rs
index 4489aa4d..f8ba681c 100644
--- a/contracts/proposal/cwd-proposal-multiple/src/proposal.rs
+++ b/contracts/proposal/cwd-proposal-multiple/src/proposal.rs
@@ -285,11 +285,13 @@ mod tests {
         let options = vec![
             MultipleChoiceOption {
                 description: "multiple choice option 1".to_string(),
-                msgs: None,
+                msgs: vec![],
+                title: "title".to_string(),
             },
             MultipleChoiceOption {
                 description: "multiple choice option 2".to_string(),
-                msgs: None,
+                msgs: vec![],
+                title: "title".to_string(),
             },
         ];
 
diff --git a/contracts/proposal/cwd-proposal-single/schema/cwd-proposal-single.json b/contracts/proposal/cwd-proposal-single/schema/cwd-proposal-single.json
index 358bc2b7..4751997d 100644
--- a/contracts/proposal/cwd-proposal-single/schema/cwd-proposal-single.json
+++ b/contracts/proposal/cwd-proposal-single/schema/cwd-proposal-single.json
@@ -3608,92 +3608,22 @@
     },
     "proposal": {
       "$schema": "http://json-schema.org/draft-07/schema#",
-      "title": "SingleChoiceProposal",
+      "title": "ProposalResponse",
+      "description": "Information about a proposal returned by proposal queries.",
       "type": "object",
       "required": [
-        "allow_revoting",
-        "description",
-        "expiration",
-        "msgs",
-        "proposer",
-        "start_height",
-        "status",
-        "threshold",
-        "title",
-        "total_power",
-        "votes"
+        "id",
+        "proposal"
       ],
       "properties": {
-        "allow_revoting": {
-          "type": "boolean"
-        },
-        "description": {
-          "type": "string"
-        },
-        "expiration": {
-          "description": "The the time at which this proposal will expire and close for additional votes.",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Expiration"
-            }
-          ]
-        },
-        "min_voting_period": {
-          "description": "The minimum amount of time this proposal must remain open for voting. The proposal may not pass unless this is expired or None.",
-          "anyOf": [
-            {
-              "$ref": "#/definitions/Expiration"
-            },
-            {
-              "type": "null"
-            }
-          ]
-        },
-        "msgs": {
-          "description": "The messages that will be executed should this proposal pass.",
-          "type": "array",
-          "items": {
-            "$ref": "#/definitions/CosmosMsg_for_Empty"
-          }
-        },
-        "proposer": {
-          "description": "The address that created this proposal.",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Addr"
-            }
-          ]
-        },
-        "start_height": {
-          "description": "The block height at which this proposal was created. Voting power queries should query for voting power at this block height.",
+        "id": {
+          "description": "The ID of the proposal being returned.",
           "type": "integer",
           "format": "uint64",
           "minimum": 0.0
         },
-        "status": {
-          "$ref": "#/definitions/Status"
-        },
-        "threshold": {
-          "description": "The threshold at which this proposal will pass.",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Threshold"
-            }
-          ]
-        },
-        "title": {
-          "type": "string"
-        },
-        "total_power": {
-          "description": "The total amount of voting power at the time of this proposal's creation.",
-          "allOf": [
-            {
-              "$ref": "#/definitions/Uint128"
-            }
-          ]
-        },
-        "votes": {
-          "$ref": "#/definitions/Votes"
+        "proposal": {
+          "$ref": "#/definitions/SingleChoiceProposal"
         }
       },
       "additionalProperties": false,
@@ -4211,6 +4141,96 @@
             }
           ]
         },
+        "SingleChoiceProposal": {
+          "type": "object",
+          "required": [
+            "allow_revoting",
+            "description",
+            "expiration",
+            "msgs",
+            "proposer",
+            "start_height",
+            "status",
+            "threshold",
+            "title",
+            "total_power",
+            "votes"
+          ],
+          "properties": {
+            "allow_revoting": {
+              "type": "boolean"
+            },
+            "description": {
+              "type": "string"
+            },
+            "expiration": {
+              "description": "The the time at which this proposal will expire and close for additional votes.",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Expiration"
+                }
+              ]
+            },
+            "min_voting_period": {
+              "description": "The minimum amount of time this proposal must remain open for voting. The proposal may not pass unless this is expired or None.",
+              "anyOf": [
+                {
+                  "$ref": "#/definitions/Expiration"
+                },
+                {
+                  "type": "null"
+                }
+              ]
+            },
+            "msgs": {
+              "description": "The messages that will be executed should this proposal pass.",
+              "type": "array",
+              "items": {
+                "$ref": "#/definitions/CosmosMsg_for_Empty"
+              }
+            },
+            "proposer": {
+              "description": "The address that created this proposal.",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Addr"
+                }
+              ]
+            },
+            "start_height": {
+              "description": "The block height at which this proposal was created. Voting power queries should query for voting power at this block height.",
+              "type": "integer",
+              "format": "uint64",
+              "minimum": 0.0
+            },
+            "status": {
+              "$ref": "#/definitions/Status"
+            },
+            "threshold": {
+              "description": "The threshold at which this proposal will pass.",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Threshold"
+                }
+              ]
+            },
+            "title": {
+              "type": "string"
+            },
+            "total_power": {
+              "description": "The total amount of voting power at the time of this proposal's creation.",
+              "allOf": [
+                {
+                  "$ref": "#/definitions/Uint128"
+                }
+              ]
+            },
+            "votes": {
+              "$ref": "#/definitions/Votes"
+            }
+          },
+          "additionalProperties": false
+        },
         "StakingMsg": {
           "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto",
           "oneOf": [
diff --git a/contracts/proposal/cwd-proposal-single/src/msg.rs b/contracts/proposal/cwd-proposal-single/src/msg.rs
index 044fbf85..c0234d98 100644
--- a/contracts/proposal/cwd-proposal-single/src/msg.rs
+++ b/contracts/proposal/cwd-proposal-single/src/msg.rs
@@ -142,7 +142,7 @@ pub enum QueryMsg {
     #[returns(crate::state::Config)]
     Config {},
     /// Gets information about a proposal.
-    #[returns(crate::proposal::SingleChoiceProposal)]
+    #[returns(crate::query::ProposalResponse)]
     Proposal { proposal_id: u64 },
     /// Lists all the proposals that have been cast in this
     /// module.
diff --git a/packages/cwd-voting/src/multiple_choice.rs b/packages/cwd-voting/src/multiple_choice.rs
index be521c16..69f7d804 100644
--- a/packages/cwd-voting/src/multiple_choice.rs
+++ b/packages/cwd-voting/src/multiple_choice.rs
@@ -3,8 +3,9 @@ use cosmwasm_std::{CosmosMsg, Empty, StdError, StdResult, Uint128};
 
 use crate::threshold::{validate_quorum, PercentageThreshold, ThresholdError};
 
-/// Maximum number of choices for multiple choice votes
-pub const MAX_NUM_CHOICES: u32 = 10;
+/// Maximum number of choices for multiple choice votes. Chosen
+/// in order to impose a bound on state / queries.
+pub const MAX_NUM_CHOICES: u32 = 20;
 const NONE_OPTION_DESCRIPTION: &str = "None of the above";
 
 /// Determines how many choices may be selected.
@@ -98,8 +99,9 @@ pub struct MultipleChoiceOptions {
 /// Unchecked multiple choice option
 #[cw_serde]
 pub struct MultipleChoiceOption {
+    pub title: String,
     pub description: String,
-    pub msgs: Option<Vec<CosmosMsg<Empty>>>,
+    pub msgs: Vec<CosmosMsg<Empty>>,
 }
 
 /// Multiple choice options that have been verified for correctness, and have all fields
@@ -116,8 +118,9 @@ pub struct CheckedMultipleChoiceOption {
     // Workaround due to not being able to use HashMaps in Cosmwasm.
     pub index: u32,
     pub option_type: MultipleChoiceOptionType,
+    pub title: String,
     pub description: String,
-    pub msgs: Option<Vec<CosmosMsg<Empty>>>,
+    pub msgs: Vec<CosmosMsg<Empty>>,
     pub vote_count: Uint128,
 }
 
@@ -143,8 +146,9 @@ impl MultipleChoiceOptions {
                     description: choice.description,
                     msgs: choice.msgs,
                     vote_count: Uint128::zero(),
+                    title: choice.title,
                 };
-                checked_options.push(checked_option);
+                checked_options.push(checked_option)
             });
 
         // Add a "None of the above" option, required for every multiple choice proposal.
@@ -152,8 +156,9 @@ impl MultipleChoiceOptions {
             index: (checked_options.capacity() - 1) as u32,
             option_type: MultipleChoiceOptionType::None,
             description: NONE_OPTION_DESCRIPTION.to_string(),
-            msgs: None,
+            msgs: vec![],
             vote_count: Uint128::zero(),
+            title: NONE_OPTION_DESCRIPTION.to_string(),
         };
 
         checked_options.push(none_option);
@@ -167,6 +172,8 @@ impl MultipleChoiceOptions {
 
 #[cfg(test)]
 mod test {
+    use std::vec;
+
     use super::*;
 
     #[test]
@@ -204,11 +211,13 @@ mod test {
         let options = vec![
             super::MultipleChoiceOption {
                 description: "multiple choice option 1".to_string(),
-                msgs: None,
+                msgs: vec![],
+                title: "title".to_string(),
             },
             super::MultipleChoiceOption {
                 description: "multiple choice option 2".to_string(),
-                msgs: None,
+                msgs: vec![],
+                title: "title".to_string(),
             },
         ];
 
@@ -247,7 +256,8 @@ mod test {
     fn test_into_checked_wrong_num_choices() {
         let options = vec![super::MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         }];
 
         let mc_options = super::MultipleChoiceOptions { options };
diff --git a/typescript/contracts/cwd-pre-propose-multiple/CwdPreProposeMultiple.types.ts b/typescript/contracts/cwd-pre-propose-multiple/CwdPreProposeMultiple.types.ts
index 89131c9b..a13dc6f2 100644
--- a/typescript/contracts/cwd-pre-propose-multiple/CwdPreProposeMultiple.types.ts
+++ b/typescript/contracts/cwd-pre-propose-multiple/CwdPreProposeMultiple.types.ts
@@ -203,7 +203,8 @@ export interface MultipleChoiceOptions {
 }
 export interface MultipleChoiceOption {
   description: string;
-  msgs?: CosmosMsgForEmpty[] | null;
+  msgs: CosmosMsgForEmpty[];
+  title: string;
 }
 export interface Coin {
   amount: Uint128;
diff --git a/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.client.ts b/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.client.ts
index a13a6069..e1f0eea4 100644
--- a/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.client.ts
+++ b/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.client.ts
@@ -14,7 +14,7 @@ export interface CwdProposalMultipleReadOnlyInterface {
     proposalId
   }: {
     proposalId: number;
-  }) => Promise<MultipleChoiceProposal>;
+  }) => Promise<ProposalResponse>;
   listProposals: ({
     limit,
     startAfter
@@ -82,7 +82,7 @@ export class CwdProposalMultipleQueryClient implements CwdProposalMultipleReadOn
     proposalId
   }: {
     proposalId: number;
-  }): Promise<MultipleChoiceProposal> => {
+  }): Promise<ProposalResponse> => {
     return this.client.queryContractSmart(this.contractAddress, {
       proposal: {
         proposal_id: proposalId
diff --git a/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.types.ts b/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.types.ts
index 0d68aa17..01217067 100644
--- a/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.types.ts
+++ b/typescript/contracts/cwd-proposal-multiple/CwdProposalMultiple.types.ts
@@ -237,7 +237,8 @@ export interface MultipleChoiceOptions {
 }
 export interface MultipleChoiceOption {
   description: string;
-  msgs?: CosmosMsgForEmpty[] | null;
+  msgs: CosmosMsgForEmpty[];
+  title: string;
 }
 export interface Coin {
   amount: Uint128;
@@ -366,8 +367,9 @@ export interface MultipleChoiceProposal {
 export interface CheckedMultipleChoiceOption {
   description: string;
   index: number;
-  msgs?: CosmosMsgForEmpty[] | null;
+  msgs: CosmosMsgForEmpty[];
   option_type: MultipleChoiceOptionType;
+  title: string;
   vote_count: Uint128;
 }
 export interface MultipleChoiceVotes {
diff --git a/typescript/contracts/cwd-proposal-single/CwdProposalSingle.client.ts b/typescript/contracts/cwd-proposal-single/CwdProposalSingle.client.ts
index 73a82468..3718f56e 100644
--- a/typescript/contracts/cwd-proposal-single/CwdProposalSingle.client.ts
+++ b/typescript/contracts/cwd-proposal-single/CwdProposalSingle.client.ts
@@ -14,7 +14,7 @@ export interface CwdProposalSingleReadOnlyInterface {
     proposalId
   }: {
     proposalId: number;
-  }) => Promise<SingleChoiceProposal>;
+  }) => Promise<ProposalResponse>;
   listProposals: ({
     limit,
     startAfter
@@ -82,7 +82,7 @@ export class CwdProposalSingleQueryClient implements CwdProposalSingleReadOnlyIn
     proposalId
   }: {
     proposalId: number;
-  }): Promise<SingleChoiceProposal> => {
+  }): Promise<ProposalResponse> => {
     return this.client.queryContractSmart(this.contractAddress, {
       proposal: {
         proposal_id: proposalId


Test patch:
diff --git a/contracts/pre-propose/cwd-pre-propose-multiple/src/tests.rs b/contracts/pre-propose/cwd-pre-propose-multiple/src/tests.rs
index eca43152..1da222d1 100644
--- a/contracts/pre-propose/cwd-pre-propose-multiple/src/tests.rs
+++ b/contracts/pre-propose/cwd-pre-propose-multiple/src/tests.rs
@@ -192,11 +192,13 @@ fn make_proposal(
                         options: vec![
                             MultipleChoiceOption {
                                 description: "multiple choice option 1".to_string(),
-                                msgs: None,
+                                msgs: vec![],
+                                title: "title".to_string(),
                             },
                             MultipleChoiceOption {
                                 description: "multiple choice option 2".to_string(),
-                                msgs: None,
+                                msgs: vec![],
+                                title: "title".to_string(),
                             },
                         ],
                     },
@@ -229,24 +231,27 @@ fn make_proposal(
         vec![
             CheckedMultipleChoiceOption {
                 description: "multiple choice option 1".to_string(),
-                msgs: None,
+                msgs: vec![],
                 option_type: MultipleChoiceOptionType::Standard,
                 vote_count: Uint128::zero(),
                 index: 0,
+                title: "title".to_string(),
             },
             CheckedMultipleChoiceOption {
                 description: "multiple choice option 2".to_string(),
-                msgs: None,
+                msgs: vec![],
                 option_type: MultipleChoiceOptionType::Standard,
                 vote_count: Uint128::zero(),
                 index: 1,
+                title: "title".to_string(),
             },
             CheckedMultipleChoiceOption {
                 description: "None of the above".to_string(),
-                msgs: None,
+                msgs: vec![],
                 option_type: MultipleChoiceOptionType::None,
                 vote_count: Uint128::zero(),
                 index: 2,
+                title: "None of the above".to_string(),
             },
         ]
     );
@@ -874,7 +879,8 @@ fn test_permissions() {
                     choices: MultipleChoiceOptions {
                         options: vec![MultipleChoiceOption {
                             description: "multiple choice option 1".to_string(),
-                            msgs: None,
+                            msgs: vec![],
+                            title: "title".to_string(),
                         }],
                     },
                 },
@@ -979,7 +985,8 @@ fn test_no_deposit_required_members_submission() {
                     choices: MultipleChoiceOptions {
                         options: vec![MultipleChoiceOption {
                             description: "multiple choice option 1".to_string(),
-                            msgs: None,
+                            msgs: vec![],
+                            title: "title".to_string(),
                         }],
                     },
                 },
diff --git a/contracts/proposal/cwd-proposal-multiple/src/testing/do_votes.rs b/contracts/proposal/cwd-proposal-multiple/src/testing/do_votes.rs
index 0aa951a6..d25150ad 100644
--- a/contracts/proposal/cwd-proposal-multiple/src/testing/do_votes.rs
+++ b/contracts/proposal/cwd-proposal-multiple/src/testing/do_votes.rs
@@ -192,11 +192,13 @@ where
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
diff --git a/contracts/proposal/cwd-proposal-multiple/src/testing/tests.rs b/contracts/proposal/cwd-proposal-multiple/src/testing/tests.rs
index 71102c59..ef5ef271 100644
--- a/contracts/proposal/cwd-proposal-multiple/src/testing/tests.rs
+++ b/contracts/proposal/cwd-proposal-multiple/src/testing/tests.rs
@@ -140,11 +140,13 @@ fn test_propose() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -234,7 +236,8 @@ fn test_propose_wrong_num_choices() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         };
         std::convert::TryInto::try_into(MAX_NUM_CHOICES + 1).unwrap()
     ];
@@ -334,11 +337,13 @@ fn test_no_early_pass_with_min_duration() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -443,11 +448,13 @@ fn test_propose_with_messages() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: Some(vec![CosmosMsg::Wasm(wasm_msg)]),
+            msgs: vec![CosmosMsg::Wasm(wasm_msg)],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -604,11 +611,13 @@ fn test_min_duration_same_as_proposal_duration() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -877,11 +886,13 @@ fn test_take_proposal_deposit() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -991,11 +1002,13 @@ fn test_native_proposal_deposit() {
             options: vec![
                 MultipleChoiceOption {
                     description: "multiple choice option 1".to_string(),
-                    msgs: None,
+                    msgs: vec![],
+                    title: "title".to_string(),
                 },
                 MultipleChoiceOption {
                     description: "multiple choice option 2".to_string(),
-                    msgs: None,
+                    msgs: vec![],
+                    title: "title".to_string(),
                 },
             ],
         };
@@ -1401,11 +1414,13 @@ fn test_cant_propose_zero_power() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -1549,11 +1564,13 @@ fn test_cant_execute_not_member() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -1630,11 +1647,13 @@ fn test_open_proposal_submission() {
             options: vec![
                 MultipleChoiceOption {
                     description: "multiple choice option 1".to_string(),
-                    msgs: None,
+                    msgs: vec![],
+                    title: "title".to_string(),
                 },
                 MultipleChoiceOption {
                     description: "multiple choice option 2".to_string(),
-                    msgs: None,
+                    msgs: vec![],
+                    title: "title".to_string(),
                 },
             ],
         },
@@ -1658,24 +1677,27 @@ fn test_open_proposal_submission() {
         choices: vec![
             CheckedMultipleChoiceOption {
                 description: "multiple choice option 1".to_string(),
-                msgs: None,
+                msgs: vec![],
                 option_type: MultipleChoiceOptionType::Standard,
                 vote_count: Uint128::zero(),
                 index: 0,
+                title: "title".to_string(),
             },
             CheckedMultipleChoiceOption {
                 description: "multiple choice option 2".to_string(),
-                msgs: None,
+                msgs: vec![],
                 option_type: MultipleChoiceOptionType::Standard,
                 vote_count: Uint128::zero(),
                 index: 1,
+                title: "title".to_string(),
             },
             CheckedMultipleChoiceOption {
                 description: "None of the above".to_string(),
-                msgs: None,
+                msgs: vec![],
                 option_type: MultipleChoiceOptionType::None,
                 vote_count: Uint128::zero(),
                 index: 2,
+                title: "None of the above".to_string(),
             },
         ],
         votes: MultipleChoiceVotes {
@@ -1935,11 +1957,13 @@ fn test_execute_expired_proposal() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -2221,11 +2245,13 @@ fn test_query_list_proposals() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -2487,11 +2513,13 @@ fn test_active_threshold_absolute() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -2613,11 +2641,13 @@ fn test_active_threshold_percent() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -2742,11 +2772,13 @@ fn test_active_threshold_none() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -2828,11 +2860,13 @@ fn test_revoting() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
     let mc_options = MultipleChoiceOptions { options };
@@ -2955,11 +2989,13 @@ fn test_allow_revoting_config_changes() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
     let mc_options = MultipleChoiceOptions { options };
@@ -3100,11 +3136,13 @@ fn test_revoting_same_vote_twice() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
     let mc_options = MultipleChoiceOptions { options };
@@ -3190,11 +3228,13 @@ fn test_invalid_revote_does_not_invalidate_initial_vote() {
     let options = vec![
         MultipleChoiceOption {
             description: "multiple choice option 1".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "multiple choice option 2".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
     let mc_options = MultipleChoiceOptions { options };
@@ -3404,16 +3444,18 @@ fn test_close_failed_proposal() {
     let options = vec![
         MultipleChoiceOption {
             description: "Burn or burn".to_string(),
-            msgs: Some(vec![WasmMsg::Execute {
+            msgs: vec![WasmMsg::Execute {
                 contract_addr: token_contract.to_string(),
                 msg: binary_msg,
                 funds: vec![],
             }
-            .into()]),
+            .into()],
+            title: "title".to_string(),
         },
         MultipleChoiceOption {
             description: "Don't burn".to_string(),
-            msgs: None,
+            msgs: vec![],
+            title: "title".to_string(),
         },
     ];
 
@@ -3476,7 +3518,7 @@ fn test_close_failed_proposal() {
                     options: vec![
                         MultipleChoiceOption {
                             description: "Disable closing failed proposals".to_string(),
-                            msgs: Some(vec![WasmMsg::Execute {
+                            msgs: vec![WasmMsg::Execute {
                                 contract_addr: govmod.to_string(),
                                 msg: to_binary(&ExecuteMsg::UpdateConfig {
                                     voting_strategy: VotingStrategy::SingleChoice { quorum },
@@ -3490,11 +3532,13 @@ fn test_close_failed_proposal() {
                                 .unwrap(),
                                 funds: vec![],
                             }
-                            .into()]),
+                            .into()],
+                            title: "title".to_string(),
                         },
                         MultipleChoiceOption {
                             description: "Don't disable".to_string(),
-                            msgs: None,
+                            msgs: vec![],
+                            title: "title".to_string(),
                         },
                     ],
                 },
@@ -3683,16 +3727,18 @@ fn test_no_double_refund_on_execute_fail_and_close() {
         options: vec![
             MultipleChoiceOption {
                 description: "Burning more tokens, than dao treasury have".to_string(),
-                msgs: Some(vec![WasmMsg::Execute {
+                msgs: vec![WasmMsg::Execute {
                     contract_addr: token_contract.to_string(),
                     msg: binary_msg,
                     funds: vec![],
                 }
-                .into()]),
+                .into()],
+                title: "title".to_string(),
             },
             MultipleChoiceOption {
                 description: "hi there".to_string(),
-                msgs: None,
+                msgs: vec![],
+                title: "title".to_string(),
             },
         ],
     };