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

Airdrop | minor tweaks #138

Merged
merged 6 commits into from
Nov 23, 2021
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
35 changes: 23 additions & 12 deletions contracts/airdrop/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use shade_protocol::{
QueryMsg, Config
}
};
use crate::{state::{config_w, reward_w, claim_status_w},
handle::{try_update_config, try_add_tasks, try_complete_task, try_claim},
use crate::{state::{config_w, reward_w, claim_status_w, user_total_claimed_w, total_claimed_w},
handle::{try_update_config, try_add_tasks, try_complete_task, try_claim, try_decay},
query };
use shade_protocol::airdrop::RequiredTask;

Expand Down Expand Up @@ -34,12 +34,26 @@ pub fn init<S: Storage, A: Api, Q: Querier>(
return Err(StdError::GenericErr { msg: "tasks above 100%".to_string(), backtrace: None })
}

// Store the delegators list
let mut airdrop_total = Uint128::zero();
for reward in msg.rewards {
let key = reward.address.to_string();

reward_w(&mut deps.storage).save(key.as_bytes(), &reward)?;
airdrop_total += reward.amount;
user_total_claimed_w(&mut deps.storage).save(key.as_bytes(), &Uint128::zero())?;
// Save the initial claim
claim_status_w(&mut deps.storage, 0).save(key.as_bytes(), &false)?;
}

let config = Config{
admin: match msg.admin {
None => { env.message.sender.clone() }
Some(admin) => { admin }
},
dump_address: msg.dump_address,
airdrop_snip20: msg.airdrop_token.clone(),
airdrop_total,
task_claim,
start_date: match msg.start_time {
None => env.block.time,
Expand All @@ -50,14 +64,8 @@ pub fn init<S: Storage, A: Api, Q: Querier>(

config_w(&mut deps.storage).save(&config)?;

// Store the delegators list
for reward in msg.rewards {
let key = reward.address.to_string();

reward_w(&mut deps.storage).save(key.as_bytes(), &reward)?;
// Save the initial claim
claim_status_w(&mut deps.storage, 0).save(key.as_bytes(), &false)?;
}
// Initialize claim amount
total_claimed_w(&mut deps.storage).save(&Uint128::zero())?;

Ok(InitResponse {
messages: vec![],
Expand All @@ -72,13 +80,16 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
) -> StdResult<HandleResponse> {
match msg {
HandleMsg::UpdateConfig {
admin, start_date, end_date
} => try_update_config(deps, env, admin, start_date, end_date),
admin, dump_address,
start_date, end_date
} => try_update_config(deps, env, admin, dump_address,
start_date, end_date),
HandleMsg::AddTasks { tasks
} => try_add_tasks(deps, &env, tasks),
HandleMsg::CompleteTask { address
} => try_complete_task(deps, &env, address),
HandleMsg::Claim { } => try_claim(deps, &env),
HandleMsg::Decay { } => try_decay(deps, &env),
}
}

Expand Down
89 changes: 69 additions & 20 deletions contracts/airdrop/src/handle.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
use cosmwasm_std::{to_binary, Api, Env, Extern, HandleResponse, Querier, StdError, StdResult, Storage, HumanAddr, Uint128};
use crate::state::{config_r, config_w, reward_r, claim_status_w, claim_status_r};
use crate::state::{config_r, config_w, reward_r, claim_status_w, claim_status_r, user_total_claimed_w, total_claimed_w, total_claimed_r};
use shade_protocol::airdrop::{HandleAnswer, RequiredTask};
use shade_protocol::generic_response::ResponseStatus;
use secret_toolkit::snip20::mint_msg;
use secret_toolkit::snip20::send_msg;

pub fn try_update_config<S: Storage, A: Api, Q: Querier>(
deps: &mut Extern<S, A, Q>,
env: Env,
admin: Option<HumanAddr>,
dump_address: Option<HumanAddr>,
start_date: Option<u64>,
end_date: Option<u64>,
) -> StdResult<HandleResponse> {
let config = config_r(&deps.storage).load()?;
// Check if admin
if env.message.sender != config.admin {
return Err(StdError::Unauthorized { backtrace: None });
return Err(StdError::unauthorized());
}

// Save new info
Expand All @@ -23,6 +24,9 @@ pub fn try_update_config<S: Storage, A: Api, Q: Querier>(
if let Some(admin) = admin {
state.admin = admin;
}
if let Some(dump_address)= dump_address {
state.dump_address = Some(dump_address);
}
if let Some(start_date) = start_date {
state.start_date = start_date;
}
Expand Down Expand Up @@ -50,7 +54,7 @@ pub fn try_add_tasks<S: Storage, A: Api, Q: Querier>(
let config = config_r(&deps.storage).load()?;
// Check if admin
if env.message.sender != config.admin {
return Err(StdError::Unauthorized { backtrace: None });
return Err(StdError::unauthorized());
}

config_w(&mut deps.storage).update(|mut config| {
Expand All @@ -64,7 +68,7 @@ pub fn try_add_tasks<S: Storage, A: Api, Q: Querier>(
}

if count > Uint128(100) {
return Err(StdError::GenericErr { msg: "tasks above 100%".to_string(), backtrace: None })
return Err(StdError::generic_err("tasks above 100%"))
}

Ok(config)
Expand Down Expand Up @@ -95,7 +99,7 @@ pub fn try_complete_task<S: Storage, A: Api, Q: Querier>(
Ok(false)
}
else {
Err(StdError::Unauthorized { backtrace: None })
Err(StdError::unauthorized())
}
})?;

Expand All @@ -109,7 +113,7 @@ pub fn try_complete_task<S: Storage, A: Api, Q: Querier>(
}

// if not found
Err(StdError::NotFound { kind: "task".to_string(), backtrace: None })
Err(StdError::not_found("task"))
}

pub fn try_claim<S: Storage, A: Api, Q: Querier>(
Expand All @@ -120,45 +124,90 @@ pub fn try_claim<S: Storage, A: Api, Q: Querier>(

// Check if airdrop started
if env.block.time < config.start_date {
return Err(StdError::Unauthorized { backtrace: None })
return Err(StdError::unauthorized())
}
if let Some(end_date) = config.end_date {
if env.block.time > end_date {
return Err(StdError::Unauthorized { backtrace: None })
return Err(StdError::unauthorized())
}
}

let user = env.message.sender.clone();
let user_key = user.to_string();

let eligible_amount = reward_r(&deps.storage).load(
user.to_string().as_bytes())?.amount;
let eligible_amount = reward_r(&deps.storage).load(user_key.as_bytes())?.amount;

let mut claimed_percentage = Uint128::zero();
let mut total = Uint128::zero();
for (i, task) in config.task_claim.iter().enumerate() {
// Check if completed
let state = claim_status_r(&deps.storage, i).may_load(user_key.as_bytes())?;
let state = claim_status_r(&deps.storage, i).may_load(
user_key.as_bytes())?;
match state {
None => {}
Some(claimed) => {
claimed_percentage += task.percent;
if !claimed {
claim_status_w(&mut deps.storage, i).save(user_key.as_bytes(), &true)?;
total += task.percent.multiply_ratio(eligible_amount, Uint128(100));
claim_status_w(&mut deps.storage, i).save(
user_key.as_bytes(), &true)?;
total += task.percent.multiply_ratio(
eligible_amount, Uint128(100));
}
}
};
}

// Redeem
let messages = vec![mint_msg(user, total,
None, 1,
config.airdrop_snip20.code_hash,
config.airdrop_snip20.address)?];
// Update redeem info
let mut redeem_amount = total;
user_total_claimed_w(&mut deps.storage).update(
user_key.as_bytes(), |total_claimed| {
// Fix division issues
if claimed_percentage == Uint128(100) {
redeem_amount = (eligible_amount - total_claimed.unwrap())?;
}
Ok(total_claimed.unwrap() + redeem_amount)
})?;

total_claimed_w(&mut deps.storage).update(|total_claimed| {
Ok(total_claimed + redeem_amount)
})?;

Ok(HandleResponse {
messages,
messages: vec![send_msg(user, redeem_amount,
None, None, 0,
config.airdrop_snip20.code_hash,
config.airdrop_snip20.address)?],
log: vec![],
data: Some( to_binary( &HandleAnswer::Claim {
status: ResponseStatus::Success } )? )
})
}

pub fn try_decay<S: Storage, A: Api, Q: Querier>(
deps: &mut Extern<S, A, Q>,
env: &Env,
) -> StdResult<HandleResponse> {
let config = config_r(&deps.storage).load()?;

// Check if airdrop ended
if let Some(end_date) = config.end_date {
if let Some(dump_address) = config.dump_address {
if env.block.time > end_date {
let send_total = (config.airdrop_total - total_claimed_r(&deps.storage).load()?)?;
let messages = vec![send_msg(
dump_address, send_total, None, None,
1, config.airdrop_snip20.code_hash,
config.airdrop_snip20.address)?];
Comment on lines +197 to +200
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is just hard-coded like that can we just initialize it in the HandleResponse?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup we can

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 76ff676


return Ok(HandleResponse {
messages,
log: vec![],
data: Some( to_binary( &HandleAnswer::Decay {
status: ResponseStatus::Success } )? )
})
}
}
}

Err(StdError::unauthorized())
FloppyDisck marked this conversation as resolved.
Show resolved Hide resolved
}
12 changes: 7 additions & 5 deletions contracts/airdrop/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use cosmwasm_std::{Api, Extern, Querier, StdResult, Storage, HumanAddr, Uint128};
use shade_protocol::airdrop::{QueryAnswer};
use crate::{state::{config_r, reward_r}};
use crate::state::claim_status_r;
use crate::state::{claim_status_r, total_claimed_r, user_total_claimed_r};

pub fn config<S: Storage, A: Api, Q: Querier>
(deps: &Extern<S, A, Q>) -> StdResult<QueryAnswer> {
Ok(QueryAnswer::Config { config: config_r(&deps.storage).load()?
Ok(QueryAnswer::Config {
config: config_r(&deps.storage).load()?,
total_claimed: total_claimed_r(&deps.storage).load()?,
})
}

Expand All @@ -23,7 +25,7 @@ pub fn airdrop_amount<S: Storage, A: Api, Q: Querier>
let eligible_amount = reward_r(&deps.storage).load(key.as_bytes())?.amount;

let mut finished_tasks = vec![];
let mut claimed = Uint128::zero();
let claimed = user_total_claimed_r(&deps.storage).load(key.as_bytes())?;
let mut unclaimed = Uint128::zero();

let config = config_r(&deps.storage).load()?;
Expand All @@ -35,8 +37,8 @@ pub fn airdrop_amount<S: Storage, A: Api, Q: Querier>
let calc = task.percent.multiply_ratio(eligible_amount.clone(),
Uint128(100));
match task_claimed {
true => claimed += calc,
false => unclaimed += calc
false => unclaimed += calc,
_ => {}
};
}
}
Expand Down
22 changes: 21 additions & 1 deletion contracts/airdrop/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use cosmwasm_std::Storage;
use cosmwasm_std::{Storage, Uint128};
use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, bucket, Bucket, bucket_read, ReadonlyBucket};
use shade_protocol::airdrop::{Config, Reward};

pub static CONFIG_KEY: &[u8] = b"config";
pub static REWARDS_KEY: &[u8] = b"rewards";
pub static TOTAL_CLAIMED_KEY: &[u8] = b"total_claimed";
pub static USER_TOTAL_CLAIMED_KEY: &[u8] = b"user_total_claimed";

pub fn config_w<S: Storage>(storage: &mut S) -> Singleton<S, Config> {
singleton(storage, CONFIG_KEY)
Expand All @@ -28,4 +30,22 @@ pub fn claim_status_r<S: Storage>(storage: & S, index: usize) -> ReadonlyBucket<

pub fn claim_status_w<S: Storage>(storage: &mut S, index: usize) -> Bucket<S, bool> {
bucket(&[index as u8], storage)
}

// Total claimed
pub fn total_claimed_r<S: Storage>(storage: &S) -> ReadonlySingleton<S, Uint128> {
singleton_read(storage, TOTAL_CLAIMED_KEY)
}

pub fn total_claimed_w<S: Storage>(storage: &mut S) -> Singleton<S, Uint128> {
singleton(storage, TOTAL_CLAIMED_KEY)
}

// Total user claimed
pub fn user_total_claimed_r<S: Storage>(storage: & S) -> ReadonlyBucket<S, Uint128> {
bucket_read(USER_TOTAL_CLAIMED_KEY, storage)
}

pub fn user_total_claimed_w<S: Storage>(storage: &mut S) -> Bucket<S, Uint128> {
bucket(USER_TOTAL_CLAIMED_KEY, storage)
}
1 change: 1 addition & 0 deletions packages/network_integration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ default = []

[dependencies]
colored = "2.0.0"
chrono = "0.4.19"
shade-protocol = { version = "0.1.0", path = "../shade_protocol" }
secretcli = { version = "0.1.0", path = "../secretcli" }
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use shade_protocol::{snip20::{InitialBalance}, snip20,
initializer, initializer::Snip20ContractInfo};
use crate::{utils::{print_header, generate_label, print_contract, print_warning,
STORE_GAS, GAS, VIEW_KEY, ACCOUNT_KEY, INITIALIZER_FILE},
contract_helpers::governance::add_contract,
contract_helpers::minter::get_balance};
use secretcli::{cli_types::NetContract,
secretcli::{test_contract_handle, test_inst_init, list_contracts_by_code}};
Expand Down
3 changes: 0 additions & 3 deletions packages/network_integration/src/main.rs

This file was deleted.

Loading