Skip to content

Commit

Permalink
query auth added
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhishek-1857 committed Mar 21, 2024
1 parent 792aaf2 commit 1911683
Show file tree
Hide file tree
Showing 70 changed files with 796 additions and 1,505 deletions.
230 changes: 223 additions & 7 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@ exclude = ["ci/configs/", "wasmvm/libwasmvm"]
members = [
"./contracts/dao-dao-core",
"./contracts/external/cw-admin-factory",
"./contracts/external/snip20-reference-impl",
"./contracts/external/snip20-reference-impl",
"./contracts/external/snip721-reference-impl",
"./contracts/external/snip721-roles/",
"./contracts/external/snip721-roles/",
"./contracts/proposal/*",
"./contracts/pre-propose/*",
"./contracts/staking/*",
"./contracts/voting/*",
"./packages/*",

# "ci/*",
]
"./packages/*"
]
resolver = "2"

[workspace.package]
Expand Down Expand Up @@ -140,3 +138,9 @@ cosmwasm-schema = { git = "https://github.com/scrtlabs/cosmwasm/", branch = "sec
snip20-reference-impl = { path = "./contracts/external/snip20-reference-impl/",default-features = false }
snip721-reference-impl = { path = "./contracts/external/snip721-reference-impl/" ,default-features = false}
cosmos-sdk-proto = { version = "0.20.0", default-features = false }
shade-protocol = { git = "https://github.com/securesecrets/shade", rev = "lend-v1",features = [
"query_auth_impl",
"admin","basic_staking"
] }
shade-multi-test = { git = "https://github.com/securesecrets/shade", rev = "lend-v1",features = [ "query_auth", "admin" ] }

3 changes: 2 additions & 1 deletion contracts/dao-dao-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ backtraces = ["cosmwasm-std/backtraces"]
library = []

[dependencies]
cosmwasm-std = { workspace = true, features = ["ibc3"] }
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
secret-storage-plus = { workspace = true }
secret-cw2 = { workspace = true }
Expand All @@ -33,6 +33,7 @@ snip721-reference-impl = { workspace = true }
schemars = { workspace = true }
serde = { workspace = true }
secret-cw-controllers = { workspace = true }
shade-protocol ={ workspace = true }


[dev-dependencies]
Expand Down
18 changes: 6 additions & 12 deletions contracts/dao-dao-core/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use secret_cw2::{get_contract_version, set_contract_version, ContractVersion};
use secret_cw_controllers::ReplyEvent;
use secret_toolkit::{serialization::Json, storage::Keymap, utils::HandleCallback};
use secret_utils::{parse_reply_event_for_contract_address, Duration};
use shade_protocol::basic_staking::Auth;
use snip20_reference_impl::msg::ExecuteAnswer;

use crate::state::{
Expand Down Expand Up @@ -656,11 +657,9 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
QueryMsg::ProposalModuleCount {} => query_proposal_module_count(deps),
QueryMsg::TotalPowerAtHeight { height } => query_total_power_at_height(deps, height),
QueryMsg::VotingModule {} => query_voting_module(deps),
QueryMsg::VotingPowerAtHeight {
address,
height,
key,
} => query_voting_power_at_height(deps, address, key, height),
QueryMsg::VotingPowerAtHeight { auth, height } => {
query_voting_power_at_height(deps, auth, height)
}
QueryMsg::ActiveProposalModules { start_after, limit } => {
query_active_proposal_modules(deps, start_after, limit)
}
Expand Down Expand Up @@ -822,19 +821,14 @@ pub fn query_dump_state(deps: Deps, env: Env) -> StdResult<Binary> {

pub fn query_voting_power_at_height(
deps: Deps,
address: String,
key: String,
auth: Auth,
height: Option<u64>,
) -> StdResult<Binary> {
let voting_module = VOTING_MODULE.load(deps.storage)?;
let voting_power: voting::VotingPowerAtHeightResponse = deps.querier.query_wasm_smart(
voting_module.code_hash,
voting_module.addr,
&voting::Query::VotingPowerAtHeight {
height,
address,
key,
},
&voting::Query::VotingPowerAtHeight { height, auth },
)?;
to_binary(&voting_power)
}
Expand Down
1 change: 1 addition & 0 deletions contracts/external/snip721-reference-impl/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2985,6 +2985,7 @@ pub fn query_transactions(
/// * `token_ids` - a list of token ids to check if the address has transfer approval
/// * `viewer` - optional address and key making an authenticated query request
/// * `from_permit` - address derived from an Owner permit, if applicable
#[allow(unknown_lints)]
pub fn query_verify_approval(
deps: Deps,
block: &BlockInfo,
Expand Down
1 change: 1 addition & 0 deletions contracts/external/snip721-roles/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ thiserror = { workspace = true }
secret-toolkit ={ workspace = true}
snip721-reference-impl ={ workspace = true }
schemars ={ workspace=true }
shade-protocol ={ workspace = true }

[dev-dependencies]
secret-multi-test = { workspace = true }
Expand Down
143 changes: 35 additions & 108 deletions contracts/external/snip721-roles/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@ use cw4::{
};
use schemars::JsonSchema;
use secret_cw_controllers::HookItem;
use secret_toolkit::permit::{Permit, RevokedPermits, TokenPermissions};
use secret_toolkit::utils::InitCallback;
use secret_toolkit::viewing_key::{ViewingKey, ViewingKeyStore};
use serde::{Deserialize, Serialize};
// use cw721_base::Cw721Contract;
// use snip721_reference_impl::msg::InstantiateMsg as Cw721BaseInstantiateMsg;

use dao_snip721_extensions::roles::{
CreateViewingKey, ExecuteExt, QueryExt, QueryWithPermit, ViewingKeyError,
use dao_snip721_extensions::roles::{ExecuteExt, QueryExt};
use shade_protocol::basic_staking::{Auth, AuthPermit};
use shade_protocol::query_auth::helpers::{
authenticate_permit, authenticate_vk, PermitAuthentication,
};
use shade_protocol::Contract;
use std::cmp::Ordering;
// use snip721_reference_impl::msg::{ExecuteMsg as Snip721ExecuteMsg};

use crate::state::{Config, MembersStore, TotalStore, MEMBERS_PRIMARY, SNIP721_INFO};
use crate::state::{Config, MembersStore, TotalStore, MEMBERS_PRIMARY, QUERY_AUTH, SNIP721_INFO};
use crate::{error::RolesContractError as ContractError, state::HOOKS};

// Version info for migration
Expand Down Expand Up @@ -107,6 +108,8 @@ pub fn instantiate(
// Initialize total weight to zero
TotalStore::save(deps.storage, env.block.height, 0)?;

QUERY_AUTH.save(deps.storage, &msg.query_auth.into_valid(deps.api)?)?;

secret_cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

Ok(Response::new()
Expand Down Expand Up @@ -223,11 +226,6 @@ pub fn execute(
ExecuteExt::UpdateTokenRole { token_id, role } => {
execute_update_token_role(deps, env, info, token_id, role)
}
ExecuteExt::CreateViewingKey { entropy, .. } => {
try_create_key(deps, env, info, entropy)
}
ExecuteExt::SetViewingKey { key, .. } => try_set_key(deps, info, key),
ExecuteExt::RevokePermit { permit_name, .. } => revoke_permit(deps, info, permit_name),
},
}
}
Expand Down Expand Up @@ -908,58 +906,20 @@ pub fn execute_update_token_weight(
.add_message(exec_msg))
}

pub fn try_set_key(
deps: DepsMut,
info: MessageInfo,
key: String,
) -> Result<Response, ContractError> {
ViewingKey::set(deps.storage, info.sender.as_str(), key.as_str());
Ok(Response::default())
}

pub fn try_create_key(
deps: DepsMut,
env: Env,
info: MessageInfo,
entropy: String,
) -> Result<Response, ContractError> {
let key = ViewingKey::create(
deps.storage,
&info,
&env,
info.sender.as_str(),
entropy.as_ref(),
);

Ok(Response::new().set_data(to_binary(&CreateViewingKey { key })?))
}

fn revoke_permit(
deps: DepsMut,
info: MessageInfo,
permit_name: String,
) -> Result<Response, ContractError> {
RevokedPermits::revoke_permit(
deps.storage,
PREFIX_REVOKED_PERMITS,
info.sender.as_str(),
&permit_name,
);

Ok(Response::default())
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::ExtensionQuery(extension_query) => match extension_query {
QueryExt::Hooks {} => to_binary(&HOOKS.query_hooks(deps)?),
QueryExt::ListMembers { start_after, limit } => {
to_binary(&query_list_members(deps, start_after, limit)?)
}
QueryExt::TotalWeight { at_height } => to_binary(&query_total_weight(deps, at_height)?),
QueryExt::WithPermit { permit, query } => permit_queries(deps, env, permit, query),
_ => viewing_keys_queries(deps, env, extension_query),
QueryExt::Member { auth, at_height } => {
let query_auth = QUERY_AUTH.load(deps.storage)?;
let user = authenticate(deps, auth, query_auth)?;
to_binary(&query_member(deps, user, at_height)?)
}
},
QueryMsg::GetNftContractInfo {} => to_binary(&get_info(deps)?),
_ => {
Expand All @@ -974,58 +934,6 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
}
}

fn permit_queries(
deps: Deps,
env: Env,
permit: Permit,
query: QueryWithPermit,
) -> Result<Binary, StdError> {
// Validate permit content

let _account = secret_toolkit::permit::validate(
deps,
PREFIX_REVOKED_PERMITS,
&permit,
env.contract.address.clone().into_string(),
None,
)?;

// Permit validated! We can now execute the query.
match query {
QueryWithPermit::Member { addr, at_height } => {
if !permit.check_permission(&TokenPermissions::Balance) {
return Err(StdError::generic_err(format!(
"No permission to query memeber, got permissions {:?}",
permit.params.permissions
)));
}

to_binary(&query_member(deps, addr, at_height)?)
}
}
}

pub fn viewing_keys_queries(deps: Deps, _env: Env, msg: QueryExt) -> StdResult<Binary> {
let (addresses, key) = msg.get_validation_params(deps.api)?;

for address in addresses {
let result = ViewingKey::check(deps.storage, address.as_str(), key.as_str());
if result.is_ok() {
return match msg {
// Base
QueryExt::Member {
addr, at_height, ..
} => to_binary(&query_member(deps, addr, at_height)?),
_ => panic!("This query type does not require authentication"),
};
}
}

to_binary(&ViewingKeyError {
msg: "Wrong viewing key for this address or viewing key not set".to_string(),
})
}

pub fn query_total_weight(deps: Deps, height: Option<u64>) -> StdResult<TotalWeightResponse> {
if height.is_some() {
let weight = TotalStore::may_load_at_height(deps.storage, height.unwrap())?;
Expand All @@ -1046,8 +954,7 @@ pub fn get_info(deps: Deps) -> StdResult<Config> {
})
}

pub fn query_member(deps: Deps, addr: String, height: Option<u64>) -> StdResult<MemberResponse> {
let addr = deps.api.addr_validate(&addr)?;
pub fn query_member(deps: Deps, addr: Addr, height: Option<u64>) -> StdResult<MemberResponse> {
if height.is_some() {
let weight = MembersStore::may_load_at_height(deps.storage, addr.clone(), height.unwrap())?;

Expand Down Expand Up @@ -1113,6 +1020,26 @@ pub fn query_list_members(
Ok(response)
}

pub fn authenticate(deps: Deps, auth: Auth, query_auth: Contract) -> StdResult<Addr> {
match auth {
Auth::ViewingKey { key, address } => {
let address = deps.api.addr_validate(&address)?;
if !authenticate_vk(address.clone(), key, &deps.querier, &query_auth)? {
return Err(StdError::generic_err("Invalid Viewing Key"));
}
Ok(address)
}
Auth::Permit(permit) => {
let res: PermitAuthentication<AuthPermit> =
authenticate_permit(permit, &deps.querier, query_auth)?;
if res.revoked {
return Err(StdError::generic_err("Permit Revoked"));
}
Ok(res.sender)
}
}
}

#[entry_point]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
match msg.id {
Expand Down
3 changes: 3 additions & 0 deletions contracts/external/snip721-roles/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use cosmwasm_std::Addr;
use dao_snip721_extensions::roles::{ExecuteExt, QueryExt};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use shade_protocol::utils::asset::RawContract;

use crate::snip721::{self, Snip721ExecuteMsg, Snip721QueryMsg};

Expand All @@ -24,6 +25,8 @@ pub struct InstantiateMsg {

/// optional privacy configuration for the contract
pub config: Option<snip721::InstantiateConfig>,

pub query_auth: RawContract,
}

#[cw_serde]
Expand Down
2 changes: 2 additions & 0 deletions contracts/external/snip721-roles/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use secret_cw_controllers::Hooks;
use secret_storage_plus::Item;
use secret_toolkit::storage::Keymap;
use serde::{Deserialize, Serialize};
use shade_protocol::Contract;

#[derive(Serialize, Deserialize, JsonSchema, Debug, Default)]
pub struct Config {
Expand All @@ -14,6 +15,7 @@ pub struct Config {
// Hooks to contracts that will receive staking and unstaking messages.
pub const HOOKS: Hooks = Hooks::new("hooks");
pub const SNIP721_INFO: Item<Config> = Item::new("si");
pub const QUERY_AUTH: Item<Contract> = Item::new("qa");

// /// A historic snapshot of total weight over time
// pub const TOTAL: SnapshotItem<u64> = SnapshotItem::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ thiserror = { workspace = true }
dao-interface = { workspace = true }
secret-toolkit ={ workspace = true }
cw-hooks ={ workspace = true }
shade-protocol ={ workspace = true }

[dev-dependencies]
cw-denom = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use dao_pre_propose_base::{
use dao_voting::deposit::DepositRefundPolicy;
use dao_voting::proposal::SingleChoiceProposeMsg as ProposeMsg;
use secret_cw2::set_contract_version;
use shade_protocol::basic_staking::Auth;

use crate::msg::{
ApproverProposeMessage, ExecuteExt, ExecuteMsg, InstantiateExt, InstantiateMsg, ProposeMessage,
Expand Down Expand Up @@ -77,7 +78,12 @@ pub fn execute_propose(
let pre_propose_base = PrePropose::default();
let config = pre_propose_base.config.load(deps.storage)?;

pre_propose_base.check_can_submit(deps.as_ref(), info.sender.clone(), key.clone())?;
let auth = Auth::ViewingKey {
key: key.clone(),
address: info.sender.clone().to_string(),
};

pre_propose_base.check_can_submit(deps.as_ref(), auth)?;

// Take deposit, if configured.
let deposit_messages = if let Some(ref deposit_info) = config.deposit_info {
Expand Down
1 change: 1 addition & 0 deletions contracts/proposal/dao-proposal-condorcet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ serde ={ workspace = true }
schemars ={ workspace = true }
secret-toolkit ={ workspace = true }
secret-cw-controllers ={ workspace = true }
shade-protocol ={ workspace = true }

[dev-dependencies]
cosmwasm-schema = { workspace = true }
Expand Down
Loading

0 comments on commit 1911683

Please sign in to comment.