Skip to content

Commit

Permalink
Merge pull request #1 from OmniFlix/seperate-pick
Browse files Browse the repository at this point in the history
Seperate pick
  • Loading branch information
Ninjatosba authored Apr 14, 2024
2 parents 7cb63da + 8b1555b commit 449da49
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 38 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ The contract is deployed on the Juno Network and integrates with the Nois protoc
- **Instantiation**: Sets up the contract with the Nois proxy address and participant count.
- **Execution**:
- **Request Randomness**: Initiates a randomness request to the Nois protocol, requiring a unique job ID and necessary funds.
- **Pick Winners (Nois Receive)**: Receives randomness from Nois, selects 100 winners, and handles different outcomes based on the job ID context ("test" or regular).
- **Nois Receive**: Receives randomness from Nois, then saves the randomness based on the job ID. If the job id constains the word "test", the contract will save the randomness as a test value. Otherwise, it will save the randomness as the final value. Test value can be reseted if another request is made. But the final value can only be set once.
- **Pick Test Winners**: Selects test winners based on the test randomness value.
- **Pick Winners**: Selects winners based on the final randomness value.
- **Queries**: Provides smart queries for accessing participant count, list of winners, admin details, etc.

# **Setup and Configuration**
Expand Down
2 changes: 1 addition & 1 deletion artifacts/checksums.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12bf66626d6c7972664a19b0c6394cf65de38a831d84c2340a096656316a5859 raffle_drop.wasm
a9a6edecd2fc2c37a161d5a28a25c80cf2b577007d4350f92354b2920df476cf raffle_drop.wasm
2 changes: 1 addition & 1 deletion artifacts/checksums_intermediate.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
45da052c35dc16f3d2080236dbf00daac2d7c2e8850c897871c3b7d614b52152 /target/wasm32-unknown-unknown/release/raffle_drop.wasm
1fd30a662f8a48b58a6a9e6167085550b9fdfedbc06e338f81ec801f7f55c1d4 /target/wasm32-unknown-unknown/release/raffle_drop.wasm
Binary file modified artifacts/raffle_drop.wasm
Binary file not shown.
125 changes: 92 additions & 33 deletions src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::state::{ADMIN, NOIS_PROXY, PARTICIPANT_COUNT, TEST_WINNERS, WINNERS};
use crate::state::{
ADMIN, FINAL_RANDOMNESS, NOIS_PROXY, PARTICIPANT_COUNT, TEST_RANDOMNESS, TEST_WINNERS, WINNERS,
};
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
Expand Down Expand Up @@ -46,34 +48,45 @@ pub fn execute(
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::RequestRandomness { job_id } => {
execute_request_randomness(deps, env, info, job_id)
}
ExecuteMsg::NoisReceive { callback } => execute_pick_winners(deps, env, info, callback),
ExecuteMsg::RequestRandomness {
job_id,
delay_in_mins,
} => execute_request_randomness(deps, env, info, job_id, delay_in_mins),
ExecuteMsg::NoisReceive { callback } => execute_set_randomness(deps, env, info, callback),
ExecuteMsg::PickTestWinners {} => pick_test_winners(deps, env, info),
ExecuteMsg::PickWinners {} => pick_winners(deps, env, info),
}
}

pub fn execute_request_randomness(
deps: DepsMut,
_env: Env,
env: Env,
info: MessageInfo,
job_id: String,
delay_in_mins: u64,
) -> Result<Response, ContractError> {
let nois_proxy = NOIS_PROXY.load(deps.storage)?;

if info.sender != ADMIN.load(deps.storage)? {
return Err(ContractError::Unauthorized {});
}

let res = Response::new().add_message(WasmMsg::Execute {
contract_addr: nois_proxy.into(),
msg: to_json_binary(&ProxyExecuteMsg::GetNextRandomness { job_id })?,
funds: info.funds.clone(),
});
let now = env.block.time;
let res = Response::new()
.add_message(WasmMsg::Execute {
contract_addr: nois_proxy.into(),
msg: to_json_binary(&ProxyExecuteMsg::GetRandomnessAfter {
after: now.plus_minutes(delay_in_mins),
job_id: job_id.clone(),
})?,
funds: info.funds.clone(),
})
.add_attribute("action", "request_randomness")
.add_attribute("job_id", job_id)
.add_attribute("after", now.plus_minutes(delay_in_mins).to_string());
Ok(res)
}

pub fn execute_pick_winners(
pub fn execute_set_randomness(
deps: DepsMut,
_env: Env,
info: MessageInfo,
Expand All @@ -86,34 +99,80 @@ pub fn execute_pick_winners(
job_id, randomness, ..
} = callback;

let randomness: [u8; 32] = randomness
.to_array()
.map_err(|_| ContractError::InvalidRandomness {})?;
if job_id.contains("test") {
TEST_RANDOMNESS.save(deps.storage, &randomness)?;
} else {
if FINAL_RANDOMNESS.may_load(deps.storage)?.is_some() {
return Err(ContractError::FinalRandomnessAlreadySet {});
}
FINAL_RANDOMNESS.save(deps.storage, &randomness)?;
}

let res = Response::new();
Ok(res)
}

pub fn pick_test_winners(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
) -> Result<Response, ContractError> {
let participant_count = PARTICIPANT_COUNT.load(deps.storage)?;
let participant_arr = (1..=participant_count).collect::<Vec<u32>>();
let participants = (1..=participant_count).collect::<Vec<u32>>();
let test_randomness = TEST_RANDOMNESS.load(deps.storage)?;
let test_randomness_vec: [u8; 32] = test_randomness[..].try_into().unwrap();

let winners = pick(randomness, 100, participant_arr);
let winners_string = winners
if test_randomness.is_empty() {
return Err(ContractError::TestRandomnessNotSet {});
}

let winners = pick(test_randomness_vec, 100, participants);
let winners_str = winners
.iter()
.map(|&x| x.to_string())
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join(", ");
.join(",");
TEST_WINNERS.save(deps.storage, &winners)?;

match job_id.as_str() {
"test" => {
TEST_WINNERS.save(deps.storage, &winners)?;
}
_ => {
let old_winners = WINNERS.may_load(deps.storage)?;
if old_winners.is_some() {
return Err(ContractError::WinnersAlreadyPicked {});
}
WINNERS.save(deps.storage, &winners)?;
}
let res = Response::new()
.add_attribute("action", "pick_test_winners")
.add_attribute("test winners", winners_str);
Ok(res)
}

pub fn pick_winners(
deps: DepsMut,
_env: Env,
info: MessageInfo,
) -> Result<Response, ContractError> {
if info.sender != ADMIN.load(deps.storage)? {
return Err(ContractError::Unauthorized {});
}
if WINNERS.may_load(deps.storage)?.is_some() {
return Err(ContractError::WinnersAlreadyPicked {});
}

let res = Response::new().add_attribute("winners", winners_string);
let participant_count = PARTICIPANT_COUNT.load(deps.storage)?;
let participants = (1..=participant_count).collect::<Vec<u32>>();

let final_randomness = FINAL_RANDOMNESS
.load(deps.storage)
.map_err(|_| ContractError::FinalRandomnessNotSet {})?;
let final_randomness_vec: [u8; 32] = final_randomness[..].try_into().unwrap();

let winners = pick(final_randomness_vec, 100, participants);
let winners_str = winners
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join(",");

WINNERS.save(deps.storage, &winners)?;

let res = Response::new()
.add_attribute("action", "pick_winners")
.add_attribute("winners", winners_str);

Ok(res)
}

Expand Down
9 changes: 9 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,13 @@ pub enum ContractError {

#[error("Winners already picked")]
WinnersAlreadyPicked {},

#[error("Test randomness not set")]
TestRandomnessNotSet {},

#[error("Final randomness not set")]
FinalRandomnessNotSet {},

#[error("Final randomness already set")]
FinalRandomnessAlreadySet {},
}
4 changes: 3 additions & 1 deletion src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ pub struct InstantiateMsg {

#[cw_serde]
pub enum ExecuteMsg {
RequestRandomness { job_id: String },
RequestRandomness { job_id: String, delay_in_mins: u64 },
NoisReceive { callback: NoisCallback },
PickTestWinners {},
PickWinners {},
}

#[cw_serde]
Expand Down
4 changes: 3 additions & 1 deletion src/state.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use cosmwasm_std::Addr;
use cosmwasm_std::{Addr, HexBinary};
use cw_storage_plus::Item;

pub const PARTICIPANT_COUNT: Item<u32> = Item::new("participant_count");
pub const NOIS_PROXY: Item<Addr> = Item::new("nois_proxy");
pub const ADMIN: Item<Addr> = Item::new("admin");
pub const WINNERS: Item<Vec<u32>> = Item::new("winners");
pub const TEST_WINNERS: Item<Vec<u32>> = Item::new("test_winners");
pub const TEST_RANDOMNESS: Item<HexBinary> = Item::new("test_randomness");
pub const FINAL_RANDOMNESS: Item<HexBinary> = Item::new("final_randomness");

0 comments on commit 449da49

Please sign in to comment.