Skip to content

Commit

Permalink
Merge pull request #86 from CosmWasm/cw20-zero-amount-checks
Browse files Browse the repository at this point in the history
Cw20 zero amount checks
  • Loading branch information
ethanfrey committed Sep 14, 2020
2 parents 1d30838 + b1ad7c7 commit 243801c
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 30 deletions.
2 changes: 1 addition & 1 deletion contracts/cw20-atomic-swap/src/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl Balance {
pub fn is_empty(&self) -> bool {
match self {
Balance::Native(coins) => coins.is_empty(),
Balance::Cw20(_) => false, // FIXME: Reject zero-valued coins
Balance::Cw20(coin) => coin.is_empty(),
}
}
}
2 changes: 1 addition & 1 deletion contracts/cw20-base/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This is a basic implementation of a cw20 contract. It implements
the [CW20 spec](../../packages/cw20/README.md) and is designed to
be deloyed as is, or imported into other contracts to easily build
be deployed as is, or imported into other contracts to easily build
cw20-compatible tokens with custom logic.

Implements:
Expand Down
10 changes: 5 additions & 5 deletions contracts/cw20-base/schema/init_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"initial_balances": {
"type": "array",
"items": {
"$ref": "#/definitions/InitialBalance"
"$ref": "#/definitions/Cw20CoinHuman"
}
},
"mint": {
Expand All @@ -38,10 +38,7 @@
}
},
"definitions": {
"HumanAddr": {
"type": "string"
},
"InitialBalance": {
"Cw20CoinHuman": {
"type": "object",
"required": [
"address",
Expand All @@ -56,6 +53,9 @@
}
}
},
"HumanAddr": {
"type": "string"
},
"MinterResponse": {
"type": "object",
"required": [
Expand Down
6 changes: 3 additions & 3 deletions contracts/cw20-base/src/allowances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,10 @@ mod tests {

use cosmwasm_std::testing::{mock_dependencies, mock_env};
use cosmwasm_std::{coins, CosmosMsg, StdError, WasmMsg};
use cw20::TokenInfoResponse;
use cw20::{Cw20CoinHuman, TokenInfoResponse};

use crate::contract::{handle, init, query_balance, query_token_info};
use crate::msg::{HandleMsg, InitMsg, InitialBalance};
use crate::msg::{HandleMsg, InitMsg};

fn get_balance<S: Storage, A: Api, Q: Querier, T: Into<HumanAddr>>(
deps: &Extern<S, A, Q>,
Expand All @@ -287,7 +287,7 @@ mod tests {
name: "Auto Gen".to_string(),
symbol: "AUTO".to_string(),
decimals: 3,
initial_balances: vec![InitialBalance {
initial_balances: vec![Cw20CoinHuman {
address: addr.into(),
amount,
}],
Expand Down
18 changes: 9 additions & 9 deletions contracts/cw20-base/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use cosmwasm_std::{
MigrateResponse, Querier, StdError, StdResult, Storage, Uint128,
};
use cw2::{get_contract_version, set_contract_version};
use cw20::{BalanceResponse, Cw20ReceiveMsg, MinterResponse, TokenInfoResponse};
use cw20::{BalanceResponse, Cw20CoinHuman, Cw20ReceiveMsg, MinterResponse, TokenInfoResponse};

use crate::allowances::{
handle_burn_from, handle_decrease_allowance, handle_increase_allowance, handle_send_from,
handle_transfer_from, query_allowance,
};
use crate::enumerable::{query_all_accounts, query_all_allowances};
use crate::migrations::migrate_v01_to_v02;
use crate::msg::{HandleMsg, InitMsg, InitialBalance, MigrateMsg, QueryMsg};
use crate::msg::{HandleMsg, InitMsg, MigrateMsg, QueryMsg};
use crate::state::{balances, balances_read, token_info, token_info_read, MinterData, TokenInfo};

// version info for migration info
Expand Down Expand Up @@ -57,7 +57,7 @@ pub fn init<S: Storage, A: Api, Q: Querier>(

pub fn create_accounts<S: Storage, A: Api, Q: Querier>(
deps: &mut Extern<S, A, Q>,
accounts: &[InitialBalance],
accounts: &[Cw20CoinHuman],
) -> StdResult<Uint128> {
let mut total_supply = Uint128::zero();
let mut store = balances(&mut deps.storage);
Expand Down Expand Up @@ -396,7 +396,7 @@ mod tests {
name: "Auto Gen".to_string(),
symbol: "AUTO".to_string(),
decimals: 3,
initial_balances: vec![InitialBalance {
initial_balances: vec![Cw20CoinHuman {
address: addr.into(),
amount,
}],
Expand Down Expand Up @@ -429,7 +429,7 @@ mod tests {
name: "Cash Token".to_string(),
symbol: "CASH".to_string(),
decimals: 9,
initial_balances: vec![InitialBalance {
initial_balances: vec![Cw20CoinHuman {
address: HumanAddr("addr0000".to_string()),
amount,
}],
Expand Down Expand Up @@ -461,7 +461,7 @@ mod tests {
name: "Cash Token".to_string(),
symbol: "CASH".to_string(),
decimals: 9,
initial_balances: vec![InitialBalance {
initial_balances: vec![Cw20CoinHuman {
address: HumanAddr("addr0000".to_string()),
amount,
}],
Expand Down Expand Up @@ -503,7 +503,7 @@ mod tests {
name: "Cash Token".to_string(),
symbol: "CASH".to_string(),
decimals: 9,
initial_balances: vec![InitialBalance {
initial_balances: vec![Cw20CoinHuman {
address: HumanAddr("addr0000".to_string()),
amount,
}],
Expand Down Expand Up @@ -612,11 +612,11 @@ mod tests {
symbol: "BASH".to_string(),
decimals: 6,
initial_balances: vec![
InitialBalance {
Cw20CoinHuman {
address: addr1.clone(),
amount: amount1,
},
InitialBalance {
Cw20CoinHuman {
address: addr2.clone(),
amount: amount2,
},
Expand Down
6 changes: 3 additions & 3 deletions contracts/cw20-base/src/enumerable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ mod tests {

use cosmwasm_std::testing::{mock_dependencies, mock_env};
use cosmwasm_std::{coins, Uint128};
use cw20::{Expiration, TokenInfoResponse};
use cw20::{Cw20CoinHuman, Expiration, TokenInfoResponse};

use crate::contract::{handle, init, query_token_info};
use crate::msg::{HandleMsg, InitMsg, InitialBalance};
use crate::msg::{HandleMsg, InitMsg};

// this will set up the init for other tests
fn do_init<S: Storage, A: Api, Q: Querier>(
Expand All @@ -87,7 +87,7 @@ mod tests {
name: "Auto Gen".to_string(),
symbol: "AUTO".to_string(),
decimals: 3,
initial_balances: vec![InitialBalance {
initial_balances: vec![Cw20CoinHuman {
address: addr.into(),
amount,
}],
Expand Down
10 changes: 2 additions & 8 deletions contracts/cw20-base/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
use cosmwasm_std::{Binary, HumanAddr, StdError, StdResult, Uint128};
use cw20::{Expiration, MinterResponse};
use cw20::{Cw20CoinHuman, Expiration, MinterResponse};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
pub struct InitialBalance {
pub address: HumanAddr,
pub amount: Uint128,
}

#[derive(Serialize, Deserialize, JsonSchema)]
pub struct InitMsg {
pub name: String,
pub symbol: String,
pub decimals: u8,
pub initial_balances: Vec<InitialBalance>,
pub initial_balances: Vec<Cw20CoinHuman>,
pub mint: Option<MinterResponse>,
}

Expand Down
10 changes: 10 additions & 0 deletions contracts/cw20-escrow/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ pub fn try_cw20_create<S: Storage, A: Api, Q: Querier>(
token: Cw20Coin,
msg: CreateMsg,
) -> StdResult<HandleResponse> {
if token.is_empty() {
return Err(StdError::generic_err(
"Send some amount to create an escrow",
));
}
let mut cw20_whitelist = msg.canonical_whitelist(&deps.api)?;
// make sure the token sent is on the whitelist by default
if !cw20_whitelist.iter().any(|t| t == &token.address) {
Expand Down Expand Up @@ -151,6 +156,11 @@ pub fn try_cw20_top_up<S: Storage, A: Api, Q: Querier>(
token: Cw20Coin,
id: String,
) -> StdResult<HandleResponse> {
if token.is_empty() {
return Err(StdError::generic_err(
"Send some amount to increase an escrow",
));
}
// this fails is no escrow there
let mut escrow = escrows_read(&deps.storage).load(id.as_bytes())?;

Expand Down
6 changes: 6 additions & 0 deletions packages/cw20/src/coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ pub struct Cw20Coin {
pub amount: Uint128,
}

impl Cw20Coin {
pub fn is_empty(&self) -> bool {
self.amount == Uint128(0)
}
}

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
pub struct Cw20CoinHuman {
pub address: HumanAddr,
Expand Down

0 comments on commit 243801c

Please sign in to comment.