diff --git a/Cargo.lock b/Cargo.lock index 8232b4d78..f5e0025ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2399,7 +2399,7 @@ dependencies = [ [[package]] name = "mars-params" -version = "2.0.0" +version = "2.0.1" dependencies = [ "anyhow", "cosmwasm-schema", diff --git a/contracts/params/Cargo.toml b/contracts/params/Cargo.toml index eac8c0d78..3940ce36a 100644 --- a/contracts/params/Cargo.toml +++ b/contracts/params/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "mars-params" description = "Contract storing the asset params for Credit Manager and Red Bank." -version = { workspace = true } +version = "2.0.1" authors = { workspace = true } license = { workspace = true } edition = { workspace = true } diff --git a/contracts/params/src/contract.rs b/contracts/params/src/contract.rs index e4a7a36ee..fdc39fd55 100644 --- a/contracts/params/src/contract.rs +++ b/contracts/params/src/contract.rs @@ -1,6 +1,6 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; use cw2::set_contract_version; use mars_owner::OwnerInit::SetInitialOwner; use mars_types::params::{ @@ -15,6 +15,7 @@ use crate::{ assert_thf, update_asset_params, update_config, update_target_health_factor, update_vault_config, }, + migrations, query::{ query_all_asset_params, query_all_vault_configs, query_config, query_total_deposit, query_vault_config, @@ -22,8 +23,8 @@ use crate::{ state::{ADDRESS_PROVIDER, ASSET_PARAMS, OWNER, TARGET_HEALTH_FACTOR}, }; -const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -109,3 +110,8 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> ContractResult { }; res.map_err(Into::into) } + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> ContractResult { + migrations::v2_0_1::migrate(deps) +} diff --git a/contracts/params/src/error.rs b/contracts/params/src/error.rs index 409766955..d11e4636d 100644 --- a/contracts/params/src/error.rs +++ b/contracts/params/src/error.rs @@ -1,4 +1,5 @@ use cosmwasm_std::{DecimalRangeExceeded, StdError}; +use cw2::VersionError; use mars_owner::OwnerError; use mars_types::error::MarsError; use mars_utils::error::ValidationError; @@ -22,4 +23,7 @@ pub enum ContractError { #[error("{0}")] Mars(#[from] MarsError), + + #[error("{0}")] + Version(#[from] VersionError), } diff --git a/contracts/params/src/lib.rs b/contracts/params/src/lib.rs index 7d346e7ee..33737b65f 100644 --- a/contracts/params/src/lib.rs +++ b/contracts/params/src/lib.rs @@ -2,5 +2,6 @@ pub mod contract; pub mod emergency_powers; pub mod error; pub mod execute; +pub mod migrations; pub mod query; pub mod state; diff --git a/contracts/params/src/migrations/mod.rs b/contracts/params/src/migrations/mod.rs new file mode 100644 index 000000000..04e6bfcb1 --- /dev/null +++ b/contracts/params/src/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v2_0_1; diff --git a/contracts/params/src/migrations/v2_0_1.rs b/contracts/params/src/migrations/v2_0_1.rs new file mode 100644 index 000000000..777b1e365 --- /dev/null +++ b/contracts/params/src/migrations/v2_0_1.rs @@ -0,0 +1,21 @@ +use cosmwasm_std::{DepsMut, Response}; +use cw2::{assert_contract_version, set_contract_version}; + +use crate::{ + contract::{CONTRACT_NAME, CONTRACT_VERSION}, + error::ContractError, +}; + +const FROM_VERSION: &str = "2.0.0"; + +pub fn migrate(deps: DepsMut) -> Result { + // make sure we're migrating the correct contract and from the correct version + assert_contract_version(deps.storage, &format!("crates.io:{CONTRACT_NAME}"), FROM_VERSION)?; + + set_contract_version(deps.storage, format!("crates.io:{CONTRACT_NAME}"), CONTRACT_VERSION)?; + + Ok(Response::new() + .add_attribute("action", "migrate") + .add_attribute("from_version", FROM_VERSION) + .add_attribute("to_version", CONTRACT_VERSION)) +} diff --git a/contracts/params/src/query.rs b/contracts/params/src/query.rs index 2a660fa89..e3d6bacb0 100644 --- a/contracts/params/src/query.rs +++ b/contracts/params/src/query.rs @@ -4,7 +4,7 @@ use mars_interest_rate::get_underlying_liquidity_amount; use mars_types::{ address_provider::{self, MarsAddressType}, params::{AssetParams, ConfigResponse, TotalDepositResponse, VaultConfig}, - red_bank::{self, Market, UserDebtResponse}, + red_bank::{self, Market}, }; use crate::state::{ADDRESS_PROVIDER, ASSET_PARAMS, VAULT_CONFIGS}; @@ -115,26 +115,13 @@ pub fn query_total_deposit( .transpose()? .unwrap_or_else(Uint128::zero); - // amount of debt in this asset the Credit Manager owes to Red Bank - // this query returns zero if no debt is owed - let cm_debt = deps - .querier - .query_wasm_smart::( - red_bank_addr, - &red_bank::QueryMsg::UserDebt { - user: credit_manager_addr.into(), - denom: denom.clone(), - }, - )? - .amount; - // amount of this asset deposited into Credit Manager // this is simply the coin balance of the CM contract // note that this way, we don't include LP tokens or vault positions let cm_deposit = deps.querier.query_balance(credit_manager_addr, &denom)?.amount; // total deposited amount - let amount = rb_deposit.checked_add(cm_deposit)?.checked_sub(cm_debt)?; + let amount = rb_deposit.checked_add(cm_deposit)?; // additionally, we include the deposit cap in the response let asset_params = ASSET_PARAMS.load(deps.storage, &denom)?; diff --git a/contracts/params/tests/tests/mod.rs b/contracts/params/tests/tests/mod.rs index 4465a43bd..1022139ce 100644 --- a/contracts/params/tests/tests/mod.rs +++ b/contracts/params/tests/tests/mod.rs @@ -3,6 +3,7 @@ mod helpers; mod test_asset_validation; mod test_deposit_cap; mod test_emergency_powers; +mod test_migration; mod test_owner; mod test_target_health_factor; mod test_update_asset_params; diff --git a/contracts/params/tests/tests/test_deposit_cap.rs b/contracts/params/tests/tests/test_deposit_cap.rs index d4f47290f..976a1f7d7 100644 --- a/contracts/params/tests/tests/test_deposit_cap.rs +++ b/contracts/params/tests/tests/test_deposit_cap.rs @@ -62,7 +62,7 @@ fn querying_total_deposit(rb_market: Market, rb_debt: UserDebtResponse, cm_balan // setup deps.querier.set_redbank_market(rb_market.clone()); - deps.querier.set_red_bank_user_debt(CREDIT_MANAGER, rb_debt.clone()); + deps.querier.set_red_bank_user_debt(CREDIT_MANAGER, rb_debt); deps.querier.update_balances(CREDIT_MANAGER, coins(cm_balance.u128(), MOCK_DENOM)); ADDRESS_PROVIDER.save(deps.as_mut().storage, &Addr::unchecked("address_provider")).unwrap(); ASSET_PARAMS.save(deps.as_mut().storage, MOCK_DENOM, ¶ms).unwrap(); @@ -71,7 +71,7 @@ fn querying_total_deposit(rb_market: Market, rb_debt: UserDebtResponse, cm_balan let rb_deposit = get_underlying_liquidity_amount(rb_market.collateral_total_scaled, &rb_market, TIMESTAMP) .unwrap(); - let exp_total_deposit = rb_deposit + cm_balance - rb_debt.amount; + let exp_total_deposit = rb_deposit + cm_balance; // query total deposit let res = query_total_deposit(deps.as_ref(), &env, MOCK_DENOM.into()).unwrap(); diff --git a/contracts/params/tests/tests/test_migration.rs b/contracts/params/tests/tests/test_migration.rs new file mode 100644 index 000000000..72c23d0bf --- /dev/null +++ b/contracts/params/tests/tests/test_migration.rs @@ -0,0 +1,61 @@ +use cosmwasm_std::{ + attr, + testing::{mock_dependencies, mock_env}, + Empty, Event, +}; +use cw2::{ContractVersion, VersionError}; +use mars_params::{contract::migrate, error::ContractError}; + +#[test] +fn wrong_contract_name() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(deps.as_mut().storage, "contract_xyz", "1.0.0").unwrap(); + + let err = migrate(deps.as_mut(), mock_env(), Empty {}).unwrap_err(); + + assert_eq!( + err, + ContractError::Version(VersionError::WrongContract { + expected: "crates.io:mars-params".to_string(), + found: "contract_xyz".to_string() + }) + ); +} + +#[test] +fn wrong_contract_version() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-params", "4.1.0").unwrap(); + + let err = migrate(deps.as_mut(), mock_env(), Empty {}).unwrap_err(); + + assert_eq!( + err, + ContractError::Version(VersionError::WrongVersion { + expected: "2.0.0".to_string(), + found: "4.1.0".to_string() + }) + ); +} + +#[test] +fn successful_migration_to_v2_0_1() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-params", "2.0.0").unwrap(); + + let res = migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); + + assert_eq!(res.messages, vec![]); + assert_eq!(res.events, vec![] as Vec); + assert!(res.data.is_none()); + assert_eq!( + res.attributes, + vec![attr("action", "migrate"), attr("from_version", "2.0.0"), attr("to_version", "2.0.1")] + ); + + let new_contract_version = ContractVersion { + contract: "crates.io:mars-params".to_string(), + version: "2.0.1".to_string(), + }; + assert_eq!(cw2::get_contract_version(deps.as_ref().storage).unwrap(), new_contract_version); +} diff --git a/schemas/mars-params/mars-params.json b/schemas/mars-params/mars-params.json index e5ec05425..ee571bbbd 100644 --- a/schemas/mars-params/mars-params.json +++ b/schemas/mars-params/mars-params.json @@ -1,6 +1,6 @@ { "contract_name": "mars-params", - "contract_version": "2.0.0", + "contract_version": "2.0.1", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#",