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

feat: stargate integration #374

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
21807ad
feat: initial stargate integration
kuchmenko Jan 13, 2025
a8027f6
feat(stargate): chain and assets support
kuchmenko Jan 14, 2025
0bbdea5
Merge branch 'main' into feat/stargate-integration
kuchmenko Jan 14, 2025
0680931
chore: remove unused files
kuchmenko Jan 15, 2025
55ae06d
chore: removed unused assets and chains
kuchmenko Jan 15, 2025
a9ba9fc
chore: removed unused assets
kuchmenko Jan 15, 2025
8def015
Merge branch 'main' into feat/stargate-integration
kuchmenko Jan 15, 2025
9177f96
feat: added bnb assets decimals transformation and tests
kuchmenko Jan 15, 2025
bcf8b16
chore: stargate contract docs
kuchmenko Jan 15, 2025
3293549
chore: clippy
kuchmenko Jan 15, 2025
c1cc274
Merge branch 'main' into feat/stargate-integration
kuchmenko Jan 15, 2025
85e9074
Update gemstone/src/swapper/models.rs
kuchmenko Jan 16, 2025
358e450
Update gemstone/src/swapper/stargate/provider.rs
kuchmenko Jan 16, 2025
c0d0b44
chore: pr comments refactoring
kuchmenko Jan 16, 2025
daba5dc
fix: added tests for domain logic
kuchmenko Jan 16, 2025
b5b044f
Merge branch 'main' into feat/stargate-integration
kuchmenko Jan 16, 2025
32364b8
Merge branch 'main' into feat/stargate-integration
0xh3rman Jan 17, 2025
25fed9a
chore: clippy fix
kuchmenko Jan 17, 2025
9a4605e
chore: improve crypto value converter readabilty
kuchmenko Jan 17, 2025
890bfc7
chore: pr comments
kuchmenko Jan 20, 2025
fb52837
chore: improved code style
kuchmenko Jan 20, 2025
1b3244d
Merge branch 'main' into feat/stargate-integration
gemcoder21 Jan 22, 2025
6cc2c20
Merge branch 'main' into feat/stargate-integration
kuchmenko Jan 28, 2025
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
11 changes: 11 additions & 0 deletions crates/gem_evm/src/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ impl TransactionObject {
data: format!("0x{}", hex::encode(data)),
}
}

pub fn new_call_with_from_value(from: &str, to: &str, value: &str, data: Vec<u8>) -> Self {
Self {
from: Some(from.to_string()),
to: to.to_string(),
gas: None,
gas_price: None,
value: Some(value.to_string()),
data: format!("0x{}", hex::encode(data)),
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
1 change: 1 addition & 0 deletions crates/gem_evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod jsonrpc;
pub mod lido;
pub mod multicall3;
pub mod permit2;
pub mod stargate;
pub mod thorchain;
pub mod uniswap;
pub mod weth;
Expand Down
116 changes: 116 additions & 0 deletions crates/gem_evm/src/stargate/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
use alloy_core::sol;
use serde::{Deserialize, Serialize};

sol! {
/// Parameters for the OFT send() operation
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct SendParam {
uint32 dstEid;
bytes32 to;
uint256 amountLD;
uint256 minAmountLD;
bytes extraOptions;
bytes composeMsg;
bytes oftCmd;
}

/// OFT limit information
///
/// These amounts can change dynamically and are determined by the specific OFT implementation
#[derive(Debug, PartialEq)]
struct OFTLimit {
uint256 minAmountLD;
uint256 maxAmountLD;
}

/// OFT receipt information containing details about sent and received amounts
#[derive(Debug, PartialEq)]
struct OFTReceipt {
uint256 amountSentLD;
uint256 amountReceivedLD;
}

/// Detailed information about OFT fees
#[derive(Debug, PartialEq)]
struct OFTFeeDetail {
int256 feeAmountLD;
string description;
}

/// Structure containing messaging fee information
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}

/// Receipt for messaging operations
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct MessagingReceipt {
bytes32 guid;
uint64 nonce;
MessagingFee fee;
}

/// Interface for Stargate cross-chain operations
#[derive(Debug, PartialEq)]
interface IStargate {
/// Provides a quote for messaging fees
///
/// # Arguments
///
/// * `_sendParam` - Parameters for the send operation
/// * `_payInLzToken` - Flag indicating whether to pay in LayerZero tokens
///
/// # Returns
///
/// * `fee` - Messaging fee information
function quoteSend(
SendParam calldata _sendParam,
bool _payInLzToken
) external view returns (MessagingFee memory fee);

/// Provides a quote for sending OFT to another chain
///
/// # Arguments
///
/// * `_sendParam` - Parameters for the send operation
///
/// # Returns
///
/// * `limit` - Information on OFT transfer limits
/// * `oftFeeDetails` - Details of OFT transaction cost or reward
/// * `receipt` - OFT receipt information indicating token amounts
function quoteOFT(
SendParam calldata _sendParam
) external view returns (
OFTLimit memory limit,
OFTFeeDetail[] memory oftFeeDetails,
OFTReceipt memory receipt
);

/// Executes the send operation
///
/// # Arguments
///
/// * `_sendParam` - Parameters for the send operation
/// * `_fee` - Fee information containing native and LayerZero token fees
/// * `_refundAddress` - Address to receive any excess funds from fees on the source chain
///
/// # Returns
///
/// * `msgReceipt` - LayerZero messaging receipt containing:
/// - guid: Unique identifier for the message
/// - nonce: Message nonce
/// - fee: LayerZero fee details
/// * `oftReceipt` - OFT receipt with sent and received amount information
function send(
SendParam calldata _sendParam,
MessagingFee calldata _fee,
address _refundAddress
) external payable returns (
MessagingReceipt memory msgReceipt,
OFTReceipt memory oftReceipt
);
}
}
1 change: 1 addition & 0 deletions crates/gem_evm/src/stargate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod contract;
2 changes: 1 addition & 1 deletion crates/primitives/src/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use typeshare::typeshare;

use crate::{asset_id::AssetId, asset_type::AssetType, Chain};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[typeshare(swift = "Sendable")]
pub struct Asset {
pub id: AssetId,
Expand Down
2 changes: 2 additions & 0 deletions gemstone/src/swapper/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub const ETHEREUM_USDC_TOKEN_ID: &str = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606
pub const ETHEREUM_USDT_TOKEN_ID: &str = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
pub const ETHEREUM_WBTC_TOKEN_ID: &str = "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599";
pub const ETHEREUM_DAI_TOKEN_ID: &str = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
pub const ETHEREUM_METH_TOKEN_ID: &str = "0xd5f7838f5c461feff7fe49ea5ebaf7728bb0adfa";
0xh3rman marked this conversation as resolved.
Show resolved Hide resolved
pub const SMARTCHAIN_USDT_TOKEN_ID: &str = "0x55d398326f99059fF775485246999027B3197955";
pub const SMARTCHAIN_USDC_TOKEN_ID: &str = "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d";
pub const AVALANCHE_USDT_TOKEN_ID: &str = "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7";
Expand Down Expand Up @@ -226,4 +227,5 @@ lazy_static! {
decimals: 6,
asset_type: AssetType::ERC20,
};

}
2 changes: 2 additions & 0 deletions gemstone/src/swapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod models;
pub mod orca;
pub mod pancakeswap_aptos;
pub mod slippage;
pub mod stargate;
pub mod thorchain;
pub mod universal_router;

Expand Down Expand Up @@ -86,6 +87,7 @@ impl GemSwapper {
Box::new(jupiter::Jupiter::default()),
Box::new(pancakeswap_aptos::PancakeSwapAptos::default()),
Box::new(across::Across::default()),
Box::new(stargate::Stargate::new()),
],
}
}
Expand Down
3 changes: 3 additions & 0 deletions gemstone/src/swapper/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub enum SwapProvider {
Orca,
Jupiter,
Across,
Stargate,
}

#[derive(Debug, Clone, PartialEq, uniffi::Enum)]
Expand All @@ -88,6 +89,7 @@ impl SwapProvider {
Self::Orca => "Orca Whirlpool",
Self::Jupiter => "Jupiter",
Self::Across => "Across v3",
Self::Stargate => "Stargate",
kuchmenko marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand All @@ -100,6 +102,7 @@ impl SwapProvider {
Self::Orca => SwapProviderType::OnChain,
Self::Jupiter => SwapProviderType::OnChain,
Self::Across => SwapProviderType::Bridge,
Self::Stargate => SwapProviderType::Bridge,
}
}
}
Expand Down
155 changes: 155 additions & 0 deletions gemstone/src/swapper/stargate/endpoint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use lazy_static::lazy_static;
use primitives::{Asset, Chain};

use crate::swapper::asset::{
ARBITRUM_USDC, ARBITRUM_USDT, AVALANCHE_USDC, AVALANCHE_USDT, BASE_USDC, ETHEREUM_USDC, ETHEREUM_USDT, OPTIMISM_USDC, OPTIMISM_USDT, POLYGON_USDC,
POLYGON_USDT, SMARTCHAIN_USDC, SMARTCHAIN_USDT,
};

#[derive(Clone, Debug, PartialEq)]
pub struct StargatePool {
pub asset: Asset,
pub address: String,
}

#[derive(Clone, Debug, PartialEq)]
pub struct StargateEndpoint {
pub id: Chain,
pub pools: Vec<StargatePool>,
pub endpoint_id: u32,
}

#[derive(Clone, Debug)]
pub struct StargateRoutes {
pub ethereum: StargateEndpoint,
pub base: StargateEndpoint,
pub optimism: StargateEndpoint,
pub arbitrum: StargateEndpoint,
pub polygon: StargateEndpoint,
pub avalanche: StargateEndpoint,
pub linea: StargateEndpoint,
pub smartchain: StargateEndpoint,
}

lazy_static! {
pub static ref STARGATE_ROUTES: StargateRoutes = StargateRoutes {
ethereum: StargateEndpoint {
id: Chain::Ethereum,
pools: vec![
StargatePool {
asset: Asset::from_chain(Chain::Ethereum),
address: "0x77b2043768d28E9C9aB44E1aBfC95944bcE57931".to_string(),
},
StargatePool {
asset: ETHEREUM_USDC.clone(),
address: "0xc026395860Db2d07ee33e05fE50ed7bD583189C7".to_string(),
},
StargatePool {
asset: ETHEREUM_USDT.clone(),
address: "0x933597a323Eb81cAe705C5bC29985172fd5A3973".to_string(),
},
],
endpoint_id: 30101,
0xh3rman marked this conversation as resolved.
Show resolved Hide resolved
},
base: StargateEndpoint {
id: Chain::Base,
pools: vec![
StargatePool {
asset: Asset::from_chain(Chain::Base),
address: "0xdc181Bd607330aeeBEF6ea62e03e5e1Fb4B6F7C7".to_string(),
},
StargatePool {
asset: BASE_USDC.clone(),
address: "0x27a16dc786820B16E5c9028b75B99F6f604b5d26".to_string(),
},
],
endpoint_id: 30184,
},
optimism: StargateEndpoint {
id: Chain::Optimism,
pools: vec![
StargatePool {
asset: Asset::from_chain(Chain::Optimism),
address: "0xe8CDF27AcD73a434D661C84887215F7598e7d0d3".to_string(),
},
StargatePool {
asset: OPTIMISM_USDC.clone(),
address: "0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0".to_string(),
},
StargatePool {
asset: OPTIMISM_USDT.clone(),
address: "0x19cFCE47eD54a88614648DC3f19A5980097007dD".to_string(),
},
],
endpoint_id: 30111,
},
arbitrum: StargateEndpoint {
id: Chain::Arbitrum,
pools: vec![
StargatePool {
asset: Asset::from_chain(Chain::Arbitrum),
address: "0xA45B5130f36CDcA45667738e2a258AB09f4A5f7F".to_string(),
},
StargatePool {
asset: ARBITRUM_USDC.clone(),
address: "0xe8CDF27AcD73a434D661C84887215F7598e7d0d3".to_string(),
},
StargatePool {
asset: ARBITRUM_USDT.clone(),
address: "0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0".to_string(),
},
],
endpoint_id: 30110,
},
polygon: StargateEndpoint {
id: Chain::Polygon,
pools: vec![
StargatePool {
asset: POLYGON_USDC.clone(),
address: "0x9Aa02D4Fae7F58b8E8f34c66E756cC734DAc7fe4".to_string(),
},
StargatePool {
asset: POLYGON_USDT.clone(),
address: "0xd47b03ee6d86Cf251ee7860FB2ACf9f91B9fD4d7".to_string(),
},
],
endpoint_id: 30109,
},
avalanche: StargateEndpoint {
id: Chain::AvalancheC,
pools: vec![
StargatePool {
asset: AVALANCHE_USDC.clone(),
address: "0x5634c4a5FEd09819E3c46D86A965Dd9447d86e47".to_string(),
},
StargatePool {
asset: AVALANCHE_USDT.clone(),
address: "0x12dC9256Acc9895B076f6638D628382881e62CeE".to_string(),
},
],
endpoint_id: 30106,
},
linea: StargateEndpoint {
id: Chain::Linea,
pools: vec![StargatePool {
asset: Asset::from_chain(Chain::Linea),
address: "0x81F6138153d473E8c5EcebD3DC8Cd4903506B075".to_string(),
},],
endpoint_id: 30183,
},
smartchain: StargateEndpoint {
id: Chain::SmartChain,
pools: vec![
StargatePool {
asset: SMARTCHAIN_USDC.clone(),
address: "0x962Bd449E630b0d928f308Ce63f1A21F02576057".to_string(),
},
StargatePool {
asset: SMARTCHAIN_USDT.clone(),
address: "0x138EB30f73BC423c6455C53df6D89CB01d9eBc63".to_string(),
},
],
endpoint_id: 30102,
},
};
}
Loading
Loading