fn try_accept(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    mint_amount: Option<Uint128>,
) -> Result<Response<ProvenanceMsg>, ContractError> {
    // Validate params.
    if !info.funds.is_empty() {
        return Err(contract_err("no funds should be sent during accept"));
    }

    // Read state
    let state = config_read(deps.storage).load()?;

    // Ensure proposal exists
    let key = info.sender.as_bytes();
    let proposal = join_proposals_read(deps.storage).load(key)?;

    match proposal.admin_vote {
        Some(VoteChoice::No) => {
            return Err(contract_err("admin voted no"));
        }
        Some(VoteChoice::Yes) => {} // Admin override, no need to check quorum
        None => {
            // Ensure quorum percentage has been reached for 'yes' votes.
            let total_weight: u128 = get_members(deps.as_ref())?
                .iter()
                .filter(|m| m.joined < proposal.created) // members from before the proposal was created.
                .map(|m| m.weight.u128())
                .sum();
            let pct = if total_weight > 0 {
                Decimal::from_ratio(proposal.yes, total_weight)
            } else {
                Decimal::zero()
            };

            deps.api.debug(&format!(
                "pct: {} | quorum {}",
                pct.to_string(),
                state.quorum_pct.to_string()
            ));

            if pct < state.quorum_pct {
                return Err(contract_err("no membership quorum"));
            }
        }
    }

    // Block membership if duplicate votes are detected in the join proposal.
    let mut votes = proposal.voters.clone();
    votes.sort();
    votes.dedup();
    if votes.len() < proposal.voters.len() {
        return Err(contract_err("membership blocked: duplicate vote(s) found"));
    }

    // Calculate member vote weight.
    let weight = calculate_weight(proposal.max_supply.u128());

    // Determine whether we're minting any reserve tokens
    let mut supply = Uint128::zero();
    if let Some(ma) = mint_amount {
        if ma > proposal.max_supply {
            return Err(contract_err("cannot mint more than max_supply"));
        }
        supply = ma;
    }

    // Persist member.
    members(deps.storage).save(
        key,
        &Member {
            id: info.sender.clone(),
            denom: proposal.denom.clone(),
            joined: Uint128::from(env.block.height),
            supply,
            max_supply: proposal.max_supply,
            weight: Uint128::new(weight),
            name: proposal.name.unwrap_or_else(|| info.sender.to_string()),
        },
    )?;

    // Finalize and activate the reserve marker.
    let mut res = Response::new()
        .add_message(finalize_marker(&proposal.denom)?)
        .add_message(activate_marker(&proposal.denom)?);

    // If non-zero, mint the reserve token supply and withdraw to the member account.
    if !supply.is_zero() {
        res = res
            .add_message(mint_marker_supply(supply.u128(), &proposal.denom)?)
            .add_message(withdraw_coins(
                &proposal.denom,
                supply.u128(),
                &proposal.denom,
                info.sender,
            )?);
    }

    // Add wasm event attributes
    Ok(res
        .add_attribute("action", "accept")
        .add_attribute("join_proposal_id", &proposal.id))
}
// Proposers must explicitly accept membership once voted into the consortium. Note: a proposer
// does not have to wait for the voting window to close before accepting - they only need a quroum
// of 'yes' votes.
Proposers must explicitly accept membership once voted into the consortium. Note: a proposer
does not have to wait for the voting window to close before accepting - they only need a quroum
of 'yes' votes.
Proposers must explicitly accept membership once voted into the consortium . Note : a proposer does not have to wait for the voting window to close before accepting - they only need a quroum of ' yes ' votes .
fn try_accept(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    mint_amount: Option<Uint128>,
) -> Result<Response<ProvenanceMsg>, ContractError> {
    // Validate params.
    if !info.funds.is_empty() {
        return Err(contract_err("no funds should be sent during accept"));
    }
    // Read state
    let state = config_read(deps.storage).load()?;
    // Ensure proposal exists
    let key = info.sender.as_bytes();
    let proposal = join_proposals_read(deps.storage).load(key)?;
    match proposal.admin_vote {
        Some(VoteChoice::No) => {
            return Err(contract_err("admin voted no"));
        }
        Some(VoteChoice::Yes) => {} // Admin override, no need to check quorum
        None => {
            // Ensure quorum percentage has been reached for 'yes' votes.
            let total_weight: u128 = get_members(deps.as_ref())?
                .iter()
                .filter(|m| m.joined < proposal.created) // members from before the proposal was created.
                .map(|m| m.weight.u128())
                .sum();
            let pct = if total_weight > 0 {
                Decimal::from_ratio(proposal.yes, total_weight)
            } else {
                Decimal::zero()
            };
            deps.api.debug(&format!(
                "pct: {} | quorum {}",
                pct.to_string(),
                state.quorum_pct.to_string()
            ));
            if pct < state.quorum_pct {
                return Err(contract_err("no membership quorum"));
            }
        }
    }
    // Block membership if duplicate votes are detected in the join proposal.
    let mut votes = proposal.voters.clone();
    votes.sort();
    votes.dedup();
    if votes.len() < proposal.voters.len() {
        return Err(contract_err("membership blocked: duplicate vote(s) found"));
    }
    // Calculate member vote weight.
    let weight = calculate_weight(proposal.max_supply.u128());
    // Determine whether we're minting any reserve tokens
    let mut supply = Uint128::zero();
    if let Some(ma) = mint_amount {
        if ma > proposal.max_supply {
            return Err(contract_err("cannot mint more than max_supply"));
        }
        supply = ma;
    }
    // Persist member.
    members(deps.storage).save(
        key,
        &Member {
            id: info.sender.clone(),
            denom: proposal.denom.clone(),
            joined: Uint128::from(env.block.height),
            supply,
            max_supply: proposal.max_supply,
            weight: Uint128::new(weight),
            name: proposal.name.unwrap_or_else(|| info.sender.to_string()),
        },
    )?;
    // Finalize and activate the reserve marker.
    let mut res = Response::new()
        .add_message(finalize_marker(&proposal.denom)?)
        .add_message(activate_marker(&proposal.denom)?);
    // If non-zero, mint the reserve token supply and withdraw to the member account.
    if !supply.is_zero() {
        res = res
            .add_message(mint_marker_supply(supply.u128(), &proposal.denom)?)
            .add_message(withdraw_coins(
                &proposal.denom,
                supply.u128(),
                &proposal.denom,
                info.sender,
            )?);
    }
    // Add wasm event attributes
    Ok(res
        .add_attribute("action", "accept")
        .add_attribute("join_proposal_id", &proposal.id))
}
fn try_accept ( deps : DepsMut , env : Env , info : MessageInfo , mint_amount : Option < Uint128 > , ) -> Result < Response < ProvenanceMsg > , ContractError > { // Validate params. if ! info . funds . is_empty ( ) { return Err ( contract_err ( " " ) ) ; } // Read state let state = config_read ( deps . storage ) . load ( ) ? ; // Ensure proposal exists let key = info . sender . as_bytes ( ) ; let proposal = join_proposals_read ( deps . storage ) . load ( key ) ? ; match proposal . admin_vote { Some ( VoteChoice :: No ) => { return Err ( contract_err ( " " ) ) ; } Some ( VoteChoice :: Yes ) => { } // Admin override, no need to check quorum None => { // Ensure quorum percentage has been reached for 'yes' votes. let total_weight : u128 = get_members ( deps . as_ref ( ) ) ? . iter ( ) . filter ( | m | m . joined < proposal . created ) // members from before the proposal was created. . map ( | m | m . weight . u128 ( ) ) . sum ( ) ; let pct = if total_weight > 0 { Decimal :: from_ratio ( proposal . yes , total_weight ) } else { Decimal :: zero ( ) } ; deps . api . debug ( & format ! ( " " pct to_string ( ) state quorum_pct to_string ( ) ) ) ; if pct < state . quorum_pct { return Err ( contract_err ( " " ) ) ; } } } // Block membership if duplicate votes are detected in the join proposal. let mut votes = proposal . voters . clone ( ) ; votes . sort ( ) ; votes . dedup ( ) ; if votes . len ( ) < proposal . voters . len ( ) { return Err ( contract_err ( " " ) ) ; } // Calculate member vote weight. let weight = calculate_weight ( proposal . max_supply . u128 ( ) ) ; // Determine whether we're minting any reserve tokens let mut supply = Uint128 :: zero ( ) ; if let Some ( ma ) = mint_amount { if ma > proposal . max_supply { return Err ( contract_err ( " " ) ) ; } supply = ma ; } // Persist member. members ( deps . storage ) . save ( key , & Member { id : info . sender . clone ( ) , denom : proposal . denom . clone ( ) , joined : Uint128 :: from ( env . block . height ) , supply , max_supply : proposal . max_supply , weight : Uint128 :: new ( weight ) , name : proposal . name . unwrap_or_else ( | | info . sender . to_string ( ) ) , } , ) ? ; // Finalize and activate the reserve marker. let mut res = Response :: new ( ) . add_message ( finalize_marker ( & proposal . denom ) ? ) . add_message ( activate_marker ( & proposal . denom ) ? ) ; // If non-zero, mint the reserve token supply and withdraw to the member account. if ! supply . is_zero ( ) { res = res . add_message ( mint_marker_supply ( supply . u128 ( ) , & proposal . denom ) ? ) . add_message ( withdraw_coins ( & proposal . denom , supply . u128 ( ) , & proposal . denom , info . sender , ) ? ) ; } // Add wasm event attributes Ok ( res . add_attribute ( " " , " " ) . add_attribute ( " " , & proposal . id ) ) }
Proposers must explicitly accept membership once voted into the consortium.
Proposers must explicitly accept membership once voted into the consortium .
deps
DepsMut
env
Env
info
MessageInfo
mint_amount
Option<Uint128>
deps
DepsMut
env
Env
info
MessageInfo
mint_amount
Option<Uint128>