Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Update flat rate whitelist to support multiple admins #254

Merged
merged 7 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 59 additions & 26 deletions contracts/whitelist-updatable-flatrate/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, Event, MessageInfo, Order, StdError,
StdResult,
ensure, to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, Event, MessageInfo, Order,
StdError, StdResult,
};
use cw2::set_contract_version;
use semver::Version;
Expand All @@ -27,8 +27,19 @@
) -> Result<Response, ContractError> {
nonpayable(&info)?;
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

let admin_list: Vec<Addr> = msg.admin_list.as_ref().map_or_else(
|| Ok(vec![info.sender.clone()]),
|admins| {
admins
.iter()
.map(|addr| deps.api.addr_validate(addr))
.collect()
},
)?;

let config = Config {
admin: info.sender,
admins: admin_list,
per_address_limit: msg.per_address_limit,
mint_discount_amount: msg.mint_discount_amount,
};
Expand Down Expand Up @@ -60,7 +71,9 @@
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::UpdateAdmin { new_admin } => execute_update_admin(deps, info, new_admin),
ExecuteMsg::UpdateAdmins { new_admin_list } => {
execute_update_admins(deps, info, new_admin_list)
}
ExecuteMsg::AddAddresses { addresses } => execute_add_addresses(deps, info, addresses),
ExecuteMsg::RemoveAddresses { addresses } => {
execute_remove_addresses(deps, info, addresses)
Expand All @@ -73,21 +86,33 @@
}
}

pub fn execute_update_admin(
pub fn execute_update_admins(
deps: DepsMut,
info: MessageInfo,
new_admin: String,
new_admin_list: Vec<String>,
) -> Result<Response, ContractError> {
nonpayable(&info)?;
let mut config = CONFIG.load(deps.storage)?;
if config.admin != info.sender {
return Err(ContractError::Unauthorized {});
}
ensure!(
config.admins.contains(&info.sender),
ContractError::Unauthorized {}
);

config.admins = new_admin_list
.into_iter()
.map(|address| deps.api.addr_validate(&address))
.collect::<StdResult<Vec<Addr>>>()?;

Check warning on line 104 in contracts/whitelist-updatable-flatrate/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/whitelist-updatable-flatrate/src/contract.rs#L104

Added line #L104 was not covered by tests

config.admin = deps.api.addr_validate(&new_admin)?;
CONFIG.save(deps.storage, &config)?;
let event = Event::new("update-admin")
.add_attribute("new_admin", config.admin)
.add_attribute(
"new_admin_list",
config
.admins
.into_iter()
.map(|x| x.to_string())
.collect::<String>(),
)
.add_attribute("sender", info.sender);
Ok(Response::new().add_event(event))
}
Expand All @@ -99,9 +124,10 @@
) -> Result<Response, ContractError> {
let config = CONFIG.load(deps.storage)?;
let mut count = TOTAL_ADDRESS_COUNT.load(deps.storage)?;
if config.admin != info.sender {
return Err(ContractError::Unauthorized {});
}
ensure!(
config.admins.contains(&info.sender),
ContractError::Unauthorized {}

Check warning on line 129 in contracts/whitelist-updatable-flatrate/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/whitelist-updatable-flatrate/src/contract.rs#L129

Added line #L129 was not covered by tests
);

// dedupe
addresses.sort_unstable();
Expand Down Expand Up @@ -135,9 +161,10 @@
nonpayable(&info)?;
let config = CONFIG.load(deps.storage)?;
let mut count = TOTAL_ADDRESS_COUNT.load(deps.storage)?;
if config.admin != info.sender {
return Err(ContractError::Unauthorized {});
}
ensure!(
config.admins.contains(&info.sender),
ContractError::Unauthorized {}

Check warning on line 166 in contracts/whitelist-updatable-flatrate/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/whitelist-updatable-flatrate/src/contract.rs#L166

Added line #L166 was not covered by tests
);

// dedupe
addresses.sort_unstable();
Expand Down Expand Up @@ -208,9 +235,10 @@
) -> Result<Response, ContractError> {
nonpayable(&info)?;
let mut config = CONFIG.load(deps.storage)?;
if config.admin != info.sender {
return Err(ContractError::Unauthorized {});
}
ensure!(
config.admins.contains(&info.sender),
ContractError::Unauthorized {}

Check warning on line 240 in contracts/whitelist-updatable-flatrate/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/whitelist-updatable-flatrate/src/contract.rs#L240

Added line #L240 was not covered by tests
);

config.per_address_limit = limit;
CONFIG.save(deps.storage, &config)?;
Expand All @@ -224,9 +252,10 @@
pub fn execute_purge(deps: DepsMut, info: MessageInfo) -> Result<Response, ContractError> {
nonpayable(&info)?;
let config = CONFIG.load(deps.storage)?;
if config.admin != info.sender {
return Err(ContractError::Unauthorized {});
}
ensure!(
config.admins.contains(&info.sender),
ContractError::Unauthorized {}

Check warning on line 257 in contracts/whitelist-updatable-flatrate/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/whitelist-updatable-flatrate/src/contract.rs#L257

Added line #L257 was not covered by tests
);

let keys = WHITELIST
.keys(deps.as_ref().storage, None, None, Order::Ascending)
Expand All @@ -251,7 +280,7 @@
to_json_binary(&query_includes_address(deps, address)?)
}
QueryMsg::MintCount { address } => to_json_binary(&query_mint_count(deps, address)?),
QueryMsg::Admin {} => to_json_binary(&query_admin(deps)?),
QueryMsg::Admins {} => to_json_binary(&query_admins(deps)?),
QueryMsg::AddressCount {} => to_json_binary(&query_address_count(deps)?),
QueryMsg::PerAddressLimit {} => to_json_binary(&query_per_address_limit(deps)?),
QueryMsg::IsProcessable { address } => {
Expand All @@ -274,9 +303,13 @@
WHITELIST.load(deps.storage, addr)
}

pub fn query_admin(deps: Deps) -> StdResult<String> {
pub fn query_admins(deps: Deps) -> StdResult<Vec<String>> {
let config = CONFIG.load(deps.storage)?;
Ok(config.admin.to_string())
Ok(config
.admins
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>())
}

pub fn query_address_count(deps: Deps) -> StdResult<u64> {
Expand Down
30 changes: 19 additions & 11 deletions contracts/whitelist-updatable-flatrate/src/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod tests {
use sg_multi_test::StargazeApp;

const CREATOR: &str = "creator";
const TEMP_ADMIN: &str = "temp_admin";
const OTHER_ADMIN: &str = "other_admin";
const PER_ADDRESS_LIMIT: u32 = 10;

Expand Down Expand Up @@ -63,7 +64,7 @@ mod tests {

#[test]
pub fn init() {
let addrs: Vec<String> = vec![
let addrs = vec![
"addr0001".to_string(),
"addr0002".to_string(),
"addr0003".to_string(),
Expand All @@ -75,6 +76,7 @@ mod tests {
per_address_limit: PER_ADDRESS_LIMIT,
addresses: addrs.clone(),
mint_discount_amount: None,
admin_list: Some(vec![CREATOR.to_string(), TEMP_ADMIN.to_string()]),
};

let mut app = custom_mock_app();
Expand Down Expand Up @@ -106,11 +108,11 @@ mod tests {
)
.unwrap();

let admin: String = app
let admins: Vec<String> = app
.wrap()
.query_wasm_smart(&wl_addr, &QueryMsg::Admin {})
.query_wasm_smart(&wl_addr, &QueryMsg::Admins {})
.unwrap();
assert_eq!(admin, CREATOR.to_string());
assert_eq!(admins, [CREATOR.to_string(), TEMP_ADMIN.to_string()]);

let count: u64 = app
.wrap()
Expand Down Expand Up @@ -174,7 +176,7 @@ mod tests {

#[test]
fn exec() {
let addrs: Vec<String> = vec![
let addrs = vec![
"addr0001".to_string(),
"addr0002".to_string(),
"addr0003".to_string(),
Expand All @@ -186,6 +188,7 @@ mod tests {
per_address_limit: 10,
addresses: addrs,
mint_discount_amount: None,
admin_list: None,
};

let mut app = custom_mock_app();
Expand Down Expand Up @@ -217,16 +220,18 @@ mod tests {
)
.unwrap();

let msg = ExecuteMsg::UpdateAdmin {
new_admin: OTHER_ADMIN.to_string(),
let msg = ExecuteMsg::UpdateAdmins {
new_admin_list: vec![OTHER_ADMIN.to_string(), TEMP_ADMIN.to_string()],
};
let res = app.execute_contract(Addr::unchecked(TEMP_ADMIN), wl_addr.clone(), &msg, &[]);
assert!(res.is_err());
let res = app.execute_contract(Addr::unchecked(CREATOR), wl_addr.clone(), &msg, &[]);
assert!(res.is_ok());
let res: String = app
let res: Vec<String> = app
.wrap()
.query_wasm_smart(&wl_addr, &QueryMsg::Admin {})
.query_wasm_smart(&wl_addr, &QueryMsg::Admins {})
.unwrap();
assert_eq!(res, OTHER_ADMIN.to_string());
assert_eq!(res, [OTHER_ADMIN.to_string(), TEMP_ADMIN.to_string()]);

// add addresses
let msg = ExecuteMsg::AddAddresses {
Expand Down Expand Up @@ -397,7 +402,10 @@ mod tests {
.wrap()
.query_wasm_smart(&wl_addr, &QueryMsg::Config {})
.unwrap();
assert_eq!(res.admin, Addr::unchecked(OTHER_ADMIN).to_string());
assert_eq!(
res.admins,
vec![OTHER_ADMIN.to_string(), TEMP_ADMIN.to_string()]
);
assert_eq!(res.per_address_limit, new_per_address_limit);
}
}
7 changes: 4 additions & 3 deletions contracts/whitelist-updatable-flatrate/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ pub struct InstantiateMsg {
pub addresses: Vec<String>,
pub per_address_limit: u32,
pub mint_discount_amount: Option<u64>,
pub admin_list: Option<Vec<String>>,
}

#[cw_serde]
pub enum ExecuteMsg {
UpdateAdmin {
new_admin: String,
UpdateAdmins {
new_admin_list: Vec<String>,
},
AddAddresses {
addresses: Vec<String>,
Expand Down Expand Up @@ -43,7 +44,7 @@ pub enum QueryMsg {
#[returns(bool)]
IsProcessable { address: String },
#[returns(cw_controllers::AdminResponse)]
Admin {},
Admins {},
#[returns(u64)]
AddressCount {},
#[returns(u64)]
Expand Down
2 changes: 1 addition & 1 deletion contracts/whitelist-updatable-flatrate/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cw_storage_plus::{Item, Map};

#[cw_serde]
pub struct Config {
pub admin: Addr,
pub admins: Vec<Addr>,
pub per_address_limit: u32,
pub mint_discount_amount: Option<u64>,
}
Expand Down
Loading