Skip to content

Commit

Permalink
Begin implementing buy/sell logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanfrey committed Dec 15, 2020
1 parent 83b2859 commit c3fd928
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 42 deletions.
2 changes: 1 addition & 1 deletion contracts/cw20-base/src/allowances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub fn handle_decrease_allowance(
}

// this can be used to update a lower allowance - call bucket.update with proper keys
fn deduct_allowance(
pub fn deduct_allowance(
storage: &mut dyn Storage,
owner: &CanonicalAddr,
spender: &CanonicalAddr,
Expand Down
88 changes: 51 additions & 37 deletions contracts/cw20-bonding/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ use cosmwasm_std::{

use cw2::set_contract_version;
use cw20_base::allowances::{
handle_decrease_allowance, handle_increase_allowance, handle_send_from, handle_transfer_from,
query_allowance,
deduct_allowance, handle_decrease_allowance, handle_increase_allowance, handle_send_from,
handle_transfer_from, query_allowance,
};
use cw20_base::contract::{
handle_burn, handle_mint, handle_send, handle_transfer, query_balance, query_token_info,
handle_send,
handle_transfer,
query_balance,
query_token_info,
// handle_burn, handle_mint,
};
use cw20_base::state::{token_info, MinterData, TokenInfo};

use crate::error::ContractError;
use crate::msg::{CurveInfoResponse, HandleMsg, InitMsg, QueryMsg};
use crate::state::{Supply, SUPPLY};
use crate::state::{CurveState, CURVE_STATE};

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:cw20-bonding";
Expand Down Expand Up @@ -43,8 +47,8 @@ pub fn init(
};
token_info(deps.storage).save(&data)?;

let supply = Supply::new(msg.reserve_denom);
SUPPLY.save(deps.storage, &supply)?;
let supply = CurveState::new(msg.reserve_denom);
CURVE_STATE.save(deps.storage, &supply)?;

Ok(InitResponse::default())
}
Expand Down Expand Up @@ -107,31 +111,33 @@ pub fn handle(

pub fn handle_buy(
deps: DepsMut,
env: Env,
_env: Env,
info: MessageInfo,
) -> Result<HandleResponse, ContractError> {
let supply = CURVE_STATE.load(deps.storage)?;

// ensure the sent denom was proper
let sent = match info.sent_funds.len() {
0 => Err(ContractError::NoFunds {}),
1 => {
if info.sent_funds[0].denom == supply.reserve_denom {
Ok(info.sent_funds[0].amount)
} else {
Err(ContractError::MissingDenom(supply.reserve_denom.clone()))
}
}
_ => Err(ContractError::ExtraDenoms(supply.reserve_denom.clone())),
}?;
if sent.is_zero() {
return Err(ContractError::NoFunds {});
}

// TODO: calculate how many tokens can be purchased with this and mint them

unimplemented!();
// // ensure we have the proper denom
// let invest = invest_info_read(deps.storage).load()?;
// // payment finds the proper coin (or throws an error)
// let payment = info
// .sent_funds
// .iter()
// .find(|x| x.denom == invest.bond_denom)
// .ok_or_else(|| ContractError::EmptyBalance {
// denom: invest.bond_denom.clone(),
// })?;
//
// // bonded is the total number of tokens we have delegated from this address
// let bonded = get_bonded(&deps.querier, &env.contract.address)?;
//
// // calculate to_mint and update total supply
// let mut totals = total_supply(deps.storage);
// let mut supply = totals.load()?;
// // TODO: this is just a safety assertion - do we keep it, or remove caching?
// // in the end supply is just there to cache the (expected) results of get_bonded() so we don't
// // have expensive queries everywhere
// assert_bonds(&supply, bonded)?;
// let to_mint = if supply.issued.is_zero() || bonded.is_zero() {
// FALLBACK_RATIO * payment.amount
// } else {
Expand All @@ -150,11 +156,6 @@ pub fn handle_buy(
//
// // bond them to the validator
// let res = HandleResponse {
// messages: vec![StakingMsg::Delegate {
// validator: invest.validator,
// amount: payment.clone(),
// }
// .into()],
// attributes: vec![
// attr("action", "bond"),
// attr("from", info.sender),
Expand All @@ -167,10 +168,10 @@ pub fn handle_buy(
}

pub fn handle_sell(
deps: DepsMut,
env: Env,
info: MessageInfo,
amount: Uint128,
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
_amount: Uint128,
) -> Result<HandleResponse, ContractError> {
unimplemented!();
}
Expand All @@ -182,7 +183,18 @@ pub fn handle_sell_from(
owner: HumanAddr,
amount: Uint128,
) -> Result<HandleResponse, ContractError> {
unimplemented!();
let owner_raw = deps.api.canonical_address(&owner)?;
let spender_raw = deps.api.canonical_address(&info.sender)?;

// deduct allowance before doing anything else have enough allowance
deduct_allowance(deps.storage, &owner_raw, &spender_raw, &env.block, amount)?;

// TODO: don't return verbatim, different return attrs
let owner_info = MessageInfo {
sender: owner.clone(),
sent_funds: info.sent_funds,
};
handle_sell(deps, env, owner_info, amount)
}

// pub fn unbond(
Expand Down Expand Up @@ -273,11 +285,11 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
}

pub fn query_curve_info(deps: Deps) -> StdResult<CurveInfoResponse> {
let Supply {
let CurveState {
reserve,
supply,
reserve_denom,
} = SUPPLY.load(deps.storage)?;
} = CURVE_STATE.load(deps.storage)?;
Ok(CurveInfoResponse {
reserve,
supply,
Expand All @@ -287,6 +299,8 @@ pub fn query_curve_info(deps: Deps) -> StdResult<CurveInfoResponse> {
})
}

// this is poor mans "skip" flag
#[cfg(target_arch = "arm")]
#[cfg(test)]
mod tests {
use super::*;
Expand Down
9 changes: 5 additions & 4 deletions contracts/cw20-bonding/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use cw_storage_plus::Item;

/// Supply is dynamic and tracks the current supply of staked and ERC20 tokens.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default)]
pub struct Supply {
pub struct CurveState {
/// reserve is how many native tokens exist bonded to the validator
pub reserve: Uint128,
/// supply is how many tokens this contract has issued
Expand All @@ -16,16 +16,17 @@ pub struct Supply {
pub reserve_denom: String,
}

impl Supply {
impl CurveState {
pub fn new(reserve_denom: String) -> Self {
Supply {
CurveState {
reserve: Uint128(0),
supply: Uint128(0),
reserve_denom,
}
}
}

pub const SUPPLY: Item<Supply> = Item::new("total_supply");
pub const CURVE_STATE: Item<CurveState> = Item::new("total_supply");

// TODO: add curve functions
// TODO: make this customizable in handle/query call

0 comments on commit c3fd928

Please sign in to comment.