Repository: DA0-DA0/dao-contracts
Pull request #516 (2022-11-01 00:39:27)

Refactor macro code for better hygiene.
deduplicates the macro code a fair bit and makes it more hygenic by using absolute paths for imports.

codecov-commenter: # [Codecov](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/516?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0) Report
Base: **91.25**% // Head: **92.30**% // Increases project coverage by **`+1.04%`** :tada:
> Coverage data is based on head [(`9f63900`)](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/516?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0) compared to base [(`7c92d95`)](https://codecov.io/gh/DA0-DA0/dao-contracts/commit/7c92d951fb0eef4ec3b6e39c5b867cfd5ea55fcb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0).
> Patch coverage: 0.00% of modified lines in pull request are covered.

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


```diff
@@                 Coverage Diff                 @@
##           upgradeCosmwasm     #516      +/-   ##
===================================================
+ Coverage            91.25%   92.30%   +1.04%     
===================================================
  Files                   38       38              
  Lines                 3695     3653      -42     
===================================================
  Hits                  3372     3372              
+ Misses                 323      281      -42     
```


| [Impacted Files](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/516?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0) | Coverage Δ | |
|---|---|---|
| [packages/cwd-macros/src/lib.rs](https://codecov.io/gh/DA0-DA0/dao-contracts/pull/516/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DA0-DA0#diff-cGFja2FnZXMvY3dkLW1hY3Jvcy9zcmMvbGliLnJz) | `0.00% <0.00%> (ø)` | |

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/516?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).

github-actions[bot]: <h1>Cosm-Orc Gas Usage</h1> 
 
 | Contract | Op Name | Gas Used | Old Gas Used | Gas Diff | File | 
 | --- | --- | --- | --- | --- | --- | 
| cwd_core | Store__Store | 45995600 | 45404020 | +1.3029% | ci/integration-tests/src/helpers/chain.rs:98 |
| cw20_stake | Store__Store | 29285060 | 28858700 | +1.4774% | ci/integration-tests/src/helpers/chain.rs:98 |
| cw_token_swap | Store__Store | 20276940 | 19327750 | +4.9110% | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_pre_propose_single | Store__Store | 33151120 | 32975010 | +0.5341% | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_proposal_single | Store__Store | 53896020 | 52785680 | +2.1035% | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_cw20_staked | Store__Store | 29905635 | 29338585 | +1.9328% | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_cw4 | Store__Store | 22062790 | 21746540 | +1.4543% | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_cw721_staked | Store__Store | 31326440 | 31069590 | +0.8267% | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_native_staked | Store__Store | 24601370 | 24412610 | +0.7732% | ci/integration-tests/src/helpers/chain.rs:98 |
| cwd_voting_staking_denom_staked | Store__Store | 17908970 | 17433000 | +2.7303% | ci/integration-tests/src/helpers/chain.rs:98 |
| stake_cw20_external_rewards | Store__Store | 26120250 | 25375000 | +2.9369% | ci/integration-tests/src/helpers/chain.rs:98 |
| stake_cw20_reward_distributor | Store__Store | 19956840 | 19378680 | +2.9835% | ci/integration-tests/src/helpers/chain.rs:98 |
 
 <details><summary>Raw Report for 9f63900693dfbe3b04d28a1030b9a34cf55780bd </summary><br/> 

| Contract | Op Name | Gas Used | Gas Wanted | File | 
 | --- | --- | --- | --- | --- |
| 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 | Instantiate__exc_stake_create_dao | 1200230 | 1775733 | 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 |
| cwd_core | Store__Store | 45995600 | 68968760 | 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 | Instantiate__inst_dao_no_admin | 1200254 | 1775769 | 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 | 33703650 | 50530835 | 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 | 52041530 | 78037655 | 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>

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index f59f61f7..437a4b07 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -48,16 +48,16 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9"
 
 [[package]]
 name = "async-io"
-version = "1.9.0"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83e21f3a490c72b3b0cf44962180e60045de2925d8dff97918f7ee43c8f637c7"
+checksum = "e8121296a9f05be7f34aa4196b1747243b3b62e048bb7906f644f3fbfc490cf7"
 dependencies = [
+ "async-lock",
  "autocfg",
  "concurrent-queue",
  "futures-lite",
  "libc",
  "log",
- "once_cell",
  "parking",
  "polling",
  "slab",
@@ -66,6 +66,16 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "async-lock"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685"
+dependencies = [
+ "event-listener",
+ "futures-lite",
+]
+
 [[package]]
 name = "async-stream"
 version = "0.3.3"
@@ -294,9 +304,9 @@ checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
 
 [[package]]
 name = "cc"
-version = "1.0.73"
+version = "1.0.74"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574"
 
 [[package]]
 name = "cfg-if"
@@ -1601,6 +1611,12 @@ dependencies = [
  "termcolor",
 ]
 
+[[package]]
+name = "event-listener"
+version = "2.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+
 [[package]]
 name = "eyre"
 version = "0.6.8"
@@ -1622,9 +1638,9 @@ dependencies = [
 
 [[package]]
 name = "ff"
-version = "0.12.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e"
+checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
 dependencies = [
  "rand_core 0.6.4",
  "subtle",
@@ -1944,9 +1960,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
 name = "hyper"
-version = "0.14.20"
+version = "0.14.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
+checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -2368,9 +2384,9 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.15.0"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
 
 [[package]]
 name = "opaque-debug"
@@ -2861,9 +2877,9 @@ dependencies = [
 
 [[package]]
 name = "scoped-tls"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
+checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
 
 [[package]]
 name = "sct"
diff --git a/contracts/cwd-core/src/msg.rs b/contracts/cwd-core/src/msg.rs
index b51bba58..23f62694 100644
--- a/contracts/cwd-core/src/msg.rs
+++ b/contracts/cwd-core/src/msg.rs
@@ -2,9 +2,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses};
 use cosmwasm_std::Addr;
 use cosmwasm_std::{CosmosMsg, Empty};
 use cw_utils::Duration;
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_interface::ModuleInstantiateInfo;
 
 use cwd_macros::{info_query, voting_query};
diff --git a/contracts/proposal/cwd-proposal-multiple/src/msg.rs b/contracts/proposal/cwd-proposal-multiple/src/msg.rs
index cddc3e77..c382be5b 100644
--- a/contracts/proposal/cwd-proposal-multiple/src/msg.rs
+++ b/contracts/proposal/cwd-proposal-multiple/src/msg.rs
@@ -4,10 +4,10 @@ use crate::{
     state::Config,
 };
 use cosmwasm_schema::{cw_serde, QueryResponses};
-use cosmwasm_std::Addr;
+
 use cw_utils::Duration;
 use cwd_hooks::HooksResponse;
-use cwd_interface::voting::InfoResponse;
+
 use cwd_macros::{info_query, proposal_module_query};
 use cwd_voting::{
     multiple_choice::{MultipleChoiceOptions, MultipleChoiceVote, VotingStrategy},
diff --git a/contracts/proposal/cwd-proposal-single/src/msg.rs b/contracts/proposal/cwd-proposal-single/src/msg.rs
index b2f940f1..599fad38 100644
--- a/contracts/proposal/cwd-proposal-single/src/msg.rs
+++ b/contracts/proposal/cwd-proposal-single/src/msg.rs
@@ -1,8 +1,7 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
-use cosmwasm_std::{Addr, CosmosMsg, Empty};
+use cosmwasm_std::{CosmosMsg, Empty};
 use cw_utils::Duration;
 use cwd_hooks::HooksResponse;
-use cwd_interface::voting::InfoResponse;
 
 use cwd_macros::{info_query, proposal_module_query};
 use cwd_voting::{
diff --git a/contracts/voting/cwd-voting-cw20-staked/src/msg.rs b/contracts/voting/cwd-voting-cw20-staked/src/msg.rs
index a44b5b12..c404e340 100644
--- a/contracts/voting/cwd-voting-cw20-staked/src/msg.rs
+++ b/contracts/voting/cwd-voting-cw20-staked/src/msg.rs
@@ -4,9 +4,7 @@ use cosmwasm_std::{Decimal, Uint128};
 use cw20::Cw20Coin;
 use cw20_base::msg::InstantiateMarketingInfo;
 use cw_utils::Duration;
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_macros::{active_query, info_query, token_query, voting_query};
 
 #[cw_serde]
diff --git a/contracts/voting/cwd-voting-cw4/src/msg.rs b/contracts/voting/cwd-voting-cw4/src/msg.rs
index f74f8aa3..76237c05 100644
--- a/contracts/voting/cwd-voting-cw4/src/msg.rs
+++ b/contracts/voting/cwd-voting-cw4/src/msg.rs
@@ -1,8 +1,6 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
 use cosmwasm_std::Addr;
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_macros::{info_query, voting_query};
 
 #[cw_serde]
diff --git a/contracts/voting/cwd-voting-cw721-staked/src/msg.rs b/contracts/voting/cwd-voting-cw721-staked/src/msg.rs
index e0a5e285..449a1857 100644
--- a/contracts/voting/cwd-voting-cw721-staked/src/msg.rs
+++ b/contracts/voting/cwd-voting-cw721-staked/src/msg.rs
@@ -2,9 +2,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses};
 use cosmwasm_std::{Addr, Uint128};
 use cw721::Cw721ReceiveMsg;
 use cw_utils::Duration;
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_interface::Admin;
 use cwd_macros::{info_query, voting_query};
 
diff --git a/contracts/voting/cwd-voting-native-staked/src/msg.rs b/contracts/voting/cwd-voting-native-staked/src/msg.rs
index 97b8fb9b..b5691d42 100644
--- a/contracts/voting/cwd-voting-native-staked/src/msg.rs
+++ b/contracts/voting/cwd-voting-native-staked/src/msg.rs
@@ -2,9 +2,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses};
 use cosmwasm_std::{Addr, Uint128};
 use cw_controllers::ClaimsResponse;
 use cw_utils::Duration;
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_interface::Admin;
 use cwd_macros::{info_query, voting_query};
 
diff --git a/contracts/voting/cwd-voting-staking-denom-staked/src/msg.rs b/contracts/voting/cwd-voting-staking-denom-staked/src/msg.rs
index 24888383..cce2008e 100644
--- a/contracts/voting/cwd-voting-staking-denom-staked/src/msg.rs
+++ b/contracts/voting/cwd-voting-staking-denom-staked/src/msg.rs
@@ -1,8 +1,6 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
 use cosmwasm_std::Addr;
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_macros::{info_query, voting_query};
 
 #[cw_serde]
diff --git a/packages/cwd-interface/src/voting.rs b/packages/cwd-interface/src/voting.rs
index 396da723..4ff148e2 100644
--- a/packages/cwd-interface/src/voting.rs
+++ b/packages/cwd-interface/src/voting.rs
@@ -1,5 +1,4 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
-use cosmwasm_std::Addr;
 use cosmwasm_std::Uint128;
 use cw2::ContractVersion;
 use cwd_macros::{active_query, info_query, proposal_module_query, token_query, voting_query};
@@ -41,11 +40,8 @@ mod tests {
     /// fail to compile if not.
     #[test]
     fn test_macro_expansion() {
-        use crate::voting::InfoResponse;
-        use crate::voting::TotalPowerAtHeightResponse;
-        use crate::voting::VotingPowerAtHeightResponse;
         use cosmwasm_schema::{cw_serde, QueryResponses};
-        use cosmwasm_std::Addr;
+
         use cwd_macros::{active_query, info_query, token_query, voting_query};
         let query = Query::TokenContract {};
 
diff --git a/packages/cwd-macros/src/lib.rs b/packages/cwd-macros/src/lib.rs
index 4f03b4fd..907664a9 100644
--- a/packages/cwd-macros/src/lib.rs
+++ b/packages/cwd-macros/src/lib.rs
@@ -1,6 +1,54 @@
 use proc_macro::TokenStream;
+
 use quote::quote;
-use syn::{parse::Parser, parse_macro_input, AttributeArgs, DataEnum, DeriveInput, Variant};
+use syn::{parse_macro_input, AttributeArgs, DataEnum, DeriveInput, Path};
+
+// Merges the variants of two enums.
+fn merge_variants(metadata: TokenStream, left: TokenStream, right: TokenStream) -> TokenStream {
+    use syn::Data::Enum;
+
+    let args = parse_macro_input!(metadata as AttributeArgs);
+    if let Some(first_arg) = args.first() {
+        return syn::Error::new_spanned(first_arg, "macro takes no arguments")
+            .to_compile_error()
+            .into();
+    }
+
+    let mut left: DeriveInput = parse_macro_input!(left);
+    let right: DeriveInput = parse_macro_input!(right);
+
+    if let (
+        Enum(DataEnum { variants, .. }),
+        Enum(DataEnum {
+            variants: to_add, ..
+        }),
+    ) = (&mut left.data, right.data)
+    {
+        variants.extend(to_add.into_iter());
+
+        quote! { #left }.into()
+    } else {
+        syn::Error::new(left.ident.span(), "variants may only be added for enums")
+            .to_compile_error()
+            .into()
+    }
+}
+
+/// Gets the cwd_interface path for something exported by
+/// cwd_interface. If we are currently compiling the cwd-interface
+/// crate, `crate::{internal}` is returned. If we are not,
+/// `::cwd_interface::{internal}` is returned.
+fn cwd_interface_path(inside: &str) -> Path {
+    let pkg = std::env::var("CARGO_PKG_NAME").unwrap();
+    let base = if pkg == "cwd-interface" {
+        "crate"
+    } else {
+        "::cwd_interface"
+    };
+    let path = format!("{}::{}", base, inside);
+    let path: Path = syn::parse_str(&path).unwrap();
+    path
+}
 
 /// Adds the necessary fields to an enum such that the enum implements the
 /// interface needed to be a voting module.
@@ -61,60 +109,27 @@ use syn::{parse::Parser, parse_macro_input, AttributeArgs, DataEnum, DeriveInput
 /// ```
 #[proc_macro_attribute]
 pub fn voting_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
-    // Make sure that no arguments were passed in.
-    let args = parse_macro_input!(metadata as AttributeArgs);
-    if let Some(first_arg) = args.first() {
-        return syn::Error::new_spanned(first_arg, "voting query macro takes no arguments")
-            .to_compile_error()
-            .into();
-    }
-
-    let mut ast: DeriveInput = parse_macro_input!(input);
-    match &mut ast.data {
-        syn::Data::Enum(DataEnum { variants, .. }) => {
-            let mut voting_power: Variant = syn::parse2(quote! { VotingPowerAtHeight {
-                address: ::std::string::String,
-                height: ::std::option::Option<::std::primitive::u64>
-            } })
-            .unwrap();
-
-            let mut total_power: Variant = syn::parse2(quote! { TotalPowerAtHeight {
-                height: ::std::option::Option<::std::primitive::u64>
-            } })
-            .unwrap();
-
-            let voting_power_attr = syn::Attribute::parse_outer
-                .parse2(quote! {
-                    #[returns(VotingPowerAtHeightResponse)]
-                })
-                .unwrap();
-
-            let total_power_attr = syn::Attribute::parse_outer
-                .parse2(quote! {
-                    #[returns(TotalPowerAtHeightResponse)]
-                })
-                .unwrap();
-
-            voting_power.attrs.push(voting_power_attr[0].clone());
-            total_power.attrs.push(total_power_attr[0].clone());
+    let vp = cwd_interface_path("voting::VotingPowerAtHeightResponse");
+    let tp = cwd_interface_path("voting::TotalPowerAtHeightResponse");
 
-            variants.push(voting_power);
-            variants.push(total_power);
+    merge_variants(
+        metadata,
+        input,
+        quote! {
+        enum Right {
+            #[returns(#vp)]
+            VotingPowerAtHeight {
+            address: ::std::string::String,
+            height: ::std::option::Option<::std::primitive::u64>
+            },
+            #[returns(#tp)]
+            TotalPowerAtHeight {
+            height: ::std::option::Option<::std::primitive::u64>
+            },
         }
-        _ => {
-            return syn::Error::new(
-                ast.ident.span(),
-                "voting query types can not be only be derived for enums",
-            )
-            .to_compile_error()
-            .into()
         }
-    };
-
-    quote! {
-    #ast
-    }
-    .into()
+        .into(),
+    )
 }
 
 /// Adds the necessary fields to an enum such that it implements the
@@ -163,42 +178,17 @@ pub fn voting_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
 /// ```
 #[proc_macro_attribute]
 pub fn token_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
-    // Make sure that no arguments were passed in.
-    let args = parse_macro_input!(metadata as AttributeArgs);
-    if let Some(first_arg) = args.first() {
-        return syn::Error::new_spanned(first_arg, "token query macro takes no arguments")
-            .to_compile_error()
-            .into();
-    }
-
-    let mut ast: DeriveInput = parse_macro_input!(input);
-    match &mut ast.data {
-        syn::Data::Enum(DataEnum { variants, .. }) => {
-            let mut info: Variant = syn::parse2(quote! { TokenContract {} }).unwrap();
-
-            let info_attr = syn::Attribute::parse_outer
-                .parse2(quote! {
-                    #[returns(Addr)]
-                })
-                .unwrap();
-
-            info.attrs.push(info_attr[0].clone());
-            variants.push(info);
+    merge_variants(
+        metadata,
+        input,
+        quote! {
+        enum Right {
+            #[returns(::cosmwasm_std::Addr)]
+            TokenContract {}
         }
-        _ => {
-            return syn::Error::new(
-                ast.ident.span(),
-                "token query types can not be only be derived for enums",
-            )
-            .to_compile_error()
-            .into()
         }
-    };
-
-    quote! {
-    #ast
-    }
-    .into()
+        .into(),
+    )
 }
 
 /// Adds the necessary fields to an enum such that it implements the
@@ -244,42 +234,17 @@ pub fn token_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
 /// ```
 #[proc_macro_attribute]
 pub fn active_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
-    // Make sure that no arguments were passed in.
-    let args = parse_macro_input!(metadata as AttributeArgs);
-    if let Some(first_arg) = args.first() {
-        return syn::Error::new_spanned(first_arg, "token query macro takes no arguments")
-            .to_compile_error()
-            .into();
-    }
-
-    let mut ast: DeriveInput = parse_macro_input!(input);
-    match &mut ast.data {
-        syn::Data::Enum(DataEnum { variants, .. }) => {
-            let mut info: Variant = syn::parse2(quote! { IsActive {} }).unwrap();
-
-            let info_attr = syn::Attribute::parse_outer
-                .parse2(quote! {
-                    #[returns(bool)]
-                })
-                .unwrap();
-
-            info.attrs.push(info_attr[0].clone());
-            variants.push(info);
+    merge_variants(
+        metadata,
+        input,
+        quote! {
+        enum Right {
+            #[returns(::std::primitive::bool)]
+            IsActive {}
         }
-        _ => {
-            return syn::Error::new(
-                ast.ident.span(),
-                "token query types can not be only be derived for enums",
-            )
-            .to_compile_error()
-            .into()
         }
-    };
-
-    quote! {
-    #ast
-    }
-    .into()
+        .into(),
+    )
 }
 
 /// Adds the necessary fields to an enum such that it implements the
@@ -326,41 +291,19 @@ pub fn active_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
 /// ```
 #[proc_macro_attribute]
 pub fn info_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
-    // Make sure that no arguments were passed in.
-    let args = parse_macro_input!(metadata as AttributeArgs);
-    if let Some(first_arg) = args.first() {
-        return syn::Error::new_spanned(first_arg, "info query macro takes no arguments")
-            .to_compile_error()
-            .into();
-    }
+    let i = cwd_interface_path("voting::InfoResponse");
 
-    let mut ast: DeriveInput = parse_macro_input!(input);
-    match &mut ast.data {
-        syn::Data::Enum(DataEnum { variants, .. }) => {
-            let mut info: Variant = syn::parse2(quote! { Info {} }).unwrap();
-            let info_attr = syn::Attribute::parse_outer
-                .parse2(quote! {
-                    #[returns(InfoResponse)]
-                })
-                .unwrap();
-
-            info.attrs.push(info_attr[0].clone());
-            variants.push(info);
+    merge_variants(
+        metadata,
+        input,
+        quote! {
+        enum Right {
+            #[returns(#i)]
+            Info { },
         }
-        _ => {
-            return syn::Error::new(
-                ast.ident.span(),
-                "info query types can not be only be derived for enums",
-            )
-            .to_compile_error()
-            .into()
         }
-    };
-
-    quote! {
-    #ast
-    }
-    .into()
+        .into(),
+    )
 }
 
 /// Adds the necessary fields to an enum such that it implements the
@@ -410,42 +353,17 @@ pub fn info_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
 /// ```
 #[proc_macro_attribute]
 pub fn proposal_module_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
-    // Make sure that no arguments were passed in.
-    let args = parse_macro_input!(metadata as AttributeArgs);
-    if let Some(first_arg) = args.first() {
-        return syn::Error::new_spanned(first_arg, "govmod query macro takes no arguments")
-            .to_compile_error()
-            .into();
-    }
-
-    let mut ast: DeriveInput = parse_macro_input!(input);
-    match &mut ast.data {
-        syn::Data::Enum(DataEnum { variants, .. }) => {
-            let mut dao: Variant = syn::parse2(quote! { Dao {} }).unwrap();
-
-            let dao_attr = syn::Attribute::parse_outer
-                .parse2(quote! {
-                    #[returns(Addr)]
-                })
-                .unwrap();
-
-            dao.attrs.push(dao_attr[0].clone());
-            variants.push(dao);
+    merge_variants(
+        metadata,
+        input,
+        quote! {
+        enum Right {
+            #[returns(::cosmwasm_std::Addr)]
+            Dao {}
         }
-        _ => {
-            return syn::Error::new(
-                ast.ident.span(),
-                "govmod query types can not be only be derived for enums",
-            )
-            .to_compile_error()
-            .into()
         }
-    };
-
-    quote! {
-    #ast
-    }
-    .into()
+        .into(),
+    )
 }
 
 /// Limits the number of variants allowed on an enum at compile


Test patch:
diff --git a/packages/cwd-macros/tests/govmod.rs b/packages/cwd-macros/tests/govmod.rs
index 19f04c13..b3220832 100644
--- a/packages/cwd-macros/tests/govmod.rs
+++ b/packages/cwd-macros/tests/govmod.rs
@@ -1,5 +1,5 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
-use cosmwasm_std::Addr;
+
 use cwd_macros::proposal_module_query;
 
 #[proposal_module_query]
diff --git a/packages/cwd-macros/tests/voting.rs b/packages/cwd-macros/tests/voting.rs
index 0407ebae..27c73730 100644
--- a/packages/cwd-macros/tests/voting.rs
+++ b/packages/cwd-macros/tests/voting.rs
@@ -1,7 +1,5 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_macros::{info_query, voting_query};
 
 /// enum for testing. Important that this derives things / has other
diff --git a/test-contracts/cwd-proposal-sudo/src/msg.rs b/test-contracts/cwd-proposal-sudo/src/msg.rs
index 7a9bbff7..84914b17 100644
--- a/test-contracts/cwd-proposal-sudo/src/msg.rs
+++ b/test-contracts/cwd-proposal-sudo/src/msg.rs
@@ -1,6 +1,5 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
 use cosmwasm_std::{Addr, CosmosMsg};
-use cwd_interface::voting::InfoResponse;
 
 use cwd_macros::{info_query, proposal_module_query};
 
diff --git a/test-contracts/cwd-voting-cw20-balance/src/msg.rs b/test-contracts/cwd-voting-cw20-balance/src/msg.rs
index a70d7fbf..3496c120 100644
--- a/test-contracts/cwd-voting-cw20-balance/src/msg.rs
+++ b/test-contracts/cwd-voting-cw20-balance/src/msg.rs
@@ -1,10 +1,8 @@
 use cosmwasm_schema::{cw_serde, QueryResponses};
-use cosmwasm_std::Addr;
+
 use cw20::Cw20Coin;
 use cw20_base::msg::InstantiateMarketingInfo;
-use cwd_interface::voting::InfoResponse;
-use cwd_interface::voting::TotalPowerAtHeightResponse;
-use cwd_interface::voting::VotingPowerAtHeightResponse;
+
 use cwd_macros::{info_query, token_query, voting_query};
 
 #[cw_serde]