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

store MASP total rewards #3375

Merged
merged 4 commits into from
Jul 5, 2024
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 .changelog/unreleased/bug-fixes/3375-masp-total-rewards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Update native token total supply with MASP rewards.
([\#3375](https://github.com/anoma/namada/pull/3375))
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/3375-masp-total-rewards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Store total MASP rewards and print them in the conversions query.
([\#3375](https://github.com/anoma/namada/pull/3375))
13 changes: 13 additions & 0 deletions crates/apps_lib/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,19 @@ pub async fn query_conversions(
) {
// The chosen token type of the conversions
let target_token = args.token;

if target_token.as_ref().is_none() {
// Query and print the total rewards first
let total_rewards = rpc::query_masp_total_rewards(context.client())
.await
.expect("MASP total rewards should be present");
display!(
context.io(),
"Total rewards of native token minted for shielded pool: {}",
total_rewards.to_string_native()
);
}

// To facilitate human readable token addresses
let tokens = context
.wallet()
Expand Down
25 changes: 24 additions & 1 deletion crates/sdk/src/queries/vp/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub mod client_only_methods {
use borsh::BorshDeserialize;
use namada_core::address::Address;
use namada_core::token;
use namada_token::storage_key::balance_key;
use namada_token::storage_key::{balance_key, masp_total_rewards};

use super::Token;
use crate::queries::{Client, RPC};
Expand Down Expand Up @@ -79,5 +79,28 @@ pub mod client_only_methods {
};
Ok(balance)
}

/// Get the total rewards minted by MASP.
pub async fn masp_total_rewards<CLIENT>(
&self,
client: &CLIENT,
) -> Result<token::Amount, <CLIENT as Client>::Error>
where
CLIENT: Client + Sync,
{
let total_rewards_key = masp_total_rewards();
let response = RPC
.shell()
.storage_value(client, None, None, false, &total_rewards_key)
.await?;

let tokens = if response.data.is_empty() {
token::Amount::zero()
} else {
token::Amount::try_from_slice(&response.data)
.unwrap_or_default()
};
Ok(tokens)
}
}
}
7 changes: 7 additions & 0 deletions crates/sdk/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@ pub async fn query_conversions<C: crate::queries::Client + Sync>(
convert_response::<C, _>(RPC.shell().read_conversions(client).await)
}

/// Query the total rewards minted by MASP
pub async fn query_masp_total_rewards<C: crate::queries::Client + Sync>(
client: &C,
) -> Result<token::Amount, error::Error> {
convert_response::<C, _>(RPC.vp().token().masp_total_rewards(client).await)
}

/// Query to read the tokens that earn masp rewards.
pub async fn query_masp_reward_tokens<C: crate::queries::Client + Sync>(
client: &C,
Expand Down
11 changes: 4 additions & 7 deletions crates/shielded_token/src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,14 @@ where
use namada_parameters as parameters;
use namada_storage::conversion_state::ConversionLeaf;
use namada_storage::{Error, OptionExt, ResultExt};
use namada_trans_token::storage_key::balance_key;
use namada_trans_token::{MaspDigitPos, NATIVE_MAX_DECIMAL_PLACES};
use rayon::iter::{
IndexedParallelIterator, IntoParallelIterator, ParallelIterator,
};
use rayon::prelude::ParallelSlice;

use crate::mint_rewards;

// The derived conversions will be placed in MASP address space
let masp_addr = MASP;

Expand Down Expand Up @@ -566,12 +567,8 @@ where

// Update the MASP's transparent reward token balance to ensure that it
// is sufficiently backed to redeem rewards
let reward_key = balance_key(&native_token, &masp_addr);
let addr_bal: Amount = storage.read(&reward_key)?.unwrap_or_default();
let new_bal = addr_bal
.checked_add(total_reward)
.ok_or_else(|| Error::new_const("Balance with reward overflow"))?;
storage.write(&reward_key, new_bal)?;
mint_rewards(storage, total_reward)?;

// Try to distribute Merkle tree construction as evenly as possible
// across multiple cores
// Merkle trees must have exactly 2^n leaves to be mergeable
Expand Down
31 changes: 30 additions & 1 deletion crates/shielded_token/src/storage.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use namada_core::address::Address;
use namada_core::address::{self, Address};
use namada_core::arith::checked;
use namada_core::token;
use namada_core::token::Amount;
use namada_core::uint::Uint;
use namada_storage as storage;
use namada_storage::{StorageRead, StorageWrite};
use namada_trans_token::credit_tokens;
use storage::ResultExt;

use crate::storage_key::*;
Expand Down Expand Up @@ -40,3 +41,31 @@ where
storage.write(&masp_locked_amount_target_key(address), raw_target)?;
Ok(())
}

/// Mint MASP rewards tokens and increment the stored total rewards.
pub fn mint_rewards<S>(
storage: &mut S,
amount: token::Amount,
) -> storage::Result<()>
where
S: StorageRead + StorageWrite,
{
let native_token = storage.get_native_token()?;
credit_tokens(storage, &native_token, &address::MASP, amount)?;

let total_rewards_key = masp_total_rewards();
let mut total_rewards = read_total_rewards(storage)?;
checked!(total_rewards += amount)?;
storage.write(&total_rewards_key, total_rewards)
}

/// Read the total rewards minted by MASP.
pub fn read_total_rewards<S>(storage: &S) -> storage::Result<token::Amount>
where
S: StorageRead,
{
let total_rewards_key = masp_total_rewards();
let total_rewards: token::Amount =
storage.read(&total_rewards_key)?.unwrap_or_default();
Ok(total_rewards)
}
9 changes: 9 additions & 0 deletions crates/shielded_token/src/storage_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub const MASP_KD_GAIN_KEY: &str = "derivative_gain";
pub const MASP_LOCKED_AMOUNT_TARGET_KEY: &str = "locked_amount_target";
/// The key for the max reward rate for a given asset
pub const MASP_MAX_REWARD_RATE_KEY: &str = "max_reward_rate";
/// The key for the total inflation rewards minted by MASP
pub const MASP_TOTAL_REWARDS: &str = "max_total_rewards";

/// Obtain the nominal proportional key for the given token
pub fn masp_kp_gain_key(token_addr: &Address) -> storage::Key {
Expand Down Expand Up @@ -163,3 +165,10 @@ pub fn masp_assets_hash_key() -> storage::Key {
.push(&MASP_ASSETS_HASH_KEY.to_owned())
.expect("Cannot obtain a storage key")
}

/// The max reward rate key for the given token
pub fn masp_total_rewards() -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_TOTAL_REWARDS.to_owned())
.expect("Cannot obtain a storage key")
}
Loading