Skip to content

Commit

Permalink
initial format
Browse files Browse the repository at this point in the history
  • Loading branch information
Buckram123 committed Oct 11, 2023
1 parent e8f2a52 commit 5103360
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 282 deletions.
28 changes: 13 additions & 15 deletions framework/scripts/src/bin/full_deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ use std::{
};

use abstract_core::objects::gov_type::GovernanceDetails;
use abstract_interface::{Abstract, VersionControl};
use abstract_interface::Abstract;

use abstract_interface_scripts::{assert_wallet_balance, DeploymentStatus, SUPPORTED_CHAINS};
use clap::Parser;
use cw_orch::daemon::{ChainKind, NetworkInfo};
use cw_orch::{
deploy::Deploy,
prelude::{
Expand All @@ -29,16 +28,16 @@ fn full_deploy(mut networks: Vec<ChainInfo>) -> anyhow::Result<()> {
if networks.is_empty() {
networks = SUPPORTED_CHAINS.to_vec();
}
//
// let deployment_status = read_deployment()?;
// if deployment_status.success {
// log::info!("Do you want to re-deploy to {:?}?", networks);
// let mut input = String::new();
// std::io::stdin().read_line(&mut input)?;
// if input.to_lowercase().contains('n') {
// return Ok(());
// }
// }

let deployment_status = read_deployment()?;
if deployment_status.success {
log::info!("Do you want to re-deploy to {:?}?", networks);
let mut input = String::new();
std::io::stdin().read_line(&mut input)?;
if input.to_lowercase().contains('n') {
return Ok(());
}
}
// let deployment_status = deployment_status.clone();

// If some chains need to be deployed, deploy them
Expand Down Expand Up @@ -141,10 +140,9 @@ fn main() {

use dotenv::dotenv;

// let args = Arguments::parse();
let args = Arguments::parse();

// let networks = args.network_ids.iter().map(|n| parse_network(n)).collect();
let networks = vec![NEUTRON_1];
let networks = args.network_ids.iter().map(|n| parse_network(n)).collect();

if let Err(ref err) = full_deploy(networks) {
log::error!("{}", err);
Expand Down
2 changes: 1 addition & 1 deletion modules/contracts/apps/betting/examples/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use cw_orch::daemon::DaemonBuilder;
use cw_orch::daemon::networks::parse_network;
use cw_orch::tokio::runtime::Runtime;

use clap::Parser;
use betting_app::contract::interface::BetApp;
use betting_app::BET_APP_ID;
use clap::Parser;
use semver::Version;

const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
Expand Down
2 changes: 1 addition & 1 deletion modules/contracts/apps/betting/examples/schema.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
use betting_app::contract::BetApp;
use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
use std::env::current_dir;
use std::fs::create_dir_all;

Expand Down
11 changes: 7 additions & 4 deletions modules/contracts/apps/betting/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::state::RoundId;
use abstract_app::AppError;
use abstract_core::AbstractError;
use abstract_core::objects::AccountId;
use abstract_core::objects::validation::ValidationError;
use abstract_core::objects::AccountId;
use abstract_core::AbstractError;
use abstract_sdk::AbstractSdkError;
use cosmwasm_std::{Addr, CheckedFromRatioError, OverflowError, StdError};
use cw_asset::{AssetError, AssetInfo, AssetInfoBase};
use cw_controllers::AdminError;
use thiserror::Error;
use crate::state::RoundId;

#[derive(Error, Debug, PartialEq)]
pub enum BetError {
Expand Down Expand Up @@ -84,7 +84,10 @@ pub enum BetError {
account_id: AccountId,
},
#[error("Invalid asset. Expected: {expected}, Actual: {actual}")]
InvalidAsset { expected: AssetInfo, actual: AssetInfoBase<Addr> },
InvalidAsset {
expected: AssetInfo,
actual: AssetInfoBase<Addr>,
},

#[error("Round {0} already closed")]
RoundAlreadyClosed(RoundId),
Expand Down
148 changes: 87 additions & 61 deletions modules/contracts/apps/betting/src/handlers/execute.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
use std::str::FromStr;
use abstract_core::objects::{AccountId, AnsAsset, AssetEntry};
use abstract_sdk::{
*,
core::objects::fee::Fee, features::AbstractResponse,
use abstract_sdk::{core::objects::fee::Fee, features::AbstractResponse, *};
use cosmwasm_std::{
coins, Addr, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, Order, Response, StdError,
StdResult, Storage, Uint128,
};
use cosmwasm_std::{Addr, coins, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Storage, Uint128};
use cw_storage_plus::Item;
use std::str::FromStr;

use crate::contract::{BetApp, BetResult};
use crate::error::BetError;
use crate::handlers::query;
use crate::msg::BetExecuteMsg;
use crate::state::*;
use crate::state::CONFIG;
use crate::state::*;
use abstract_sdk::features::AbstractNameService;
use crate::handlers::query;


pub fn execute_handler(
deps: DepsMut,
Expand All @@ -39,7 +38,11 @@ pub fn execute_handler(
// Check asset
create_round(deps, info, app, round_info)
}
BetExecuteMsg::UpdateAccounts { to_add, to_remove, round_id } => {
BetExecuteMsg::UpdateAccounts {
to_add,
to_remove,
round_id,
} => {
// Only admin can register specific accounts
app.admin.assert_admin(deps.as_ref(), &info.sender)?;

Expand All @@ -54,23 +57,14 @@ pub fn execute_handler(

update_config(deps, app, rake)
}
BetExecuteMsg::PlaceBet {
bet,
round_id
} => {
place_bet(deps, info, app, round_id, bet)
}
BetExecuteMsg::CloseRound {
round_id, winner
} => {
BetExecuteMsg::PlaceBet { bet, round_id } => place_bet(deps, info, app, round_id, bet),
BetExecuteMsg::CloseRound { round_id, winner } => {
app.admin.assert_admin(deps.as_ref(), &info.sender)?;
let round = Round::new(round_id);

close_round(deps, &app, winner, round)?
}
BetExecuteMsg::DistributeWinnings {
round_id
} => distribute_winnings(deps, app, round_id),
BetExecuteMsg::DistributeWinnings { round_id } => distribute_winnings(deps, app, round_id),
BetExecuteMsg::Register { round_id } => {
let round = Round::new(round_id);
round.assert_not_closed(deps.storage)?;
Expand All @@ -80,7 +74,7 @@ pub fn execute_handler(
}

fn update_config(deps: DepsMut, app: BetApp, rake: Option<Decimal>) -> BetResult {
// TODO: use config constant, not sure why this is not working.
// TODO: use config constant, not sure why this is not working.
let mut config: Config = Item::new("config").load(deps.storage)?;
let mut attrs = vec![];

Expand All @@ -89,26 +83,26 @@ fn update_config(deps: DepsMut, app: BetApp, rake: Option<Decimal>) -> BetResult
attrs.push(("rake", rake.to_string()));
};

Ok(app.custom_tag_response(
Response::default(),
"update_config",
attrs,
))
Ok(app.custom_tag_response(Response::default(), "update_config", attrs))
}

fn register_for_round(deps: DepsMut, info: MessageInfo, app: BetApp, round: Round) -> BetResult {
let account_id = app.account_registry(deps.as_ref()).account_id(&info.sender)?;
let account_id = app
.account_registry(deps.as_ref())
.account_id(&info.sender)?;
// default odds
let odds = Decimal::one();
let to_add = vec![AccountOdds {
account_id,
odds,
}];
let to_add = vec![AccountOdds { account_id, odds }];
let to_remove = vec![];
update_accounts(deps, info, app, round, to_add, to_remove)
}

fn close_round(deps: DepsMut, app: &BetApp, winner: Option<AccountId>, round: Round) -> Result<Result<Response, BetError>, BetError> {
fn close_round(
deps: DepsMut,
app: &BetApp,
winner: Option<AccountId>,
round: Round,
) -> Result<Result<Response, BetError>, BetError> {
let current_status = round.status(deps.storage)?;

Ok(match current_status {
Expand All @@ -119,12 +113,19 @@ fn close_round(deps: DepsMut, app: &BetApp, winner: Option<AccountId>, round: Ro
return Err(BetError::AccountNotFound(winner));
}
}
round.set_status(deps.storage, RoundStatus::Closed { winning_team: winner })?;
round.set_status(
deps.storage,
RoundStatus::Closed {
winning_team: winner,
},
)?;

Ok(app.custom_tag_response(
Response::default(),
"update_round_status",
vec![("round_id", round.id().to_string()) /*, ("status", new_status.to_string()) */],
vec![
("round_id", round.id().to_string()), /*, ("status", new_status.to_string()) */
],
))
}
_ => Err(BetError::RoundAlreadyClosed(round.id())),
Expand All @@ -147,7 +148,8 @@ fn distribute_winnings(deps: DepsMut, app: BetApp, round_id: RoundId) -> BetResu
let bank = app.bank(deps.as_ref());
let round_info = round.info(deps.storage)?.bet_asset;

let distribution_actions: Result<Vec<AccountAction>, AbstractSdkError> = bets.into_iter()
let distribution_actions: Result<Vec<AccountAction>, AbstractSdkError> = bets
.into_iter()
.map(|(better_addr, bet_amount)| {
let transfer_asset = AnsAsset::new(round_info.clone(), bet_amount);
bank.transfer(vec![transfer_asset], &better_addr)
Expand All @@ -156,15 +158,18 @@ fn distribute_winnings(deps: DepsMut, app: BetApp, round_id: RoundId) -> BetResu

distribution_actions.map_err(Into::into)
}
RoundStatus::Closed { winning_team: Some(winning_team) } => {
RoundStatus::Closed {
winning_team: Some(winning_team),
} => {
// Distribute the winnings to the winning betters
let winning_odds = ODDS.load(deps.storage, (round_id, winning_team.clone()))?;
let winning_bets = BETS.load(deps.storage, (round_id, winning_team.clone()))?;

let bank = app.bank(deps.as_ref());
let round_info = round.info(deps.storage)?.bet_asset;

let distribution_msgs1 = winning_bets.into_iter()
let distribution_msgs1 = winning_bets
.into_iter()
.map(|(better_addr, bet_amount)| {
let winnings = bet_amount * winning_odds;
let transfer_asset = AnsAsset::new(round_info.clone(), winnings);
Expand All @@ -174,36 +179,39 @@ fn distribute_winnings(deps: DepsMut, app: BetApp, round_id: RoundId) -> BetResu

distribution_msgs1.map_err(Into::into)
}
_ => Err(BetError::RoundNotClosed(round_id))
_ => Err(BetError::RoundNotClosed(round_id)),
}?;

let executor = app.executor(deps.as_ref());


let distribution_msg = executor.execute(distribution_msgs)?;

Ok(app.tag_response(Response::default().add_message(distribution_msg), "distribute_draw"))

Ok(app.tag_response(
Response::default().add_message(distribution_msg),
"distribute_draw",
))
}


fn update_accounts(deps: DepsMut, info: MessageInfo, app: BetApp, round: Round, to_add: Vec<AccountOdds>, to_remove: Vec<AccountId>) -> BetResult {
fn update_accounts(
deps: DepsMut,
info: MessageInfo,
app: BetApp,
round: Round,
to_add: Vec<AccountOdds>,
to_remove: Vec<AccountId>,
) -> BetResult {
let account_registry = app.account_registry(deps.as_ref());
for AccountOdds {
account_id,
..
} in to_add.iter() {
for AccountOdds { account_id, .. } in to_add.iter() {
// ensure account exists
account_registry.account_base(&account_id).map_err(|_| BetError::AccountNotFound(account_id.clone()))?;
account_registry
.account_base(&account_id)
.map_err(|_| BetError::AccountNotFound(account_id.clone()))?;
}

// register account
round.update_accounts(deps, to_add, to_remove)?;

Ok(app.tag_response(
Response::default(),
"update_accounts",
))
Ok(app.tag_response(Response::default(), "update_accounts"))
}

pub fn create_round(
Expand All @@ -226,10 +234,20 @@ pub fn create_round(
state.next_round_id += 1;
Ok(state)
})?;
Ok(app.custom_tag_response(Response::default(), "create_round", vec![("round_id", state.next_round_id.to_string())]))
Ok(app.custom_tag_response(
Response::default(),
"create_round",
vec![("round_id", state.next_round_id.to_string())],
))
}

fn place_bet(deps: DepsMut, info: MessageInfo, app: BetApp, round_id: RoundId, bet: Bet) -> BetResult {
fn place_bet(
deps: DepsMut,
info: MessageInfo,
app: BetApp,
round_id: RoundId,
bet: Bet,
) -> BetResult {
let mut messages: Vec<CosmosMsg> = vec![];

let bank = app.bank(deps.as_ref());
Expand All @@ -244,17 +262,19 @@ fn place_bet(deps: DepsMut, info: MessageInfo, app: BetApp, round_id: RoundId, b
let round = Round::new(round_id);

// Ensure the account placing the bet exists
bet.validate(deps.as_ref(), &round)?;
bet.validate(deps.as_ref(), &round)?;

// deposit the sent assets
let deposit_msg = bank.deposit(vec![bet.asset.clone()])?;
messages.extend(deposit_msg.into_iter());
// deposit the sent assets
let deposit_msg = bank.deposit(vec![bet.asset.clone()])?;
messages.extend(deposit_msg.into_iter());

// Record the bet
let bet_account = bet.account_id;

let key = (round.id(), bet_account.clone());
let mut bets = BETS.may_load(deps.storage, key.clone())?.unwrap_or_default();
let mut bets = BETS
.may_load(deps.storage, key.clone())?
.unwrap_or_default();
// Find and update the existing bet if it exists
if let Some(index) = bets.iter().position(|(addr, _)| addr == &info.sender) {
let (_, amount) = &mut bets[index];
Expand Down Expand Up @@ -282,7 +302,13 @@ fn place_bet(deps: DepsMut, info: MessageInfo, app: BetApp, round_id: RoundId, b
/// Calculates the new odds for the given round/account pair
/// # Returns
/// the new odds
fn adjust_odds_for_team(storage: &mut dyn Storage, round_id: RoundId, team_id: AccountId, bet_totals: Uint128, rake: Decimal) -> StdResult<()> {
fn adjust_odds_for_team(
storage: &mut dyn Storage,
round_id: RoundId,
team_id: AccountId,
bet_totals: Uint128,
rake: Decimal,
) -> StdResult<()> {
let team_bet_total = query::get_total_bets_for_team(storage, round_id, team_id.clone())?;
// No action, odds have not changed
if team_bet_total.is_zero() {
Expand Down
4 changes: 2 additions & 2 deletions modules/contracts/apps/betting/src/handlers/instantiate.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use abstract_core::objects::fee::Fee;
use abstract_sdk::AbstractResponse;
use abstract_sdk::features::AbstractNameService;
use abstract_sdk::AbstractResponse;
use cosmwasm_std::{Decimal, DepsMut, Env, MessageInfo, Response};

use crate::contract::{BetApp, BetResult};
use crate::msg::BetInstantiateMsg;
use crate::state::{Config, CONFIG, DEFAULT_RAKE_PERCENT, State, STATE};
use crate::state::{Config, State, CONFIG, DEFAULT_RAKE_PERCENT, STATE};

pub const INSTANTIATE_REPLY_ID: u64 = 1u64;

Expand Down
Loading

0 comments on commit 5103360

Please sign in to comment.