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: 2 additions & 0 deletions contracts/oracle/osmosis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ doctest = false
backtraces = ["cosmwasm-std/backtraces"]

[dependencies]
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
cw2 = { workspace = true }
cw-storage-plus = { workspace = true }
mars-owner = { workspace = true }
mars-oracle-base = { workspace = true }
mars-osmosis = { workspace = true }
mars-red-bank-types = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion contracts/oracle/osmosis/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ pub mod entry {

#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> ContractResult<Response> {
migrations::v1_0_0::migrate(deps)
migrations::v1_0_1::migrate(deps)
}
}
103 changes: 99 additions & 4 deletions contracts/oracle/osmosis/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/// Migration logic for Oracle contract with version: 1.0.0
pub mod v1_0_0 {
/// Migration logic for Oracle contract with version: 1.0.1
pub mod v1_0_1 {
use cosmwasm_std::{DepsMut, Response};
use mars_oracle_base::ContractResult;
use mars_owner::{Owner, OwnerInit};

use crate::contract::{CONTRACT_NAME, CONTRACT_VERSION};

Expand All @@ -11,6 +12,25 @@ pub mod v1_0_0 {
// make sure we're migrating the correct contract and from the correct version
cw2::assert_contract_version(deps.as_ref().storage, CONTRACT_NAME, FROM_VERSION)?;

// map old owner struct to new one
let old_owner = old_state::OWNER.load(deps.storage)?;
let owner = match old_owner {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this throw here when it's not B or C?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea is that we know for sure mainnet is not in the other states. Otherwise it would raise in runtime anyway. Though, this is an argument that we should just import the old package so it forces us to pattern match on all of the possibilities.

old_state::OwnerState::B(state) => state.owner.to_string(),
old_state::OwnerState::C(state) => state.owner.to_string(),
};

// clear old owner state
old_state::OWNER.remove(deps.storage);

// initalize owner with new struct
Owner::new("owner").initialize(
deps.storage,
deps.api,
OwnerInit::SetInitialOwner {
owner,
},
)?;

// update contract version
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

Expand All @@ -20,18 +40,60 @@ pub mod v1_0_0 {
.add_attribute("to_version", CONTRACT_VERSION))
}

pub mod old_state {
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use cw_storage_plus::Item;

pub const OWNER: Item<OwnerState> = Item::new("owner");

/// Old OwnerState variants:
/// A(OwnerUninitialized)
/// B(OwnerSetNoneProposed)
/// C(OwnerSetWithProposed)
/// D(OwnerRoleAbolished)
///
/// Oracle contract can be in B or C state. Emergency owner is not supported for this contract.
/// We can only read `owner` value and omit `proposed` if exist.
#[cw_serde]
pub enum OwnerState {
B(OwnerSetNoneProposed),
C(OwnerSetWithProposed),
}

#[cw_serde]
pub struct OwnerSetNoneProposed {
pub owner: Addr,
}

#[cw_serde]
pub struct OwnerSetWithProposed {
pub owner: Addr,
}
}

#[cfg(test)]
mod tests {
use cosmwasm_std::{attr, testing::mock_dependencies};
use cosmwasm_std::{attr, testing::mock_dependencies, Addr};

use super::*;
use crate::migrations::v1_0_1::old_state::{OwnerSetNoneProposed, OwnerSetWithProposed};

#[test]
fn proper_migration() {
fn migration_owner_from_state_b() {
let mut deps = mock_dependencies();

cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, FROM_VERSION).unwrap();

old_state::OWNER
.save(
deps.as_mut().storage,
&old_state::OwnerState::B(OwnerSetNoneProposed {
owner: Addr::unchecked("xyz"),
}),
)
.unwrap();

let res = migrate(deps.as_mut()).unwrap();
assert_eq!(res.messages, vec![]);
assert_eq!(
Expand All @@ -42,6 +104,39 @@ pub mod v1_0_0 {
attr("to_version", "1.1.0")
]
);

let new_owner = Owner::new("owner").query(&deps.storage).unwrap();
assert_eq!(new_owner.owner.unwrap(), "xyz".to_string());
}

#[test]
fn migration_owner_from_state_c() {
let mut deps = mock_dependencies();

cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, FROM_VERSION).unwrap();

old_state::OWNER
.save(
deps.as_mut().storage,
&old_state::OwnerState::C(OwnerSetWithProposed {
owner: Addr::unchecked("xyz"),
}),
)
.unwrap();

let res = migrate(deps.as_mut()).unwrap();
assert_eq!(res.messages, vec![]);
assert_eq!(
res.attributes,
vec![
attr("action", "migrate"),
attr("from_version", "1.0.1"),
attr("to_version", "1.1.0")
]
);

let new_owner = Owner::new("owner").query(&deps.storage).unwrap();
assert_eq!(new_owner.owner.unwrap(), "xyz".to_string());
}
}
}