Skip to content

Commit

Permalink
Migration to add LunaX as collateral (#88)
Browse files Browse the repository at this point in the history
* Add LunaX as collateral to mirror protocol (#87)

* revert mint contract to v2.1.1

* revert factory and col oracle to 2.1.1 + add lunax to 2.1.1 col oracle

* adapt collector for lunax and prepare migration

* register LunaX collateral on migration

* fix clippy

* add input validation to col_oracle migration

Co-authored-by: Bharath Vedartham <vedabharath12345@gmail.com>
  • Loading branch information
csanti and bharath-123 authored Feb 3, 2022
1 parent d2bffaf commit 97cabc2
Show file tree
Hide file tree
Showing 42 changed files with 1,156 additions and 709 deletions.
3 changes: 1 addition & 2 deletions contracts/mirror_collateral_oracle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mirror-collateral-oracle"
version = "2.1.1"
version = "2.1.2"
authors = ["Terraform Labs, PTE."]
edition = "2018"
description = "A proxy oracle for collaterals in Mirror Protocol"
Expand Down Expand Up @@ -37,7 +37,6 @@ backtraces = ["cosmwasm-std/backtraces"]
cosmwasm-std = { version = "0.16.0", features = ["iterator"] }
cosmwasm-storage = { version = "0.16.0", features = ["iterator"] }
mirror-protocol = { version = "2.1.1", path = "../../packages/mirror_protocol" }
tefi-oracle = { version = "0.1.0", path = "../../packages/tefi_oracle" }
schemars = "0.8.1"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
terraswap = "2.4.0"
Expand Down
85 changes: 70 additions & 15 deletions contracts/mirror_collateral_oracle/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::migration::{migrate_collateral_infos, migrate_config};
use crate::migration::migrate_collateral_infos;
use crate::querier::query_price;
use crate::state::{
read_collateral_info, read_collateral_infos, read_config, store_collateral_info, store_config,
Expand Down Expand Up @@ -29,6 +29,9 @@ pub fn instantiate(
owner: deps.api.addr_canonicalize(&msg.owner)?,
mint_contract: deps.api.addr_canonicalize(&msg.mint_contract)?,
base_denom: msg.base_denom,
mirror_oracle: deps.api.addr_canonicalize(&msg.mirror_oracle)?,
anchor_oracle: deps.api.addr_canonicalize(&msg.anchor_oracle)?,
band_oracle: deps.api.addr_canonicalize(&msg.band_oracle)?,
},
)?;

Expand All @@ -47,7 +50,19 @@ pub fn execute(
owner,
mint_contract,
base_denom,
} => update_config(deps, info, owner, mint_contract, base_denom),
mirror_oracle,
anchor_oracle,
band_oracle,
} => update_config(
deps,
info,
owner,
mint_contract,
base_denom,
mirror_oracle,
anchor_oracle,
band_oracle,
),
ExecuteMsg::RegisterCollateralAsset {
asset,
price_source,
Expand All @@ -71,6 +86,9 @@ pub fn update_config(
owner: Option<String>,
mint_contract: Option<String>,
base_denom: Option<String>,
mirror_oracle: Option<String>,
anchor_oracle: Option<String>,
band_oracle: Option<String>,
) -> StdResult<Response> {
let mut config: Config = read_config(deps.storage)?;
if deps.api.addr_canonicalize(info.sender.as_str())? != config.owner {
Expand All @@ -89,6 +107,18 @@ pub fn update_config(
config.base_denom = base_denom;
}

if let Some(mirror_oracle) = mirror_oracle {
config.mirror_oracle = deps.api.addr_canonicalize(&mirror_oracle)?;
}

if let Some(anchor_oracle) = anchor_oracle {
config.anchor_oracle = deps.api.addr_canonicalize(&anchor_oracle)?;
}

if let Some(band_oracle) = band_oracle {
config.band_oracle = deps.api.addr_canonicalize(&band_oracle)?;
}

store_config(deps.storage, &config)?;
Ok(Response::default())
}
Expand Down Expand Up @@ -212,12 +242,13 @@ pub fn update_collateral_multiplier(
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::Config {} => to_binary(&query_config(deps)?),
QueryMsg::CollateralPrice { asset, timeframe } => {
to_binary(&query_collateral_price(deps, env, asset, timeframe)?)
}
QueryMsg::CollateralPrice {
asset,
block_height,
} => to_binary(&query_collateral_price(deps, asset, block_height)?),
QueryMsg::CollateralAssetInfo { asset } => to_binary(&query_collateral_info(deps, asset)?),
QueryMsg::CollateralAssetInfos {} => to_binary(&query_collateral_infos(deps)?),
}
Expand All @@ -229,16 +260,18 @@ pub fn query_config(deps: Deps) -> StdResult<ConfigResponse> {
owner: deps.api.addr_humanize(&config.owner)?.to_string(),
mint_contract: deps.api.addr_humanize(&config.mint_contract)?.to_string(),
base_denom: config.base_denom,
mirror_oracle: deps.api.addr_humanize(&config.mirror_oracle)?.to_string(),
anchor_oracle: deps.api.addr_humanize(&config.anchor_oracle)?.to_string(),
band_oracle: deps.api.addr_humanize(&config.band_oracle)?.to_string(),
};

Ok(resp)
}

pub fn query_collateral_price(
deps: Deps,
env: Env,
quote_asset: String,
timeframe: Option<u64>,
block_height: Option<u64>,
) -> StdResult<CollateralPriceResponse> {
let config: Config = read_config(deps.storage)?;

Expand All @@ -251,10 +284,9 @@ pub fn query_collateral_price(

let (price, last_updated): (Decimal, u64) = query_price(
deps,
env,
&config,
&quote_asset,
timeframe,
block_height,
&collateral.price_source,
)?;

Expand Down Expand Up @@ -291,12 +323,35 @@ pub fn query_collateral_infos(deps: Deps) -> StdResult<CollateralInfosResponse>

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult<Response> {
migrate_config(deps.storage)?;
// migrate collateral infos to inclue new source type
migrate_collateral_infos(deps.storage)?;

migrate_collateral_infos(
deps.storage,
msg.mirror_tefi_oracle_addr,
msg.anchor_tefi_oracle_addr,
// validate input
deps.api.addr_validate(&msg.lunax_staking_contract)?;
deps.api.addr_validate(&msg.lunax_token_addr)?;
if msg.multiplier.is_zero() {
return Err(StdError::generic_err("Multiplier must be bigger than 0"));
}

// register lunax
let lunax_asset_info = AssetInfo::Token {
contract_addr: msg.lunax_token_addr,
};
let lunax_source = SourceType::Lunax {
staking_contract_addr: msg.lunax_staking_contract,
};

let config: Config = read_config(deps.storage)?;
let self_info = MessageInfo {
sender: deps.api.addr_humanize(&config.owner)?,
funds: vec![],
};
register_collateral(
deps,
self_info,
lunax_asset_info,
lunax_source,
msg.multiplier,
)?;

Ok(Response::default())
Expand Down
152 changes: 9 additions & 143 deletions contracts/mirror_collateral_oracle/src/migration.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
use cosmwasm_storage::{singleton, singleton_read, Bucket, ReadonlySingleton, Singleton};
use cosmwasm_storage::Bucket;
use mirror_protocol::collateral_oracle::SourceType;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use cosmwasm_std::{CanonicalAddr, Decimal, Order, StdError, StdResult, Storage};
use cosmwasm_std::{Decimal, Order, StdResult, Storage};

use crate::state::{CollateralAssetInfo, Config, KEY_CONFIG, PREFIX_COLLATERAL_ASSET_INFO};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct LegacyConfig {
pub owner: CanonicalAddr,
pub mint_contract: CanonicalAddr,
pub base_denom: String,
pub mirror_oracle: CanonicalAddr,
pub anchor_oracle: CanonicalAddr,
pub band_oracle: CanonicalAddr,
}
use crate::state::{CollateralAssetInfo, PREFIX_COLLATERAL_ASSET_INFO};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct LegacyCollateralAssetInfo {
Expand Down Expand Up @@ -46,24 +36,7 @@ pub enum LegacySourceType {
},
}

pub fn migrate_config(storage: &mut dyn Storage) -> StdResult<()> {
let legacty_store: ReadonlySingleton<LegacyConfig> = singleton_read(storage, KEY_CONFIG);
let legacy_config: LegacyConfig = legacty_store.load()?;
let config = Config {
owner: legacy_config.owner,
mint_contract: legacy_config.mint_contract,
base_denom: legacy_config.base_denom,
};
let mut store: Singleton<Config> = singleton(storage, KEY_CONFIG);
store.save(&config)?;
Ok(())
}

pub fn migrate_collateral_infos(
storage: &mut dyn Storage,
mirror_tefi_oracle_addr: String,
anchor_tefi_oracle_addr: String,
) -> StdResult<()> {
pub fn migrate_collateral_infos(storage: &mut dyn Storage) -> StdResult<()> {
let mut legacy_collateral_infos_bucket: Bucket<LegacyCollateralAssetInfo> =
Bucket::new(storage, PREFIX_COLLATERAL_ASSET_INFO);

Expand All @@ -82,15 +55,9 @@ pub fn migrate_collateral_infos(

for (_, legacy_collateral_info) in collateral_infos.into_iter() {
let new_price_source: SourceType = match legacy_collateral_info.price_source {
LegacySourceType::BandOracle { .. } => {
return Err(StdError::generic_err("not supported"))
} // currently there are no assets with this config
LegacySourceType::AnchorOracle { .. } => SourceType::TeFiOracle {
oracle_addr: anchor_tefi_oracle_addr.clone(),
},
LegacySourceType::MirrorOracle { .. } => SourceType::TeFiOracle {
oracle_addr: mirror_tefi_oracle_addr.clone(),
},
LegacySourceType::BandOracle {} => SourceType::BandOracle {},
LegacySourceType::AnchorOracle {} => SourceType::AnchorOracle {},
LegacySourceType::MirrorOracle {} => SourceType::MirrorOracle {},
LegacySourceType::AnchorMarket { anchor_market_addr } => {
SourceType::AnchorMarket { anchor_market_addr }
}
Expand All @@ -99,8 +66,8 @@ pub fn migrate_collateral_infos(
LegacySourceType::Terraswap {
terraswap_pair_addr,
intermediate_denom,
} => SourceType::AMMPair {
pair_addr: terraswap_pair_addr,
} => SourceType::Terraswap {
terraswap_pair_addr,
intermediate_denom,
},
};
Expand All @@ -116,104 +83,3 @@ pub fn migrate_collateral_infos(

Ok(())
}

#[cfg(test)]
mod migrate_tests {
use crate::state::read_collateral_info;

use super::*;
use cosmwasm_std::testing::mock_dependencies;

pub fn collateral_infos_old_store(
storage: &mut dyn Storage,
) -> Bucket<LegacyCollateralAssetInfo> {
Bucket::new(storage, PREFIX_COLLATERAL_ASSET_INFO)
}

#[test]
fn test_collateral_infos_migration() {
let mut deps = mock_dependencies(&[]);
let mut legacy_store = collateral_infos_old_store(&mut deps.storage);

let col_info_1 = LegacyCollateralAssetInfo {
asset: "mAPPL0000".to_string(),
multiplier: Decimal::one(),
price_source: LegacySourceType::MirrorOracle {},
is_revoked: false,
};
let col_info_2 = LegacyCollateralAssetInfo {
asset: "anc0000".to_string(),
multiplier: Decimal::one(),
price_source: LegacySourceType::Terraswap {
terraswap_pair_addr: "pair0000".to_string(),
intermediate_denom: None,
},
is_revoked: false,
};
let col_info_3 = LegacyCollateralAssetInfo {
asset: "bluna0000".to_string(),
multiplier: Decimal::one(),
price_source: LegacySourceType::AnchorOracle {},
is_revoked: false,
};

legacy_store
.save(col_info_1.asset.as_bytes(), &col_info_1)
.unwrap();
legacy_store
.save(col_info_2.asset.as_bytes(), &col_info_2)
.unwrap();
legacy_store
.save(col_info_3.asset.as_bytes(), &col_info_3)
.unwrap();

migrate_collateral_infos(
deps.as_mut().storage,
"mirrortefi0000".to_string(),
"anctefi0000".to_string(),
)
.unwrap();

let new_col_info_1: CollateralAssetInfo =
read_collateral_info(deps.as_mut().storage, &col_info_1.asset).unwrap();
let new_col_info_2: CollateralAssetInfo =
read_collateral_info(deps.as_mut().storage, &col_info_2.asset).unwrap();
let new_col_info_3: CollateralAssetInfo =
read_collateral_info(deps.as_mut().storage, &col_info_3.asset).unwrap();

assert_eq!(
new_col_info_1,
CollateralAssetInfo {
asset: "mAPPL0000".to_string(),
multiplier: Decimal::one(),
price_source: SourceType::TeFiOracle {
oracle_addr: "mirrortefi0000".to_string(),
},
is_revoked: false,
}
);
assert_eq!(
new_col_info_2,
CollateralAssetInfo {
asset: "anc0000".to_string(),
multiplier: Decimal::one(),
price_source: SourceType::AMMPair {
pair_addr: "pair0000".to_string(),
intermediate_denom: None,
},
is_revoked: false,
}
);
assert_eq!(
new_col_info_3,
CollateralAssetInfo {
asset: "bluna0000".to_string(),
multiplier: Decimal::one(),
price_source: SourceType::TeFiOracle {
oracle_addr: "anctefi0000".to_string(),
},
is_revoked: false,
}
)
}
}
Loading

0 comments on commit 97cabc2

Please sign in to comment.