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

fix: only award redeem premium upto the secure threshold #1201

Merged
merged 20 commits into from
Jan 3, 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 Cargo.lock

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

17 changes: 16 additions & 1 deletion crates/fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,24 @@ impl<T: Config> Pallet<T> {
///
/// * `amount` - amount in collateral (at current exchange rate)
pub fn get_premium_redeem_fee(amount: &Amount<T>) -> Result<Amount<T>, DispatchError> {
amount.checked_rounded_mul(&<PremiumRedeemFee<T>>::get(), Rounding::NearestPrefUp)
amount.checked_rounded_mul(&<PremiumRedeemFee<T>>::get(), Rounding::Down)
}

/// Get the premium redeem reward rate.
///
/// # Returns
/// Returns the premium redeem reward rate.
pub fn premium_redeem_reward_rate() -> UnsignedFixedPoint<T> {
<PremiumRedeemFee<T>>::get()
}

/// Get the fee share that users need to pay to redeem tokens.
///
/// # Returns
/// Returns the redeem fee.
pub fn get_redeem_fee_value() -> UnsignedFixedPoint<T> {
<RedeemFee<T>>::get()
}
/// Calculate punishment fee for a Vault that fails to execute a redeem
/// request before the expiry.
///
Expand Down
2 changes: 1 addition & 1 deletion crates/fee/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use scale_info::TypeInfo;

pub(crate) type BalanceOf<T> = <T as currency::Config>::Balance;

pub(crate) type UnsignedFixedPoint<T> = <T as currency::Config>::UnsignedFixedPoint;
pub type UnsignedFixedPoint<T> = <T as currency::Config>::UnsignedFixedPoint;

pub(crate) type DefaultVaultId<T> = VaultId<<T as frame_system::Config>::AccountId, CurrencyId<T>>;

Expand Down
2 changes: 1 addition & 1 deletion crates/issue/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub(crate) mod vault_registry {
}

pub fn ensure_not_banned<T: crate::Config>(vault_id: &DefaultVaultId<T>) -> DispatchResult {
<vault_registry::Pallet<T>>::_ensure_not_banned(vault_id)
<vault_registry::Pallet<T>>::ensure_not_banned(vault_id)
}

pub fn decrease_to_be_issued_tokens<T: crate::Config>(
Expand Down
3 changes: 3 additions & 0 deletions crates/redeem/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkad
sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31" }
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31" }
redeem-rpc-runtime-api = { path = "runtime-api" }

[dependencies.oracle-rpc-runtime-api]
path = '../../oracle/rpc/runtime-api'
4 changes: 4 additions & 0 deletions crates/redeem/rpc/runtime-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ frame-support = { git = "https://github.com/paritytech/substrate", branch = "pol
sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }
sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }

[dependencies.oracle-rpc-runtime-api]
default-features = false
path = '../../../oracle/rpc/runtime-api'

[features]
default = ["std"]
std = [
Expand Down
9 changes: 8 additions & 1 deletion crates/redeem/rpc/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
#![cfg_attr(not(feature = "std"), no_std)]

use codec::Codec;
use frame_support::dispatch::DispatchError;
use oracle_rpc_runtime_api::BalanceWrapper;
use sp_std::vec::Vec;

sp_api::decl_runtime_apis! {
pub trait RedeemApi<AccountId, H256, RedeemRequest> where
pub trait RedeemApi<VaultId, Balance, AccountId, H256, RedeemRequest> where
VaultId: Codec,
Balance: Codec,
AccountId: Codec,
H256: Codec,
RedeemRequest: Codec,
Expand All @@ -16,5 +20,8 @@ sp_api::decl_runtime_apis! {

/// Get all redeem requests for a particular vault
fn get_vault_redeem_requests(vault_id: AccountId) -> Vec<H256>;

/// Get all vaults below the premium redeem threshold, ordered in descending order of this amount
fn get_premium_redeem_vaults() -> Result<Vec<(VaultId, BalanceWrapper<Balance>)>, DispatchError>;
}
}
41 changes: 36 additions & 5 deletions crates/redeem/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,36 @@ use jsonrpsee::{
proc_macros::rpc,
types::error::{CallError, ErrorCode, ErrorObject},
};
use oracle_rpc_runtime_api::BalanceWrapper;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_runtime::traits::Block as BlockT;
use sp_runtime::{
traits::{Block as BlockT, MaybeDisplay, MaybeFromStr},
DispatchError,
};
use std::sync::Arc;

pub use redeem_rpc_runtime_api::RedeemApi as RedeemRuntimeApi;

fn handle_response<T, E: std::fmt::Debug>(result: Result<Result<T, DispatchError>, E>, msg: String) -> RpcResult<T> {
result
.map_err(|err| internal_err(format!("Runtime error: {:?}: {:?}", msg, err)))?
.map_err(|err| internal_err(format!("Execution error: {:?}: {:?}", msg, err)))
}

#[rpc(client, server)]
pub trait RedeemApi<BlockHash, AccountId, H256, RedeemRequest> {
pub trait RedeemApi<BlockHash, VaultId, Balance, AccountId, H256, RedeemRequest>
where
Balance: Codec + MaybeDisplay + MaybeFromStr,
{
#[method(name = "redeem_getRedeemRequests")]
fn get_redeem_requests(&self, account_id: AccountId, at: Option<BlockHash>) -> RpcResult<Vec<H256>>;

#[method(name = "redeem_getVaultRedeemRequests")]
fn get_vault_redeem_requests(&self, vault_id: AccountId, at: Option<BlockHash>) -> RpcResult<Vec<H256>>;

#[method(name = "redeem_getPremiumRedeemVaults", aliases = ["vaultRegistry_getPremiumRedeemVaults"])]
fn get_premium_redeem_vaults(&self, at: Option<BlockHash>) -> RpcResult<Vec<(VaultId, BalanceWrapper<Balance>)>>;
}

fn internal_err<T: ToString>(message: T) -> JsonRpseeError {
Expand Down Expand Up @@ -47,12 +63,14 @@ impl<C, B> Redeem<C, B> {
}

#[async_trait]
impl<C, Block, AccountId, H256, RedeemRequest> RedeemApiServer<<Block as BlockT>::Hash, AccountId, H256, RedeemRequest>
for Redeem<C, Block>
impl<C, Block, VaultId, Balance, AccountId, H256, RedeemRequest>
RedeemApiServer<<Block as BlockT>::Hash, VaultId, Balance, AccountId, H256, RedeemRequest> for Redeem<C, Block>
where
Block: BlockT,
C: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
C::Api: RedeemRuntimeApi<Block, AccountId, H256, RedeemRequest>,
C::Api: RedeemRuntimeApi<Block, VaultId, Balance, AccountId, H256, RedeemRequest>,
VaultId: Codec,
Balance: Codec + MaybeDisplay + MaybeFromStr,
AccountId: Codec,
H256: Codec,
RedeemRequest: Codec,
Expand All @@ -76,4 +94,17 @@ where
api.get_vault_redeem_requests(at, vault_id)
.map_err(|e| internal_err(format!("Unable to fetch redeem requests: {:?}", e)))
}

fn get_premium_redeem_vaults(
&self,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<(VaultId, BalanceWrapper<Balance>)>> {
let api = self.client.runtime_api();
let at = at.unwrap_or_else(|| self.client.info().best_hash);

handle_response(
api.get_premium_redeem_vaults(at),
"Unable to find a vault below the premium redeem threshold".into(),
)
}
}
11 changes: 9 additions & 2 deletions crates/redeem/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ use vault_registry::{
// Pallets
use crate::Pallet as Redeem;
use btc_relay::Pallet as BtcRelay;
use oracle::Pallet as Oracle;
use oracle::{OracleKey, Pallet as Oracle};
use security::Pallet as Security;
use sp_runtime::FixedPointNumber;
use vault_registry::Pallet as VaultRegistry;

type UnsignedFixedPoint<T> = <T as currency::Config>::UnsignedFixedPoint;

fn collateral<T: crate::Config>(amount: u32) -> Amount<T> {
Expand Down Expand Up @@ -158,6 +158,13 @@ pub mod benchmarks {

#[extrinsic_call]
_(RawOrigin::Signed(caller), amount, btc_address, vault_id.clone());
let redeem_vault_request = Redeem::<T>::get_redeem_requests_for_vault(vault_id.account_id.clone());
let redeem_request_hash = redeem_vault_request
.first()
.cloned()
.unwrap_or_else(|| panic!("No redeem request found"));
let redeem_struct = RedeemRequests::<T>::get(redeem_request_hash).unwrap();
assert!(redeem_struct.premium > 0);
}

#[benchmark]
Expand Down
Loading