Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/fix/point_3' into fix/scv-audit
Browse files Browse the repository at this point in the history
  • Loading branch information
nseguias committed Sep 25, 2024
2 parents d26e3d8 + caa5449 commit a097de0
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 17 deletions.
2 changes: 1 addition & 1 deletion contracts/treasurechest-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn execute(
ExecuteMsg::ChangeTokenFactory {
token_factory_type,
} => change_token_factory(deps, info.sender, &token_factory_type),
ExecuteMsg::ReturnDust {} => return_dust(deps, env, info.sender),
ExecuteMsg::ReturnDust {limit} => return_dust(deps, env, info.sender, limit),
}
}

Expand Down
46 changes: 34 additions & 12 deletions contracts/treasurechest-contract/src/executions.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::{ops::Mul, str::FromStr};
use std::collections::HashMap;
use std::ops::Sub;

use cosmwasm_std::{
Addr, BankMsg, Coin, CosmosMsg, DepsMut, Env, Event, MessageInfo, Order, Response, StdResult,
Uint128,
};
const DEFAULT_SIZE:u32 = 20;
const MIN_TICKETS:u128 = 2;

use cosmwasm_std::{Addr, BalanceResponse, BankMsg, BankQuery, Coin, CosmosMsg, DepsMut, Env, Event, MessageInfo, Order, Response, StdResult, Uint128};
use cosmwasm_std::QueryRequest::Bank;
use treasurechest::{errors::ContractError, tf::tokenfactory::TokenFactoryType};

use crate::state::{CONFIG, TOTAL_REWARDS};
Expand Down Expand Up @@ -76,27 +79,46 @@ pub fn change_token_factory(
.add_attribute("action", "treasurechest/change_token_factory"))
}

pub fn return_dust(deps: DepsMut, env: Env, sender: Addr) -> Result<Response, ContractError> {
pub fn return_dust(deps: DepsMut, env: Env, sender: Addr, limit: Option<u32>) -> Result<Response, ContractError> {
cw_ownable::assert_owner(deps.storage, &sender)?;
let config = CONFIG.load(deps.storage)?;

let denom_total = deps.querier.query::<BalanceResponse>(&Bank(BankQuery::Supply {denom: config.denom.clone()}))?;
if config.burn_it {
if denom_total .amount.amount.u128()> MIN_TICKETS {
return Err(ContractError::TicketsOutstanding(denom_total.amount.amount.u128(),MIN_TICKETS))
}
} else {
let ticket_balance = deps.querier.query_balance(env.contract.address.clone(),config.denom.clone())?;
let outstanding = denom_total.amount.amount.sub(ticket_balance.amount);
if outstanding.u128() > MIN_TICKETS {
return Err(ContractError::TicketsOutstanding(outstanding.u128(),MIN_TICKETS))
}
}

let balances = deps
.querier
.query_all_balances(env.contract.address)?
.into_iter()
.filter(|x| x.denom != config.denom)
.collect::<Vec<Coin>>();
.filter(|x| x.denom != config.denom).map(|coin| (coin.denom,coin.amount))
.collect::<HashMap<String,Uint128>>();
let mut balances_out = vec![];

for entry in balances {
if let Some(one_amt) = TOTAL_REWARDS.may_load(deps.storage, entry.denom.clone())? {
if one_amt.to_uint_floor() > entry.amount {
TOTAL_REWARDS.remove(deps.storage, entry.denom.clone());
balances_out.push(entry)
let rewards = TOTAL_REWARDS.range(deps.storage, None,None,Order::Ascending).take(limit.unwrap_or(DEFAULT_SIZE).try_into()?).collect::<StdResult<Vec<_>>>()?;
for reward in rewards {
let reward_amt = reward.1.to_uint_floor();
if let Some(token_balance) = balances.get( &reward.0) {
if &reward_amt > token_balance{
TOTAL_REWARDS.remove(deps.storage, reward.0.clone());
balances_out.push(Coin{denom: reward.0, amount: token_balance.clone()})
}
}
}
// balances_out should only contain the dust now.
// TOTAL rewards should no longer show that token
if balances_out.is_empty() {
return Ok(Response::new().add_attribute("action", "treasurechest/return_dust").add_attribute("dust","no-dust"))
}

let msg = CosmosMsg::Bank(BankMsg::Send {
to_address: sender.to_string(),
Expand Down
4 changes: 2 additions & 2 deletions integration/src/treasurechest/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ impl TreasureChestContract {
})
}

pub fn return_dust(&self) -> StdResult<CosmosMsg> {
self.call(ExecuteMsg::ReturnDust {})
pub fn return_dust(&self, limit:Option<u32>) -> StdResult<CosmosMsg> {
self.call(ExecuteMsg::ReturnDust {limit})
}

pub fn config(&self, app: &App) -> StdResult<ConfigResponse> {
Expand Down
2 changes: 1 addition & 1 deletion integration/src/treasurechest/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ pub fn test_withdraw() -> AnyResult<()> {
assert_eq!(state.outstanding, Uint128::zero());

app.update_block(|f| f.height += 1);
let res_admin = app.execute(Addr::unchecked(ADMIN), chest.return_dust()?)?;
let res_admin = app.execute(Addr::unchecked(ADMIN), chest.return_dust(None)?)?;
for e in get_events("transfer", &res_admin.events) {
if let Some(amount) = get_attribute("amount", &e.attributes) {
let coins = amount.split(',').map(|x| x.to_string()).collect::<Vec<_>>();
Expand Down
2 changes: 1 addition & 1 deletion packages/treasurechest/src/chest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub enum ExecuteMsg {
/// Withdraw pending rewards
Withdraw {},
/// If balance is below >1< tickets worth (ADMIN only)
ReturnDust {},
ReturnDust { limit: Option<u32>},
/// change token factory type (ADMIN only)
ChangeTokenFactory {
token_factory_type: String,
Expand Down
6 changes: 6 additions & 0 deletions packages/treasurechest/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::num::TryFromIntError;
use cosmwasm_std::{CheckedFromRatioError, DivideByZeroError, OverflowError, StdError};
use cw_ownable::OwnershipError;
use thiserror::Error;
Expand All @@ -10,6 +11,8 @@ pub enum ContractError {
Ownership(#[from] OwnershipError),
#[error("{0}")]
OverflowError(#[from] OverflowError),
#[error("{0}")]
TryFromIntError(#[from] TryFromIntError),

#[error("{0}")]
DivideByZeroError(#[from] DivideByZeroError),
Expand All @@ -23,6 +26,9 @@ pub enum ContractError {
#[error("invalid token factory type {0}")]
TokenFactoryTypeInvalid(String),

#[error("Too many outstanding redemption tokens {0} - min = {1}")]
TicketsOutstanding(u128,u128),

#[error("Unauthorized")]
Unauthorized {},

Expand Down

0 comments on commit a097de0

Please sign in to comment.