Skip to content

Commit

Permalink
Contract: Token status update implementation (#64)
Browse files Browse the repository at this point in the history
# Description

- Allow admin to disable/enable tokens (both Coreum or XRPL) to block
them from being bridged / or bridged back
  • Loading branch information
keyleu authored Dec 19, 2023
1 parent 82fd1ca commit 621eebb
Show file tree
Hide file tree
Showing 12 changed files with 559 additions and 51 deletions.
58 changes: 29 additions & 29 deletions contract/Cargo.lock

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

2 changes: 1 addition & 1 deletion contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ cosmwasm-std = { version = "1.5.0", features = ["cosmwasm_1_1"] }
cw-ownable = "0.5.1"
cw-storage-plus = "1.2.0"
cw-utils = "1.0.3"
cw2 = "1.1.1"
cw2 = "1.1.2"
hex = "0.4.3"
serde_json = "1.0.108"
sha2 = "0.10.8"
Expand Down
70 changes: 57 additions & 13 deletions contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::{
tickets::{
allocate_ticket, handle_ticket_allocation_confirmation, register_used_ticket, return_ticket,
},
token::{build_xrpl_token_key, is_token_xrp, set_token_state},
};

use coreum_wasm_sdk::{
Expand Down Expand Up @@ -62,8 +63,8 @@ pub const XRPL_TOKENS_DECIMALS: u32 = 15;
// For more info check https://xrpl.org/transfer-fees.html#technical-details
pub const XRPL_ZERO_TRANSFER_RATE: Uint128 = Uint128::new(1000000000);

const XRP_CURRENCY: &str = "XRP";
const XRP_ISSUER: &str = "rrrrrrrrrrrrrrrrrrrrrhoLvTp";
pub const XRP_CURRENCY: &str = "XRP";
pub const XRP_ISSUER: &str = "rrrrrrrrrrrrrrrrrrrrrhoLvTp";

// Initial values for the XRP token that can be modified afterwards.
const XRP_DEFAULT_SENDING_PRECISION: i32 = 6;
Expand Down Expand Up @@ -236,6 +237,14 @@ pub fn execute(
ExecuteMsg::SendToXRPL { recipient } => {
send_to_xrpl(deps.into_empty(), env, info, recipient)
}
ExecuteMsg::UpdateXRPLToken {
issuer,
currency,
state,
} => update_xrpl_token(deps.into_empty(), info.sender, issuer, currency, state),
ExecuteMsg::UpdateCoreumToken { denom, state } => {
update_coreum_token(deps.into_empty(), info.sender, denom, state)
}
ExecuteMsg::ClaimFees {} => claim_fees(deps.into_empty(), info.sender),
}
}
Expand Down Expand Up @@ -879,6 +888,52 @@ fn send_to_xrpl(
.add_attribute("coin", funds.to_string()))
}

fn update_xrpl_token(
deps: DepsMut,
sender: Addr,
issuer: String,
currency: String,
state: Option<TokenState>,
) -> CoreumResult<ContractError> {
assert_owner(deps.storage, &sender)?;

let key = build_xrpl_token_key(issuer.to_owned(), currency.to_owned());

let mut token = XRPL_TOKENS
.load(deps.storage, key.to_owned())
.map_err(|_| ContractError::TokenNotRegistered {})?;

set_token_state(&mut token.state, state)?;

XRPL_TOKENS.save(deps.storage, key, &token)?;

Ok(Response::new()
.add_attribute("action", ContractActions::UpdateXRPLToken.as_str())
.add_attribute("issuer", issuer)
.add_attribute("currency", currency))
}

fn update_coreum_token(
deps: DepsMut,
sender: Addr,
denom: String,
state: Option<TokenState>,
) -> CoreumResult<ContractError> {
assert_owner(deps.storage, &sender)?;

let mut token = COREUM_TOKENS
.load(deps.storage, denom.to_owned())
.map_err(|_| ContractError::TokenNotRegistered {})?;

set_token_state(&mut token.state, state)?;

COREUM_TOKENS.save(deps.storage, denom.to_owned(), &token)?;

Ok(Response::new()
.add_attribute("action", ContractActions::UpdateCoreumToken.as_str())
.add_attribute("denom", denom))
}

fn claim_fees(deps: DepsMut, sender: Addr) -> CoreumResult<ContractError> {
assert_relayer(deps.as_ref(), sender.clone())?;

Expand Down Expand Up @@ -986,13 +1041,6 @@ fn check_issue_fee(deps: &DepsMut<CoreumQueries>, info: &MessageInfo) -> Result<
Ok(())
}

pub fn build_xrpl_token_key(issuer: String, currency: String) -> String {
// Issuer+currency is the key we use to find an XRPL
let mut key = issuer;
key.push_str(currency.as_str());
key
}

pub fn validate_xrpl_issuer_and_currency(
issuer: String,
currency: String,
Expand Down Expand Up @@ -1130,10 +1178,6 @@ fn truncate_and_convert_amount(
Ok((converted_amount, remainder))
}

fn is_token_xrp(issuer: String, currency: String) -> bool {
issuer == XRP_ISSUER && currency == XRP_CURRENCY
}

fn convert_currency_to_xrpl_hexadecimal(currency: String) -> String {
// Fill with zeros to get the correct hex representation in XRPL of our currency.
format!("{:0<40}", hex::encode(currency)).to_uppercase()
Expand Down
6 changes: 6 additions & 0 deletions contract/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ pub enum ContractError {
#[error("CannotCoverBridgingFees: The amount sent is not enough to cover the bridging fees")]
CannotCoverBridgingFees {},

#[error("TokenStateIsImmutable: Current token state is immutable")]
TokenStateIsImmutable {},

#[error("InvalidTargetTokenState: A token state can only be updated to enabled or disabled")]
InvalidTargetTokenState {},

#[error("InvalidTransferRate: The transfer rate sent is invalid, it must be more than 1000000000 (0%) and less or equal than 2000000000 (100%)")]
InvalidTransferRate {},
}
2 changes: 1 addition & 1 deletion contract/src/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn handle_fee_collection(
Ok(fee_collected)
}

pub fn collect_fees(storage: &mut dyn Storage, fee: Coin) -> Result<(), ContractError> {
fn collect_fees(storage: &mut dyn Storage, fee: Coin) -> Result<(), ContractError> {
// We only collect fees if there is something to collect
// If for some reason there is a coin that we are not charging fees for, we don't collect it
if !fee.amount.is_zero() {
Expand Down
1 change: 1 addition & 0 deletions contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ pub mod state;
#[cfg(test)]
mod tests;
pub mod tickets;
pub mod token;
16 changes: 15 additions & 1 deletion contract/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cw_ownable::{cw_ownable_execute, cw_ownable_query};

#[allow(unused_imports)]
use crate::state::{Config, CoreumToken, XRPLToken};
use crate::{evidence::Evidence, operation::Operation, relayer::Relayer};
use crate::{evidence::Evidence, operation::Operation, relayer::Relayer, state::TokenState};

#[cw_serde]
pub struct InstantiateMsg {
Expand Down Expand Up @@ -65,6 +65,20 @@ pub enum ExecuteMsg {
SendToXRPL {
recipient: String,
},
// All fields that can be updatable for XRPL originated tokens will be updated with this message
// They are all optional, so any fields that have to be updated can be included in the message.
#[serde(rename = "update_xrpl_token")]
UpdateXRPLToken {
issuer: String,
currency: String,
state: Option<TokenState>,
},
// All fields that can be updatable for Coreum tokens will be updated with this message.
// They are all optional, so any fields that have to be updated can be included in the message.
UpdateCoreumToken {
denom: String,
state: Option<TokenState>,
},
// Any relayer can claim fees at any point in time. They will be distributed proportionally among all of them.
ClaimFees {},
}
Expand Down
Loading

0 comments on commit 621eebb

Please sign in to comment.