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

refactor(interchain-token-service): use contractstorage #246

Merged
merged 5 commits into from
Feb 9, 2025
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
104 changes: 27 additions & 77 deletions contracts/stellar-interchain-token-service/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use stellar_axelar_gateway::AxelarGatewayMessagingClient;
use stellar_axelar_std::address::AddressExt;
use stellar_axelar_std::events::Event;
use stellar_axelar_std::interfaces::CustomMigratableInterface;
use stellar_axelar_std::ttl::{extend_instance_ttl, extend_persistent_ttl};
use stellar_axelar_std::ttl::extend_instance_ttl;
use stellar_axelar_std::types::Token;
use stellar_axelar_std::{
ensure, interfaces, when_not_paused, Operatable, Ownable, Pausable, Upgradable,
Expand All @@ -24,7 +24,7 @@ use crate::event::{
};
use crate::flow_limit::FlowDirection;
use crate::interface::InterchainTokenServiceInterface;
use crate::storage_types::{DataKey, TokenIdConfigValue};
use crate::storage::{self, TokenIdConfigValue};
use crate::token_metadata::TokenMetadataExt;
use crate::types::{
DeployInterchainToken, HubMessage, InterchainTransfer, Message, TokenManagerType,
Expand Down Expand Up @@ -54,94 +54,59 @@ impl InterchainTokenService {
) {
interfaces::set_owner(&env, &owner);
interfaces::set_operator(&env, &operator);
env.storage().instance().set(&DataKey::Gateway, &gateway);
env.storage()
.instance()
.set(&DataKey::GasService, &gas_service);
env.storage()
.instance()
.set(&DataKey::ItsHubAddress, &its_hub_address);
env.storage()
.instance()
.set(&DataKey::ChainName, &chain_name);
env.storage()
.instance()
.set(&DataKey::NativeTokenAddress, &native_token_address);
env.storage().instance().set(
&DataKey::InterchainTokenWasmHash,
&interchain_token_wasm_hash,
);
env.storage()
.instance()
.set(&DataKey::TokenManagerWasmHash, &token_manager_wasm_hash);
storage::set_gateway(&env, &gateway);
storage::set_gas_service(&env, &gas_service);
storage::set_its_hub_address(&env, &its_hub_address);
storage::set_chain_name(&env, &chain_name);
storage::set_native_token_address(&env, &native_token_address);
storage::set_interchain_token_wasm_hash(&env, &interchain_token_wasm_hash);
storage::set_token_manager_wasm_hash(&env, &token_manager_wasm_hash);
}
}

#[contractimpl]
impl InterchainTokenServiceInterface for InterchainTokenService {
fn gas_service(env: &Env) -> Address {
env.storage()
.instance()
.get(&DataKey::GasService)
.expect("gas service not found")
storage::gas_service(env)
}

fn chain_name(env: &Env) -> String {
env.storage()
.instance()
.get(&DataKey::ChainName)
.expect("chain name not found")
storage::chain_name(env)
}

fn its_hub_chain_name(env: &Env) -> String {
String::from_str(env, ITS_HUB_CHAIN_NAME)
}

fn its_hub_address(env: &Env) -> String {
env.storage()
.instance()
.get(&DataKey::ItsHubAddress)
.expect("its hub address not found")
storage::its_hub_address(env)
}

fn native_token_address(env: &Env) -> Address {
env.storage()
.instance()
.get(&DataKey::NativeTokenAddress)
.expect("native token address not found")
storage::native_token_address(env)
}

fn interchain_token_wasm_hash(env: &Env) -> BytesN<32> {
env.storage()
.instance()
.get(&DataKey::InterchainTokenWasmHash)
.expect("interchain token wasm hash not found")
storage::interchain_token_wasm_hash(env)
}

fn token_manager_wasm_hash(env: &Env) -> BytesN<32> {
env.storage()
.instance()
.get(&DataKey::TokenManagerWasmHash)
.expect("token manager wasm hash not found")
storage::token_manager_wasm_hash(env)
}

fn is_trusted_chain(env: &Env, chain: String) -> bool {
env.storage()
.persistent()
.has(&DataKey::TrustedChain(chain))
storage::is_trusted_chain(env, chain)
}

fn set_trusted_chain(env: &Env, chain: String) -> Result<(), ContractError> {
Self::owner(env).require_auth();

let key = DataKey::TrustedChain(chain.clone());

ensure!(
!env.storage().persistent().has(&key),
!storage::is_trusted_chain(env, chain.clone()),
ContractError::TrustedChainAlreadySet
);

env.storage().persistent().set(&key, &());
storage::set_trusted_chain_status(env, chain.clone());

TrustedChainSetEvent { chain }.emit(env);

Expand All @@ -151,14 +116,12 @@ impl InterchainTokenServiceInterface for InterchainTokenService {
fn remove_trusted_chain(env: &Env, chain: String) -> Result<(), ContractError> {
Self::owner(env).require_auth();

let key = DataKey::TrustedChain(chain.clone());

ensure!(
env.storage().persistent().has(&key),
storage::is_trusted_chain(env, chain.clone()),
ContractError::TrustedChainNotSet
);

env.storage().persistent().remove(&key);
storage::remove_trusted_chain_status(env, chain.clone());

TrustedChainRemovedEvent { chain }.emit(env);

Expand Down Expand Up @@ -362,10 +325,7 @@ impl AxelarExecutableInterface for InterchainTokenService {
type Error = ContractError;

fn gateway(env: &Env) -> Address {
env.storage()
.instance()
.get(&DataKey::Gateway)
.expect("gateway not found")
storage::gateway(env)
}

fn execute(
Expand Down Expand Up @@ -397,7 +357,6 @@ impl InterchainTokenService {
Self::is_trusted_chain(env, destination_chain.clone()),
ContractError::UntrustedChain
);
extend_persistent_ttl(env, &DataKey::TrustedChain(destination_chain.clone()));

let gateway = AxelarGatewayMessagingClient::new(env, &Self::gateway(env));
let gas_service = AxelarGasServiceClient::new(env, &Self::gas_service(env));
Expand Down Expand Up @@ -451,7 +410,6 @@ impl InterchainTokenService {
Message::DeployInterchainToken(message) => Self::execute_deploy_message(env, message),
}?;

extend_persistent_ttl(env, &DataKey::TrustedChain(source_chain));
extend_instance_ttl(env);

Ok(())
Expand Down Expand Up @@ -481,18 +439,15 @@ impl InterchainTokenService {
return Err(ContractError::InvalidMessageType);
};
ensure!(
Self::is_trusted_chain(env, original_source_chain.clone()),
storage::is_trusted_chain(env, original_source_chain.clone()),
ContractError::UntrustedChain
);
extend_persistent_ttl(env, &DataKey::TrustedChain(original_source_chain.clone()));

Ok((original_source_chain, message))
}

fn set_token_id_config(env: &Env, token_id: BytesN<32>, token_data: TokenIdConfigValue) {
env.storage()
.persistent()
.set(&DataKey::TokenIdConfig(token_id), &token_data);
storage::set_token_id_config(env, token_id, &token_data);
}

/// Retrieves the configuration value for the specified token ID.
Expand All @@ -509,10 +464,7 @@ impl InterchainTokenService {
env: &Env,
token_id: BytesN<32>,
) -> Result<TokenIdConfigValue, ContractError> {
env.storage()
.persistent()
.get::<_, TokenIdConfigValue>(&DataKey::TokenIdConfig(token_id))
.ok_or(ContractError::InvalidTokenId)
storage::try_token_id_config(env, token_id).ok_or(ContractError::InvalidTokenId)
}

/// Retrieves the configuration value for the specified token ID and extends its TTL.
Expand All @@ -529,8 +481,8 @@ impl InterchainTokenService {
env: &Env,
token_id: BytesN<32>,
) -> Result<TokenIdConfigValue, ContractError> {
let config = Self::token_id_config(env, token_id.clone())?;
extend_persistent_ttl(env, &DataKey::TokenIdConfig(token_id));
let config = Self::token_id_config(env, token_id)?;

Ok(config)
}

Expand Down Expand Up @@ -766,9 +718,7 @@ impl InterchainTokenService {

fn ensure_token_not_registered(env: &Env, token_id: BytesN<32>) -> Result<(), ContractError> {
ensure!(
!env.storage()
.persistent()
.has(&DataKey::TokenIdConfig(token_id)),
storage::try_token_id_config(env, token_id).is_none(),
ContractError::TokenAlreadyRegistered
);

Expand Down
49 changes: 20 additions & 29 deletions contracts/stellar-interchain-token-service/src/flow_limit.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use soroban_sdk::{BytesN, Env};
use stellar_axelar_std::ensure;
use stellar_axelar_std::events::Event;
use stellar_axelar_std::ttl::extend_persistent_ttl;

use crate::error::ContractError;
use crate::event::FlowLimitSetEvent;
use crate::storage_types::{DataKey, FlowKey};
use crate::storage::{self, FlowKey};

const EPOCH_TIME: u64 = 6 * 60 * 60; // 6 hours in seconds = 21600

Expand Down Expand Up @@ -37,12 +36,10 @@ impl FlowDirection {
epoch: current_epoch(env),
};

let key = match self {
Self::In => DataKey::FlowIn(flow_key),
Self::Out => DataKey::FlowOut(flow_key),
match self {
Self::In => storage::set_flow_in(env, flow_key, &new_flow),
Self::Out => storage::set_flow_out(env, flow_key, &new_flow),
};

env.storage().temporary().set(&key, &new_flow);
}

/// Adds flow amount in the specified direction (in/out) for a token.
Expand Down Expand Up @@ -77,9 +74,7 @@ impl FlowDirection {
// Equivalent to flow_amount + flow - reverse_flow <= flow_limit
ensure!(new_flow <= max_allowed, ContractError::FlowLimitExceeded);

self.update_flow(env, token_id.clone(), new_flow);

extend_persistent_ttl(env, &DataKey::FlowLimit(token_id));
self.update_flow(env, token_id, new_flow);

Ok(())
}
Expand All @@ -90,9 +85,7 @@ fn current_epoch(env: &Env) -> u64 {
}

pub fn flow_limit(env: &Env, token_id: BytesN<32>) -> Option<i128> {
env.storage()
.persistent()
.get(&DataKey::FlowLimit(token_id))
storage::try_flow_limit(env, token_id)
}

pub fn set_flow_limit(
Expand All @@ -103,13 +96,9 @@ pub fn set_flow_limit(
if let Some(flow_limit) = flow_limit {
ensure!(flow_limit >= 0, ContractError::InvalidFlowLimit);

env.storage()
.persistent()
.set(&DataKey::FlowLimit(token_id.clone()), &flow_limit);
storage::set_flow_limit(env, token_id.clone(), &flow_limit);
} else {
env.storage()
.persistent()
.remove(&DataKey::FlowLimit(token_id.clone()));
storage::remove_flow_limit(env, token_id.clone());
}

FlowLimitSetEvent {
Expand All @@ -122,21 +111,23 @@ pub fn set_flow_limit(
}

pub fn flow_out_amount(env: &Env, token_id: BytesN<32>) -> i128 {
env.storage()
.temporary()
.get(&DataKey::FlowOut(FlowKey {
storage::try_flow_out(
env,
FlowKey {
token_id,
epoch: current_epoch(env),
}))
.unwrap_or(0)
},
)
.unwrap_or(0)
}

pub fn flow_in_amount(env: &Env, token_id: BytesN<32>) -> i128 {
env.storage()
.temporary()
.get(&DataKey::FlowIn(FlowKey {
storage::try_flow_in(
env,
FlowKey {
token_id,
epoch: current_epoch(env),
}))
.unwrap_or(0)
},
)
.unwrap_or(0)
}
2 changes: 1 addition & 1 deletion contracts/stellar-interchain-token-service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ cfg_if::cfg_if! {
mod abi;
mod deployer;
pub mod event;
mod storage_types;
mod storage;
mod token_id;
mod token_manager;
mod token_metadata;
Expand Down
Loading
Loading