Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MP-2425 Burn fee collector denom rewards #428

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
68 changes: 35 additions & 33 deletions contracts/rewards-collector/base/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cosmwasm_std::{
coin, to_json_binary, Addr, Binary, Coin, CosmosMsg, CustomMsg, Deps, DepsMut, Empty, Env,
MessageInfo, Response, StdResult, Uint128, WasmMsg,
coin, coins, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, CustomMsg, Deps, DepsMut,
Empty, Env, MessageInfo, Response, StdResult, Uint128, WasmMsg,
};
use cw_storage_plus::Item;
use mars_owner::{Owner, OwnerInit::SetInitialOwner, OwnerUpdate};
Expand Down Expand Up @@ -365,43 +365,45 @@ where
) -> ContractResult<Response<M>> {
let cfg = self.config.load(deps.storage)?;

let to_address = if denom == cfg.safety_fund_denom {
address_provider::helpers::query_module_addr(
let amount_to_distribute =
unwrap_option_amount(&deps.querier, &env.contract.address, &denom, amount)?;

let response = Response::new()
.add_attribute("denom", &denom)
.add_attribute("amount", amount_to_distribute);

if denom == cfg.safety_fund_denom {
let to_address = address_provider::helpers::query_module_addr(
deps.as_ref(),
&cfg.address_provider,
MarsAddressType::SafetyFund,
)?
)?;

let transfer_msg = I::ibc_transfer_msg(
env,
to_address.clone(),
Coin {
denom: denom.clone(),
amount: amount_to_distribute,
},
cfg,
)?;

Ok(response
.add_attribute("action", "distribute_rewards")
.add_attribute("to", to_address)
.add_message(transfer_msg))
} else if denom == cfg.fee_collector_denom {
address_provider::helpers::query_module_addr(
deps.as_ref(),
&cfg.address_provider,
MarsAddressType::FeeCollector,
)?
Ok(response.add_attribute("action", "burn_rewards").add_message(CosmosMsg::Bank(
BankMsg::Burn {
amount: coins(amount_to_distribute.u128(), denom),
},
)))
} else {
return Err(ContractError::AssetNotEnabledForDistribution {
Err(ContractError::AssetNotEnabledForDistribution {
denom,
});
};

let amount_to_distribute =
unwrap_option_amount(&deps.querier, &env.contract.address, &denom, amount)?;

let transfer_msg = I::ibc_transfer_msg(
env,
to_address.clone(),
Coin {
denom: denom.clone(),
amount: amount_to_distribute,
},
cfg,
)?;

Ok(Response::new()
.add_message(transfer_msg)
.add_attribute("action", "distribute_rewards")
.add_attribute("denom", denom)
.add_attribute("amount", amount_to_distribute)
.add_attribute("to", to_address))
})
}
}

pub fn query_config(&self, deps: Deps) -> StdResult<ConfigResponse> {
Expand Down
2 changes: 1 addition & 1 deletion contracts/rewards-collector/neutron/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,6 @@ pub mod entry {

#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> ContractResult<Response> {
migrations::v2_0_0::migrate(deps)
migrations::v2_0_2::migrate(deps)
}
}
2 changes: 1 addition & 1 deletion contracts/rewards-collector/neutron/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod v2_0_0;
pub mod v2_0_2;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use cosmwasm_std::{
coin, testing::mock_env, CosmosMsg, IbcMsg, IbcTimeout, SubMsg, Timestamp, Uint128,
coin, coins, testing::mock_env, BankMsg, CosmosMsg, IbcMsg, IbcTimeout, SubMsg, Timestamp,
Uint128,
};
use mars_rewards_collector_base::ContractError;
use mars_rewards_collector_osmosis::entry::execute;
Expand Down Expand Up @@ -39,7 +40,7 @@ fn distributing_rewards() {
}))
);

// distribute umars to fee collector
// burn umars as fee collector denom
let res = execute(
deps.as_mut(),
env,
Expand All @@ -53,11 +54,8 @@ fn distributing_rewards() {
assert_eq!(res.messages.len(), 1);
assert_eq!(
res.messages[0],
SubMsg::new(CosmosMsg::Ibc(IbcMsg::Transfer {
channel_id: "channel-69".to_string(),
to_address: "fee_collector".to_string(),
amount: coin(8964, "umars"),
timeout: IbcTimeout::with_timestamp(Timestamp::from_seconds(17000300))
SubMsg::new(CosmosMsg::Bank(BankMsg::Burn {
amount: coins(8964, "umars")
}))
);

Expand Down
97 changes: 70 additions & 27 deletions integration-tests/tests/test_rewards_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ fn distribute_rewards_if_ibc_channel_invalid() {
.init_accounts(
&[
coin(1_000_000_000_000, "uusdc"),
coin(1_000_000_000_000, "umars"),
coin(1_000_000_000_000, "uosmo"), // for gas
],
2,
Expand All @@ -316,16 +315,6 @@ fn distribute_rewards_if_ibc_channel_invalid() {
prefix: "osmo".to_string(),
},
);
wasm.execute(
&addr_provider_addr,
&ExecuteMsgAddr::SetAddress {
address_type: MarsAddressType::FeeCollector,
address: "mars17xpfvakm2amg962yls6f84z3kell8c5ldy6e7x".to_string(),
},
&[],
signer,
)
.unwrap();
wasm.execute(
&addr_provider_addr,
&ExecuteMsgAddr::SetAddress {
Expand Down Expand Up @@ -360,13 +349,9 @@ fn distribute_rewards_if_ibc_channel_invalid() {
// fund rewards-collector contract
let bank = Bank::new(&app);
let usdc_funded = 800_000_000u128;
let mars_funded = 50_000_000u128;
bank.send(user, &rewards_addr, &[coin(usdc_funded, "uusdc")]).unwrap();
bank.send(user, &rewards_addr, &[coin(mars_funded, "umars")]).unwrap();
let usdc_balance = bank.query_balance(&rewards_addr, "uusdc");
assert_eq!(usdc_balance, usdc_funded);
let mars_balance = bank.query_balance(&rewards_addr, "umars");
assert_eq!(mars_balance, mars_balance);

// distribute usdc
let res = wasm
Expand Down Expand Up @@ -401,18 +386,76 @@ fn distribute_rewards_if_ibc_channel_invalid() {
signer,
)
.unwrap();
}

// distribute mars
let res = wasm
.execute(
&rewards_addr,
&ExecuteMsg::DistributeRewards {
denom: "umars".to_string(),
amount: None,
},
&[],
signer,
#[test]
fn burn_rewards() {
let app = OsmosisTestApp::new();
let wasm = Wasm::new(&app);

let accs = app
.init_accounts(
&[
coin(1_000_000_000_000, "umars"),
coin(1_000_000_000_000, "uosmo"), // for gas
],
2,
)
.unwrap_err();
assert_err(res, "port ID (transfer) channel ID (channel-1): channel not found");
.unwrap();
let signer = &accs[0];
let user = &accs[1];

// setup address-provider contract
let addr_provider_addr = instantiate_contract(
&wasm,
signer,
OSMOSIS_ADDR_PROVIDER_CONTRACT_NAME,
&InstantiateAddr {
owner: signer.address(),
prefix: "osmo".to_string(),
},
);

// setup rewards-collector contract
let safety_fund_denom = "uusdc";
let fee_collector_denom = "umars";
let rewards_addr = instantiate_contract(
&wasm,
signer,
OSMOSIS_REWARDS_CONTRACT_NAME,
&InstantiateRewards {
owner: signer.address(),
address_provider: addr_provider_addr,
safety_tax_rate: Decimal::percent(50),
safety_fund_denom: safety_fund_denom.to_string(),
fee_collector_denom: fee_collector_denom.to_string(),
channel_id: "".to_string(),
timeout_seconds: 60,
slippage_tolerance: Decimal::percent(1),
neutron_ibc_config: None,
},
);

// fund rewards-collector contract
let bank = Bank::new(&app);
let mars_funded = 50_000_000u128;
bank.send(user, &rewards_addr, &[coin(mars_funded, "umars")]).unwrap();
let mars_balance = bank.query_balance(&rewards_addr, "umars");
assert_eq!(mars_balance, mars_funded);

// since umars is the fee denom, the umars should be burnt
wasm.execute(
&rewards_addr,
&ExecuteMsg::DistributeRewards {
denom: "umars".to_string(),
amount: None,
},
&[],
signer,
)
.unwrap();

// assert the rewards collector balance of umars is 0 to confirm umars has been burnt
let mars_balance = bank.query_balance(&rewards_addr, "umars");
assert_eq!(mars_balance, 0);
}
13 changes: 3 additions & 10 deletions packages/types/src/address_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,14 @@ pub enum MarsAddressType {
RewardsCollector,
Params,
CreditManager,
/// Protocol admin is an ICS-27 interchain account controlled by Mars Hub's x/gov module.
/// This account will take the owner and admin roles of red-bank contracts.
/// Protocol admin is a Mars Hubs governance smart contract instance,
/// or ICS-27 interchain account controlled by Mars Hubs governance instance.
/// This account will take the owner and admin roles of Mars Protocol contracts.
///
/// Owner means the account who can invoke certain priviliged execute methods on a contract,
/// such as updating the config.
/// Admin means the account who can migrate a contract.
ProtocolAdmin,
/// The `fee_collector` module account controlled by Mars Hub's x/distribution module.
/// Funds sent to this account will be distributed as staking rewards.
///
/// NOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized
/// by the `api.addr_validate` method.
FeeCollector,
/// The module account controlled by the by Mars Hub's x/safety module.
/// Funds sent to this account will be deposited into the safety fund.
///
Expand All @@ -43,7 +38,6 @@ impl fmt::Display for MarsAddressType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
MarsAddressType::CreditManager => "credit_manager",
MarsAddressType::FeeCollector => "fee_collector",
MarsAddressType::Incentives => "incentives",
MarsAddressType::Oracle => "oracle",
MarsAddressType::Params => "params",
Expand All @@ -64,7 +58,6 @@ impl FromStr for MarsAddressType {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"credit_manager" => Ok(MarsAddressType::CreditManager),
"fee_collector" => Ok(MarsAddressType::FeeCollector),
"incentives" => Ok(MarsAddressType::Incentives),
"oracle" => Ok(MarsAddressType::Oracle),
"params" => Ok(MarsAddressType::Params),
Expand Down
45 changes: 5 additions & 40 deletions schemas/mars-address-provider/mars-address-provider.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,12 @@
]
},
{
"description": "Protocol admin is an ICS-27 interchain account controlled by Mars Hub's x/gov module. This account will take the owner and admin roles of red-bank contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"description": "Protocol admin is a Mars Hubs governance smart contract instance, or ICS-27 interchain account controlled by Mars Hubs governance instance. This account will take the owner and admin roles of Mars Protocol contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"type": "string",
"enum": [
"protocol_admin"
]
},
{
"description": "The `fee_collector` module account controlled by Mars Hub's x/distribution module. Funds sent to this account will be distributed as staking rewards.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
"enum": [
"fee_collector"
]
},
{
"description": "The module account controlled by the by Mars Hub's x/safety module. Funds sent to this account will be deposited into the safety fund.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
Expand Down Expand Up @@ -293,19 +286,12 @@
]
},
{
"description": "Protocol admin is an ICS-27 interchain account controlled by Mars Hub's x/gov module. This account will take the owner and admin roles of red-bank contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"description": "Protocol admin is a Mars Hubs governance smart contract instance, or ICS-27 interchain account controlled by Mars Hubs governance instance. This account will take the owner and admin roles of Mars Protocol contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"type": "string",
"enum": [
"protocol_admin"
]
},
{
"description": "The `fee_collector` module account controlled by Mars Hub's x/distribution module. Funds sent to this account will be distributed as staking rewards.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
"enum": [
"fee_collector"
]
},
{
"description": "The module account controlled by the by Mars Hub's x/safety module. Funds sent to this account will be deposited into the safety fund.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
Expand Down Expand Up @@ -372,19 +358,12 @@
]
},
{
"description": "Protocol admin is an ICS-27 interchain account controlled by Mars Hub's x/gov module. This account will take the owner and admin roles of red-bank contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"description": "Protocol admin is a Mars Hubs governance smart contract instance, or ICS-27 interchain account controlled by Mars Hubs governance instance. This account will take the owner and admin roles of Mars Protocol contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"type": "string",
"enum": [
"protocol_admin"
]
},
{
"description": "The `fee_collector` module account controlled by Mars Hub's x/distribution module. Funds sent to this account will be distributed as staking rewards.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
"enum": [
"fee_collector"
]
},
{
"description": "The module account controlled by the by Mars Hub's x/safety module. Funds sent to this account will be deposited into the safety fund.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
Expand Down Expand Up @@ -454,19 +433,12 @@
]
},
{
"description": "Protocol admin is an ICS-27 interchain account controlled by Mars Hub's x/gov module. This account will take the owner and admin roles of red-bank contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"description": "Protocol admin is a Mars Hubs governance smart contract instance, or ICS-27 interchain account controlled by Mars Hubs governance instance. This account will take the owner and admin roles of Mars Protocol contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"type": "string",
"enum": [
"protocol_admin"
]
},
{
"description": "The `fee_collector` module account controlled by Mars Hub's x/distribution module. Funds sent to this account will be distributed as staking rewards.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
"enum": [
"fee_collector"
]
},
{
"description": "The module account controlled by the by Mars Hub's x/safety module. Funds sent to this account will be deposited into the safety fund.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
Expand Down Expand Up @@ -536,19 +508,12 @@
]
},
{
"description": "Protocol admin is an ICS-27 interchain account controlled by Mars Hub's x/gov module. This account will take the owner and admin roles of red-bank contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"description": "Protocol admin is a Mars Hubs governance smart contract instance, or ICS-27 interchain account controlled by Mars Hubs governance instance. This account will take the owner and admin roles of Mars Protocol contracts.\n\nOwner means the account who can invoke certain priviliged execute methods on a contract, such as updating the config. Admin means the account who can migrate a contract.",
"type": "string",
"enum": [
"protocol_admin"
]
},
{
"description": "The `fee_collector` module account controlled by Mars Hub's x/distribution module. Funds sent to this account will be distributed as staking rewards.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
"enum": [
"fee_collector"
]
},
{
"description": "The module account controlled by the by Mars Hub's x/safety module. Funds sent to this account will be deposited into the safety fund.\n\nNOTE: This is a Mars Hub address with the `mars` bech32 prefix, which may not be recognized by the `api.addr_validate` method.",
"type": "string",
Expand Down
Loading
Loading