Skip to content

Commit

Permalink
MP-2702. Migration for Osmo contracts (#439)
Browse files Browse the repository at this point in the history
* Update migration for address-provider.

* Update migration for account-nft.

* Update migration for credit-manager.

* Update migration for health.

* Update migration for incentives.

* Update migration for oracle-osmosis.

* Update migration for params.

* Update migration for red-bank.

* Update migration for rewards-collector.

* Update migration for swapper-osmosis.

* Update migration for zapper-osmosis.

* MP-2562. Add missing connection between RC addr and acc id.

* Generate schema.

* Update changelog.

* Add one more point to Changelog.
  • Loading branch information
piobab authored Dec 23, 2024
1 parent b99696d commit 06a510b
Show file tree
Hide file tree
Showing 78 changed files with 941 additions and 1,613 deletions.
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,66 @@

All notable changes to this project will be documented in this file.

## v2.1.0 - Osmosis Release

### Credit Manager Contract
- Introduced abstract account creation via `update_credit_account` message
- Added new account type: FundManager for Managed Vaults
- Updated `SwapExactIn` action:
```diff
SwapExactIn {
coin_in: ActionCoin,
denom_out: String,
- slippage: Decimal,
+ min_receive: Uint128,
route: Option<SwapperRoute>,
}
```
- Integrated Astro support:
- Added actions for staking, unstaking, and claiming rewards
- Introduced `staked_astro_lps` positions
- Updated deposit cap mechanism (see https://github.com/mars-protocol/contracts/pull/425)
- Trade any asset (https://github.com/mars-protocol/contracts/pull/381)

### Incentives Contract
- Added support for Astro ecosystem interactions:
- Introduced staking and unstaking functionality
- Added reward claiming mechanisms

### Params Contract
- Added new paginated queries:
- `QueryMsg::AllVaultConfigsV2`
- `QueryMsg::AllTotalDepositsV2`

### Red Bank Contract
- Removed UncollateralizedLoanLimit logic
- Added `QueryMsg::MarketsV2`

### Rewards Collector
- Updated `SwapAsset` execute message to support minimum receive amounts:
```diff
SwapAsset {
denom: String,
amount: Option<Uint128>,
safety_fund_route: Option<SwapperRoute>,
fee_collector_route: Option<SwapperRoute>,
+ safety_fund_min_receive: Option<Uint128>,
+ fee_collector_min_receive: Option<Uint128>,
}
```

### Swapper Contract
- Updated `SwapExactIn` to use minimum receive instead of slippage:
```diff
SwapExactIn {
coin_in: Coin,
denom_out: String,
- slippage: Decimal,
+ min_receive: Uint128,
route: Option<SwapperRoute>,
}
```

## v1.2.0

- Allow Credit account to lend/reclaim to the Red Bank (calls Deposit/Withdraw in Red Bank), claim incentive rewards from lending to the Red Bank (pass account_id to track Credit Manager users in `red-bank` and `incentives` contract).
Expand Down
4 changes: 4 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions contracts/account-nft/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ cw-multi-test = { workspace = true }
mars-mock-credit-manager = { workspace = true }
mars-mock-rover-health = { workspace = true }
mars-owner = { workspace = true }
mars-testing = { workspace = true }
serde_json = { workspace = true }
6 changes: 6 additions & 0 deletions contracts/account-nft/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use mars_types::account_nft::{ExecuteMsg, InstantiateMsg, NftConfig, QueryMsg};
use crate::{
error::ContractError,
execute::{burn, mint, update_config},
migrations,
query::{query_config, query_next_id},
state::{CONFIG, NEXT_ID},
};
Expand Down Expand Up @@ -79,3 +80,8 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
_ => Parent::default().query(deps, env, msg.try_into()?),
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
migrations::v2_1_0::migrate(deps)
}
1 change: 1 addition & 0 deletions contracts/account-nft/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod contract;
pub mod error;
pub mod execute;
pub mod migrations;
pub mod query;
pub mod state;
1 change: 1 addition & 0 deletions contracts/account-nft/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod v2_1_0;
50 changes: 50 additions & 0 deletions contracts/account-nft/src/migrations/v2_1_0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use cosmwasm_std::{Addr, DepsMut, Empty, MessageInfo, Response};
use cw2::{assert_contract_version, set_contract_version};

use crate::{
contract::{Parent, CONTRACT_NAME, CONTRACT_VERSION},
error::ContractError,
};

const FROM_VERSION: &str = "2.0.0";

const CREDIT_MANAGER_CONTRACT_ADDR: &str =
"osmo1f2m24wktq0sw3c0lexlg7fv4kngwyttvzws3a3r3al9ld2s2pvds87jqvf";

/// Check Credit-Manager `config` query response:
/// {
/// ...
/// "rewards_collector": {
/// "address": "osmo1urvqe5mw00ws25yqdd4c4hlh8kdyf567mpcml7cdve9w08z0ydcqvsrgdy",
/// "account_id": "2321"
/// }
/// }
/// }
const REWARDS_COLLECTOR_CONTRACT_ADDR: &str =
"osmo1urvqe5mw00ws25yqdd4c4hlh8kdyf567mpcml7cdve9w08z0ydcqvsrgdy";
const REWARDS_COLLECTOR_ACC_ID: &str = "2321";

pub fn migrate(mut deps: DepsMut) -> 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)?;

// Create missing connection between Reward-Collector contract addr and acc id
Parent::default().mint(
deps.branch(),
MessageInfo {
sender: Addr::unchecked(CREDIT_MANAGER_CONTRACT_ADDR.to_string()),
funds: vec![],
},
REWARDS_COLLECTOR_ACC_ID.to_string(),
REWARDS_COLLECTOR_CONTRACT_ADDR.to_string(),
None,
Empty {},
)?;

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))
}
1 change: 1 addition & 0 deletions contracts/account-nft/tests/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod helpers;

mod test_burn_allowance;
mod test_instantiate;
mod test_migration_v2;
mod test_mint;
mod test_proposed_minter;
mod test_update_config;
147 changes: 147 additions & 0 deletions contracts/account-nft/tests/tests/test_migration_v2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
use cosmwasm_std::{
attr, from_json,
testing::{mock_env, mock_info},
Empty, Event,
};
use cw2::{ContractVersion, VersionError};
use cw721_base::InstantiateMsg;
use mars_account_nft::{
contract::{execute, migrate, query, Parent},
error::ContractError,
state::NEXT_ID,
};
use mars_testing::mock_dependencies;

#[test]
fn wrong_contract_name() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "contract_xyz", "2.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-account-nft".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-account-nft", "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() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-account-nft", "2.0.0")
.unwrap();

let env = mock_env();
// Credit-Manager contract address
let owner = "osmo1f2m24wktq0sw3c0lexlg7fv4kngwyttvzws3a3r3al9ld2s2pvds87jqvf";
let owner_info = mock_info(owner, &[]);

// Init counter with 1
NEXT_ID.save(deps.as_mut().storage, &1).unwrap();

// Instantiate the contract
Parent::default()
.instantiate(
deps.as_mut(),
env.clone(),
owner_info.clone(),
InstantiateMsg {
name: "mock_nft".to_string(),
symbol: "MOCK".to_string(),
minter: owner.to_string(),
},
)
.unwrap();

// Mint a random token
execute(
deps.as_mut(),
env.clone(),
owner_info.clone(),
mars_types::account_nft::ExecuteMsg::Mint {
user: "user_1".to_string(),
},
)
.unwrap();

// Move counter to 3000
NEXT_ID.save(deps.as_mut().storage, &3000).unwrap();

// Mint a random token
execute(
deps.as_mut(),
env.clone(),
owner_info.clone(),
mars_types::account_nft::ExecuteMsg::Mint {
user: "user_2".to_string(),
},
)
.unwrap();

// Check if counter is moved to 3001
let next_id = NEXT_ID.load(deps.as_ref().storage).unwrap();
assert_eq!(next_id, 3001);

// Query should fail because token_id 2321 is not minted yet
query(
deps.as_ref(),
env.clone(),
mars_types::account_nft::QueryMsg::OwnerOf {
token_id: "2321".to_string(),
include_expired: None,
},
)
.unwrap_err();

let res = migrate(deps.as_mut(), mock_env(), Empty {}).unwrap();

// Query should now return the owner of token_id 2321, which is Rewards-Collector contract address
let owner_of_res_binary = query(
deps.as_ref(),
env.clone(),
mars_types::account_nft::QueryMsg::OwnerOf {
token_id: "2321".to_string(),
include_expired: None,
},
)
.unwrap();
let owner_of_res: cw721::OwnerOfResponse = from_json(owner_of_res_binary).unwrap();
assert_eq!(
owner_of_res.owner,
"osmo1urvqe5mw00ws25yqdd4c4hlh8kdyf567mpcml7cdve9w08z0ydcqvsrgdy".to_string()
);

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.0.0"), attr("to_version", "2.1.0")]
);

let new_contract_version = ContractVersion {
contract: "crates.io:mars-account-nft".to_string(),
version: "2.1.0".to_string(),
};
assert_eq!(cw2::get_contract_version(deps.as_ref().storage).unwrap(), new_contract_version);
}
2 changes: 1 addition & 1 deletion contracts/address-provider/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,5 @@ fn query_all_addresses(

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
migrations::v2_0_0::migrate(deps)
migrations::v2_1_0::migrate(deps)
}
2 changes: 1 addition & 1 deletion contracts/address-provider/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod v2_0_0;
pub mod v2_1_0;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
error::ContractError,
};

const FROM_VERSION: &str = "1.2.0";
const FROM_VERSION: &str = "2.0.0";

pub fn migrate(deps: DepsMut) -> Result<Response, ContractError> {
// make sure we're migrating the correct contract and from the correct version
Expand Down
8 changes: 4 additions & 4 deletions contracts/address-provider/tests/tests/test_migration_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use mars_testing::mock_dependencies;
#[test]
fn wrong_contract_name() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "contract_xyz", "1.2.0").unwrap();
cw2::set_contract_version(deps.as_mut().storage, "contract_xyz", "2.0.0").unwrap();

let err = migrate(deps.as_mut(), mock_env(), Empty {}).unwrap_err();

Expand All @@ -30,7 +30,7 @@ fn wrong_contract_version() {
assert_eq!(
err,
ContractError::Version(VersionError::WrongVersion {
expected: "1.2.0".to_string(),
expected: "2.0.0".to_string(),
found: "4.1.0".to_string()
})
);
Expand All @@ -39,7 +39,7 @@ fn wrong_contract_version() {
#[test]
fn successful_migration() {
let mut deps = mock_dependencies(&[]);
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-address-provider", "1.2.0")
cw2::set_contract_version(deps.as_mut().storage, "crates.io:mars-address-provider", "2.0.0")
.unwrap();

let res = migrate(deps.as_mut(), mock_env(), Empty {}).unwrap();
Expand All @@ -49,7 +49,7 @@ fn successful_migration() {
assert!(res.data.is_none());
assert_eq!(
res.attributes,
vec![attr("action", "migrate"), attr("from_version", "1.2.0"), attr("to_version", "2.1.0")]
vec![attr("action", "migrate"), attr("from_version", "2.0.0"), attr("to_version", "2.1.0")]
);

let new_contract_version = ContractVersion {
Expand Down
Loading

0 comments on commit 06a510b

Please sign in to comment.