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

feat(maker): add seize endpoint #440

Merged
merged 3 commits into from
Feb 24, 2025
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
119 changes: 112 additions & 7 deletions contracts/tokenomics/maker/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::collections::{HashMap, HashSet};
use std::str::FromStr;

use cosmwasm_std::{
attr, ensure, entry_point, to_json_binary, to_json_string, Addr, Attribute, Binary, Decimal,
Deps, DepsMut, Env, MessageInfo, Order, ReplyOn, Response, StdError, StdResult, SubMsg,
Uint128, Uint64,
attr, ensure, ensure_eq, entry_point, to_json_binary, to_json_string, Addr, Attribute, Binary,
Decimal, Deps, DepsMut, Env, MessageInfo, Order, ReplyOn, Response, StdError, StdResult,
SubMsg, Uint128, Uint64,
};
use cw2::{get_contract_version, set_contract_version};

Expand All @@ -14,14 +14,15 @@ use astroport::common::{claim_ownership, drop_ownership_proposal, propose_new_ow
use astroport::factory::UpdateAddr;
use astroport::maker::{
AssetWithLimit, BalancesResponse, Config, ConfigResponse, ExecuteMsg, InstantiateMsg,
MigrateMsg, QueryMsg, SecondReceiverConfig, SecondReceiverParams, UpdateDevFundConfig,
MigrateMsg, QueryMsg, SecondReceiverConfig, SecondReceiverParams, SeizeConfig,
UpdateDevFundConfig,
};
use astroport::pair::MAX_ALLOWED_SLIPPAGE;

use crate::error::ContractError;
use crate::migration::migrate_from_v120_plus;
use crate::reply::PROCESS_DEV_FUND_REPLY_ID;
use crate::state::{BRIDGES, CONFIG, LAST_COLLECT_TS, OWNERSHIP_PROPOSAL};
use crate::state::{BRIDGES, CONFIG, LAST_COLLECT_TS, OWNERSHIP_PROPOSAL, SEIZE_CONFIG};
use crate::utils::{
build_distribute_msg, build_send_msg, build_swap_msg, get_pool, try_build_swap_msg,
update_second_receiver_cfg, validate_bridge, validate_cooldown, BRIDGES_EXECUTION_MAX_DEPTH,
Expand Down Expand Up @@ -120,6 +121,16 @@ pub fn instantiate(
(String::from("none"), String::from("0"))
};

SEIZE_CONFIG.save(
deps.storage,
&SeizeConfig {
// set to invalid address initially
// governance must update this explicitly
receiver: Addr::unchecked(""),
seizable_assets: vec![],
},
)?;

Ok(Response::default().add_attributes([
attr("owner", msg.owner),
attr(
Expand Down Expand Up @@ -270,6 +281,25 @@ pub fn execute(

Ok(Response::default().add_attribute("action", "enable_rewards"))
}
ExecuteMsg::Seize { assets } => seize(deps, env, assets),
ExecuteMsg::UpdateSeizeConfig {
receiver,
seizable_assets,
} => {
let config = CONFIG.load(deps.storage)?;

ensure_eq!(info.sender, config.owner, ContractError::Unauthorized {});

SEIZE_CONFIG.update::<_, StdError>(deps.storage, |mut seize_config| {
if let Some(receiver) = receiver {
seize_config.receiver = deps.api.addr_validate(&receiver)?;
}
seize_config.seizable_assets = seizable_assets;
Ok(seize_config)
})?;

Ok(Response::new().add_attribute("action", "update_seize_config"))
}
}
}

Expand Down Expand Up @@ -870,6 +900,61 @@ fn update_bridges(
Ok(Response::default().add_attribute("action", "update_bridges"))
}

fn seize(deps: DepsMut, env: Env, assets: Vec<AssetWithLimit>) -> Result<Response, ContractError> {
ensure!(
!assets.is_empty(),
StdError::generic_err("assets vector is empty")
);

let conf = SEIZE_CONFIG.load(deps.storage)?;

ensure!(
!conf.seizable_assets.is_empty(),
StdError::generic_err("No seizable assets found")
);

let input_set = assets
.iter()
.map(|a| a.info.to_string())
.collect::<HashSet<_>>();
let seizable_set = conf
.seizable_assets
.iter()
.map(|a| a.to_string())
.collect::<HashSet<_>>();

ensure!(
input_set.is_subset(&seizable_set),
StdError::generic_err("Input vector contains assets that are not seizable")
);

let send_msgs = assets
.into_iter()
.filter_map(|asset| {
let balance = asset
.info
.query_pool(&deps.querier, &env.contract.address)
.ok()?;

let limit = asset
.limit
.map(|limit| limit.min(balance))
.unwrap_or(balance);

// Filter assets with empty balances
if limit.is_zero() {
None
} else {
Some(asset.info.with_balance(limit).into_msg(&conf.receiver))
}
})
.collect::<StdResult<Vec<_>>>()?;

Ok(Response::new()
.add_messages(send_msgs)
.add_attribute("action", "seize"))
}

/// Exposes all the queries available in the contract.
///
/// ## Queries
Expand All @@ -886,6 +971,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
QueryMsg::Config {} => to_json_binary(&query_get_config(deps)?),
QueryMsg::Balances { assets } => to_json_binary(&query_get_balances(deps, env, assets)?),
QueryMsg::Bridges {} => to_json_binary(&query_bridges(deps)?),
QueryMsg::QuerySeizeConfig {} => to_json_binary(&SEIZE_CONFIG.load(deps.storage)?),
}
}

Expand Down Expand Up @@ -952,13 +1038,32 @@ pub fn migrate(mut deps: DepsMut, env: Env, msg: MigrateMsg) -> Result<Response,
"1.2.0" => {
migrate_from_v120_plus(deps.branch(), msg)?;
LAST_COLLECT_TS.save(deps.storage, &env.block.time.seconds())?;

SEIZE_CONFIG.save(
deps.storage,
&SeizeConfig {
// set to invalid address initially
// governance must update this explicitly
receiver: Addr::unchecked(""),
seizable_assets: vec![],
},
)?;
}
"1.4.0" => {}
"1.5.0" => {
"1.4.0" | "1.5.0" => {
// It is enough to load and save config
// as we added only one optional field config.dev_fund_conf
let config = CONFIG.load(deps.storage)?;
CONFIG.save(deps.storage, &config)?;

SEIZE_CONFIG.save(
deps.storage,
&SeizeConfig {
// set to invalid address initially
// governance must update this explicitly
receiver: Addr::unchecked(""),
seizable_assets: vec![],
},
)?;
}
_ => return Err(ContractError::MigrationError {}),
},
Expand Down
4 changes: 3 additions & 1 deletion contracts/tokenomics/maker/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use astroport::asset::AssetInfo;
use astroport::common::OwnershipProposal;
use astroport::maker::Config;
use astroport::maker::{Config, SeizeConfig};
use cw_storage_plus::{Item, Map};

/// Stores the contract configuration at the given key
Expand All @@ -13,3 +13,5 @@ pub const OWNERSHIP_PROPOSAL: Item<OwnershipProposal> = Item::new("ownership_pro
pub const BRIDGES: Map<String, AssetInfo> = Map::new("bridges");
/// Stores the latest timestamp when fees were collected
pub const LAST_COLLECT_TS: Item<u64> = Item::new("last_collect_ts");
/// Stores seize config
pub const SEIZE_CONFIG: Item<SeizeConfig> = Item::new("seize_config");
Loading
Loading