Skip to content
Open
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
28 changes: 27 additions & 1 deletion contracts/factories/base-factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use cw_utils::must_pay;
use semver::Version;
use sg1::{checked_fair_burn, transfer_funds_to_launchpad_dao};
use sg2::msg::UpdateMinterParamsMsg;
use sg2::query::{AllowedCollectionCodeIdResponse, AllowedCollectionCodeIdsResponse, Sg2QueryMsg};
use sg2::query::{AllowedCollectionCodeIdResponse, AllowedCollectionCodeIdsResponse, IsContractWhitelistedResponse, Sg2QueryMsg, WhitelistedContractsResponse};
use sg2::MinterParams;
use sg_utils::NATIVE_DENOM;

Expand Down Expand Up @@ -203,6 +203,12 @@ pub fn query(deps: Deps, _env: Env, msg: Sg2QueryMsg) -> StdResult<Binary> {
Sg2QueryMsg::AllowedCollectionCodeId(code_id) => {
to_json_binary(&query_allowed_collection_code_id(deps, code_id)?)
}
Sg2QueryMsg::IsContractWhitelisted { address } => {
to_json_binary(&query_is_contract_whitelisted_base(deps, address)?)
}
Sg2QueryMsg::WhitelistedContracts { start_after: _, limit: _ } => {
to_json_binary(&query_whitelisted_contracts_base(deps)?)
}
}
}

Expand All @@ -227,6 +233,26 @@ fn query_allowed_collection_code_id(
Ok(AllowedCollectionCodeIdResponse { allowed })
}

fn query_is_contract_whitelisted_base(
_deps: Deps,
address: String,
) -> StdResult<IsContractWhitelistedResponse> {
// Base factory doesn't have whitelist functionality, so all contracts are considered non-whitelisted
Ok(IsContractWhitelistedResponse {
address,
is_whitelisted: false,
})
}

fn query_whitelisted_contracts_base(
_deps: Deps,
) -> StdResult<WhitelistedContractsResponse> {
// Base factory doesn't have whitelist functionality, so return empty list
Ok(WhitelistedContractsResponse {
contracts: vec![],
})
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(
deps: DepsMut,
Expand Down
28 changes: 27 additions & 1 deletion contracts/factories/open-edition-factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use base_factory::contract::{
};
use base_factory::ContractError as BaseContractError;
use sg1::{checked_fair_burn, transfer_funds_to_launchpad_dao};
use sg2::query::{AllowedCollectionCodeIdResponse, AllowedCollectionCodeIdsResponse, Sg2QueryMsg};
use sg2::query::{AllowedCollectionCodeIdResponse, AllowedCollectionCodeIdsResponse, IsContractWhitelistedResponse, Sg2QueryMsg, WhitelistedContractsResponse};

use crate::error::ContractError;
use crate::msg::{
Expand Down Expand Up @@ -190,6 +190,12 @@ pub fn query(deps: Deps, _env: Env, msg: Sg2QueryMsg) -> StdResult<Binary> {
Sg2QueryMsg::AllowedCollectionCodeId(code_id) => {
to_json_binary(&query_allowed_collection_code_id(deps, code_id)?)
}
Sg2QueryMsg::IsContractWhitelisted { address } => {
to_json_binary(&query_is_contract_whitelisted_open_edition(deps, address)?)
}
Sg2QueryMsg::WhitelistedContracts { start_after: _, limit: _ } => {
to_json_binary(&query_whitelisted_contracts_open_edition(deps)?)
}
}
}

Expand All @@ -214,6 +220,26 @@ fn query_allowed_collection_code_id(
Ok(AllowedCollectionCodeIdResponse { allowed })
}

fn query_is_contract_whitelisted_open_edition(
_deps: Deps,
address: String,
) -> StdResult<IsContractWhitelistedResponse> {
// Open edition factory doesn't have whitelist functionality, so all contracts are considered non-whitelisted
Ok(IsContractWhitelistedResponse {
address,
is_whitelisted: false,
})
}

fn query_whitelisted_contracts_open_edition(
_deps: Deps,
) -> StdResult<WhitelistedContractsResponse> {
// Open edition factory doesn't have whitelist functionality, so return empty list
Ok(WhitelistedContractsResponse {
contracts: vec![],
})
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(
deps: DepsMut,
Expand Down
194 changes: 151 additions & 43 deletions contracts/factories/vending-factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ use cw2::set_contract_version;
use cw_utils::must_pay;
use semver::Version;
use sg1::{checked_fair_burn, transfer_funds_to_launchpad_dao};
use sg2::query::{AllowedCollectionCodeIdResponse, AllowedCollectionCodeIdsResponse, Sg2QueryMsg};
use sg2::query::{AllowedCollectionCodeIdResponse, AllowedCollectionCodeIdsResponse, IsContractWhitelistedResponse, Sg2QueryMsg, WhitelistedContractsResponse};
use sg_utils::NATIVE_DENOM;

use crate::error::ContractError;
use crate::msg::{
ExecuteMsg, InstantiateMsg, ParamsResponse, SudoMsg, VendingMinterCreateMsg,
VendingUpdateParamsMsg,
ExecuteMsg, InstantiateMsg, MigrateMsg, ParamsResponse, SudoMsg,
VendingMinterCreateMsg, VendingUpdateParamsMsg, WhitelistUpdate,
};
use crate::state::SUDO_PARAMS;
use crate::state::{SUDO_PARAMS, WHITELISTED_CONTRACTS};

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:vending-factory";
Expand All @@ -36,7 +36,18 @@ pub fn instantiate(

SUDO_PARAMS.save(deps.storage, &msg.params)?;

Ok(Response::new())
// Initialize whitelist if provided
if let Some(initial_whitelist) = msg.initial_whitelist {
for address_str in initial_whitelist {
let addr = deps.api.addr_validate(&address_str)?;
WHITELISTED_CONTRACTS.save(deps.storage, &addr, &true)?;
}
}

Ok(Response::new()
.add_attribute("action", "instantiate")
.add_attribute("contract_name", CONTRACT_NAME)
.add_attribute("contract_version", CONTRACT_VERSION))
}

#[cfg_attr(not(feature = "library"), entry_point)]
Expand Down Expand Up @@ -129,6 +140,15 @@ pub fn execute_create_minter(
pub fn sudo(deps: DepsMut, env: Env, msg: SudoMsg) -> Result<Response, ContractError> {
match msg {
SudoMsg::UpdateParams(params_msg) => sudo_update_params(deps, env, *params_msg),
SudoMsg::AddContractToWhitelist { address } => {
sudo_add_contract_to_whitelist(deps, env, address)
}
SudoMsg::RemoveContractFromWhitelist { address } => {
sudo_remove_contract_from_whitelist(deps, env, address)
}
SudoMsg::UpdateContractWhitelist { add, remove } => {
sudo_update_contract_whitelist(deps, env, add, remove)
}
}
}

Expand Down Expand Up @@ -189,6 +209,12 @@ pub fn query(deps: Deps, _env: Env, msg: Sg2QueryMsg) -> StdResult<Binary> {
Sg2QueryMsg::AllowedCollectionCodeId(code_id) => {
to_json_binary(&query_allowed_collection_code_id(deps, code_id)?)
}
Sg2QueryMsg::IsContractWhitelisted { address } => {
to_json_binary(&query_is_contract_whitelisted(deps, address)?)
}
Sg2QueryMsg::WhitelistedContracts { start_after, limit } => {
to_json_binary(&query_whitelisted_contracts(deps, start_after, limit)?)
}
}
}

Expand All @@ -213,11 +239,100 @@ fn query_allowed_collection_code_id(
Ok(AllowedCollectionCodeIdResponse { allowed })
}

pub fn sudo_add_contract_to_whitelist(
deps: DepsMut,
_env: Env,
address: String,
) -> Result<Response, ContractError> {
let addr = deps.api.addr_validate(&address)?;
WHITELISTED_CONTRACTS.save(deps.storage, &addr, &true)?;

Ok(Response::new()
.add_attribute("action", "add_contract_to_whitelist")
.add_attribute("contract_address", address))
}

pub fn sudo_remove_contract_from_whitelist(
deps: DepsMut,
_env: Env,
address: String,
) -> Result<Response, ContractError> {
let addr = deps.api.addr_validate(&address)?;
WHITELISTED_CONTRACTS.remove(deps.storage, &addr);

Ok(Response::new()
.add_attribute("action", "remove_contract_from_whitelist")
.add_attribute("contract_address", address))
}

pub fn sudo_update_contract_whitelist(
deps: DepsMut,
_env: Env,
add: Vec<String>,
remove: Vec<String>,
) -> Result<Response, ContractError> {
let mut response = Response::new().add_attribute("action", "update_contract_whitelist");

// Add contracts to whitelist
for address in add {
let addr = deps.api.addr_validate(&address)?;
WHITELISTED_CONTRACTS.save(deps.storage, &addr, &true)?;
response = response.add_attribute("added", address);
}

// Remove contracts from whitelist
for address in remove {
let addr = deps.api.addr_validate(&address)?;
WHITELISTED_CONTRACTS.remove(deps.storage, &addr);
response = response.add_attribute("removed", address);
}

Ok(response)
}

fn query_is_contract_whitelisted(
deps: Deps,
address: String,
) -> StdResult<IsContractWhitelistedResponse> {
let addr = deps.api.addr_validate(&address)?;
let is_whitelisted = WHITELISTED_CONTRACTS
.may_load(deps.storage, &addr)?
.unwrap_or(false);

Ok(IsContractWhitelistedResponse {
address,
is_whitelisted,
})
}

fn query_whitelisted_contracts(
deps: Deps,
start_after: Option<String>,
limit: Option<u32>,
) -> StdResult<WhitelistedContractsResponse> {
let limit = limit.unwrap_or(30).min(100) as usize;
let start = start_after
.map(|s| deps.api.addr_validate(&s))
.transpose()?;
let start_bound = start.as_ref().map(cw_storage_plus::Bound::exclusive);

let contracts: Vec<String> = WHITELISTED_CONTRACTS
.range(deps.storage, start_bound, None, cosmwasm_std::Order::Ascending)
.take(limit)
.map(|item| {
let (addr, _) = item?;
Ok(addr.to_string())
})
.collect::<StdResult<Vec<String>>>()?;

Ok(WhitelistedContractsResponse { contracts })
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(
deps: DepsMut,
_env: Env,
msg: Option<VendingUpdateParamsMsg>,
msg: MigrateMsg,
) -> Result<Response, ContractError> {
let prev_contract_info = cw2::get_contract_version(deps.storage)?;
let prev_contract_name: String = prev_contract_info.contract;
Expand All @@ -238,44 +353,37 @@ pub fn migrate(
return Err(StdError::generic_err("Cannot migrate to a previous contract version").into());
}

if let Some(msg) = msg {
let mut params = SUDO_PARAMS.load(deps.storage)?;

update_params(&mut params, msg.clone())?;

params.extension.max_token_limit = msg
.extension
.max_token_limit
.unwrap_or(params.extension.max_token_limit);
params.extension.max_per_address_limit = msg
.extension
.max_per_address_limit
.unwrap_or(params.extension.max_per_address_limit);

if let Some(airdrop_mint_price) = msg.extension.airdrop_mint_price {
ensure_eq!(
&airdrop_mint_price.denom,
&NATIVE_DENOM,
ContractError::BaseError(BaseContractError::InvalidDenom {})
);
params.extension.airdrop_mint_price = airdrop_mint_price;
}
// Set new contract version
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

params.extension.airdrop_mint_fee_bps = msg
.extension
.airdrop_mint_fee_bps
.unwrap_or(params.extension.airdrop_mint_fee_bps);

if let Some(shuffle_fee) = msg.extension.shuffle_fee {
ensure_eq!(
&shuffle_fee.denom,
&NATIVE_DENOM,
ContractError::BaseError(BaseContractError::InvalidDenom {})
);
params.extension.shuffle_fee = shuffle_fee;
}
let mut response = Response::new().add_attribute("action", "migrate");

// Handle whitelist updates during migration
if let Some(whitelist_update) = msg.whitelist_update {
response = apply_whitelist_update(deps, whitelist_update, response)?;
}

Ok(response)
}

fn apply_whitelist_update(
deps: DepsMut,
whitelist_update: WhitelistUpdate,
mut response: Response,
) -> Result<Response, ContractError> {
// Add contracts to whitelist
for address_str in whitelist_update.add {
let addr = deps.api.addr_validate(&address_str)?;
WHITELISTED_CONTRACTS.save(deps.storage, &addr, &true)?;
response = response.add_attribute("whitelist_added", address_str);
}

SUDO_PARAMS.save(deps.storage, &params)?;
// Remove contracts from whitelist
for address_str in whitelist_update.remove {
let addr = deps.api.addr_validate(&address_str)?;
WHITELISTED_CONTRACTS.remove(deps.storage, &addr);
response = response.add_attribute("whitelist_removed", address_str);
}
Ok(Response::new().add_attribute("action", "migrate"))

Ok(response)
}
Loading
Loading