Skip to content
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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion contracts/red-bank/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "mars-red-bank"
description = "A smart contract that manages asset deposit, borrowing, and liquidations"
version = "2.3.2"
version = "2.3.3"
authors = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
Expand Down
4 changes: 4 additions & 0 deletions contracts/red-bank/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, Co
match msg {
MigrateMsg::V2_2_0ToV2_3_0 {} => migrations::v2_3_0::migrate(deps),
MigrateMsg::V2_3_0ToV2_3_1 {} => migrations::v2_3_1::migrate(deps),
MigrateMsg::V2_3_2ToV2_3_3 {
haircut,
market,
} => migrations::v2_3_3::migrate(deps, haircut, &market),
MigrateMsg::V2_3_1ToV2_3_2 {} => migrations::v2_3_2::migrate(deps),
}
}
1 change: 1 addition & 0 deletions contracts/red-bank/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod v2_3_0;
pub mod v2_3_1;
pub mod v2_3_2;
pub mod v2_3_3;
47 changes: 47 additions & 0 deletions contracts/red-bank/src/migrations/v2_3_3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use cosmwasm_std::{Addr, Decimal, DepsMut, Response};
use cw2::{assert_contract_version, set_contract_version};
use mars_types::keys::{UserId, UserIdKey};

use crate::{
contract::{CONTRACT_NAME, CONTRACT_VERSION},
error::ContractError,
state::{COLLATERALS, MARKETS},
};

const FROM_VERSION: &str = "2.3.2";

pub fn migrate(deps: DepsMut, haircut: Decimal, denom: &str) -> Result<Response, ContractError> {
// 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)?;
// Load affected market
let mut market = MARKETS.load(deps.storage, denom)?;
// Apply haircut
let new_index = market.liquidity_index.checked_mul(Decimal::one().checked_sub(haircut)?)?;
market.liquidity_index = new_index;
// Save new state
MARKETS.save(deps.storage, denom, &market)?;

// Remove MPF collateral
let mpf_account_id = "4954";
let acc_id = mpf_account_id.to_string();

let user_id = UserId::credit_manager(
Addr::unchecked(
"neutron1qdzn3l4kn7gsjna2tfpg3g3mwd6kunx4p50lfya59k02846xas6qslgs3r".to_string(),
),
acc_id,
);
let user_id_key: UserIdKey = user_id.try_into()?;

COLLATERALS.remove(deps.storage, (&user_id_key, denom));

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)
.add_attribute("to_version", CONTRACT_VERSION)
.add_attribute("haircut_percent", haircut.to_string())
.add_attribute("haircut_market", denom))
}
116 changes: 91 additions & 25 deletions contracts/red-bank/tests/tests/test_migration_v2.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
use cosmwasm_std::{attr, testing::mock_env, Event};
use cosmwasm_std::{attr, testing::mock_env, Addr, Decimal, Event, Uint128};
use cw2::{ContractVersion, VersionError};
use mars_red_bank::{contract::migrate, error::ContractError};
use mars_red_bank::{
contract::{migrate, CONTRACT_VERSION},
error::ContractError,
state::{COLLATERALS, MARKETS},
};
use mars_testing::mock_dependencies;
use mars_types::red_bank::MigrateMsg;
use mars_types::{
keys::{UserId, UserIdKey},
red_bank::{Collateral, Market, MigrateMsg},
};

const CONTRACT_NAME: &str = "crates.io:mars-red-bank";

const FROM_VERSION_V2_3_2: &str = "2.3.2";

#[test]
fn v2_2_0_to_v2_3_0_wrong_contract_name() {
Expand All @@ -23,7 +34,7 @@ fn v2_2_0_to_v2_3_0_wrong_contract_name() {
#[test]
fn v2_2_0_to_v2_3_0_wrong_contract_version() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-red-bank", "4.1.0").unwrap();
cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "4.1.0").unwrap();

let err = migrate(deps.as_mut(), mock_env(), MigrateMsg::V2_2_0ToV2_3_0 {}).unwrap_err();

Expand All @@ -39,7 +50,7 @@ fn v2_2_0_to_v2_3_0_wrong_contract_version() {
#[test]
fn v2_2_0_to_v2_3_0_successful_migration() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-red-bank", "2.2.0").unwrap();
cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "2.2.0").unwrap();

let res = migrate(deps.as_mut(), mock_env(), MigrateMsg::V2_2_0ToV2_3_0 {}).unwrap();

Expand All @@ -52,7 +63,7 @@ fn v2_2_0_to_v2_3_0_successful_migration() {
);

let new_contract_version = ContractVersion {
contract: "crates.io:mars-red-bank".to_string(),
contract: CONTRACT_NAME.to_string(),
version: "2.3.0".to_string(),
};
assert_eq!(cw2::get_contract_version(deps.as_ref().storage).unwrap(), new_contract_version);
Expand All @@ -77,7 +88,7 @@ fn v2_3_0_to_v2_3_1_wrong_contract_name() {
#[test]
fn v2_3_0_to_v2_3_1_wrong_contract_version() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-red-bank", "2.2.0").unwrap();
cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "2.2.0").unwrap();

let err = migrate(deps.as_mut(), mock_env(), MigrateMsg::V2_3_0ToV2_3_1 {}).unwrap_err();

Expand All @@ -93,7 +104,7 @@ fn v2_3_0_to_v2_3_1_wrong_contract_version() {
#[test]
fn v2_3_0_to_v2_3_1_successful_migration() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-red-bank", "2.3.0").unwrap();
cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "2.3.0").unwrap();

let res = migrate(deps.as_mut(), mock_env(), MigrateMsg::V2_3_0ToV2_3_1 {}).unwrap();

Expand All @@ -106,62 +117,117 @@ fn v2_3_0_to_v2_3_1_successful_migration() {
);

let new_contract_version = ContractVersion {
contract: "crates.io:mars-red-bank".to_string(),
contract: CONTRACT_NAME.to_string(),
version: "2.3.1".to_string(),
};
assert_eq!(cw2::get_contract_version(deps.as_ref().storage).unwrap(), new_contract_version);
}

#[test]
fn v2_3_1_to_v2_3_2_wrong_contract_name() {
fn v2_3_2_to_v2_3_3_wrong_contract_name() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "contract_xyz", "2.3.1").unwrap();

let err = migrate(deps.as_mut(), mock_env(), MigrateMsg::V2_3_1ToV2_3_2 {}).unwrap_err();
cw2::set_contract_version(deps.as_mut().storage, "contract_xyz", FROM_VERSION_V2_3_2).unwrap();

let err = migrate(
deps.as_mut(),
mock_env(),
MigrateMsg::V2_3_2ToV2_3_3 {
haircut: Decimal::percent(10),
market: "umars".to_string(),
},
)
.unwrap_err();

assert_eq!(
err,
ContractError::Version(VersionError::WrongContract {
expected: "crates.io:mars-red-bank".to_string(),
expected: CONTRACT_NAME.to_string(),
found: "contract_xyz".to_string()
})
);
}

#[test]
fn v2_3_1_to_v2_3_2_wrong_contract_version() {
fn v2_3_2_to_v2_3_3_wrong_contract_version() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-red-bank", "2.3.0").unwrap();

let err = migrate(deps.as_mut(), mock_env(), MigrateMsg::V2_3_1ToV2_3_2 {}).unwrap_err();
cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "2.3.0").unwrap();

let err = migrate(
deps.as_mut(),
mock_env(),
MigrateMsg::V2_3_2ToV2_3_3 {
haircut: Decimal::percent(10),
market: "umars".to_string(),
},
)
.unwrap_err();

assert_eq!(
err,
ContractError::Version(VersionError::WrongVersion {
expected: "2.3.1".to_string(),
expected: FROM_VERSION_V2_3_2.to_string(),
found: "2.3.0".to_string()
})
);
}

#[test]
fn v2_3_1_to_v2_3_2_successful_migration() {
fn v2_3_2_to_v2_3_3_successful_migration() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-red-bank", "2.3.1").unwrap();
cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, FROM_VERSION_V2_3_2).unwrap();

let res = migrate(deps.as_mut(), mock_env(), MigrateMsg::V2_3_1ToV2_3_2 {}).unwrap();
let denom = "umars";
let market = Market {
denom: denom.to_string(),
liquidity_index: Decimal::percent(200),
..Market::default()
};
MARKETS.save(deps.as_mut().storage, denom, &market).unwrap();

let user_addr =
Addr::unchecked("neutron1qdzn3l4kn7gsjna2tfpg3g3mwd6kunx4p50lfya59k02846xas6qslgs3r");
let user_id = UserId::credit_manager(user_addr, "4954".to_string());
let user_id_key: UserIdKey = user_id.try_into().unwrap();
let collateral = Collateral {
amount_scaled: Uint128::new(1234),
enabled: true,
};
COLLATERALS.save(deps.as_mut().storage, (&user_id_key, denom), &collateral).unwrap();

let haircut = Decimal::percent(10);
let res = migrate(
deps.as_mut(),
mock_env(),
MigrateMsg::V2_3_2ToV2_3_3 {
haircut,
market: denom.to_string(),
},
)
.unwrap();

assert_eq!(res.messages, vec![]);
assert_eq!(res.events, vec![] as Vec<Event>);
assert!(res.data.is_none());
assert_eq!(
res.attributes,
vec![attr("action", "migrate"), attr("from_version", "2.3.1"), attr("to_version", "2.3.2")]
vec![
attr("action", "migrate"),
attr("from_version", FROM_VERSION_V2_3_2),
attr("to_version", CONTRACT_VERSION),
attr("to_version", CONTRACT_VERSION),
attr("haircut_percent", haircut.to_string()),
attr("haircut_market", denom),
]
);

let new_market = MARKETS.load(deps.as_ref().storage, denom).unwrap();
assert_eq!(new_market.liquidity_index, Decimal::percent(180));

assert!(COLLATERALS.may_load(deps.as_ref().storage, (&user_id_key, denom)).unwrap().is_none());

let new_contract_version = ContractVersion {
contract: "crates.io:mars-red-bank".to_string(),
version: "2.3.2".to_string(),
contract: CONTRACT_NAME.to_string(),
version: CONTRACT_VERSION.to_string(),
};
assert_eq!(cw2::get_contract_version(deps.as_ref().storage).unwrap(), new_contract_version);
}
4 changes: 4 additions & 0 deletions packages/types/src/red_bank/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,8 @@ pub enum MigrateMsg {
V2_2_0ToV2_3_0 {},
V2_3_0ToV2_3_1 {},
V2_3_1ToV2_3_2 {},
V2_3_2ToV2_3_3 {
haircut: Decimal,
market: String,
},
}
2 changes: 1 addition & 1 deletion schemas/mars-red-bank/mars-red-bank.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"contract_name": "mars-red-bank",
"contract_version": "2.3.2",
"contract_version": "2.3.3",
"idl_version": "1.0.0",
"instantiate": {
"$schema": "http://json-schema.org/draft-07/schema#",
Expand Down
Loading