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 3 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
1 change: 1 addition & 0 deletions core
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
132 changes: 132 additions & 0 deletions crates/gem_evm/src/stargate/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use alloy_core::sol;
use serde::{Deserialize, Serialize};

sol! {
#[derive(Debug, PartialEq)]
struct LzTxObj {
uint256 dstGasForCall;
uint256 dstNativeAmount;
bytes dstNativeAddr;
}

/**
* @dev Struct representing token parameters for the OFT send() operation.
*/
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct SendParam {
uint32 dstEid; // Destination endpoint ID.
bytes32 to; // Recipient address.
uint256 amountLD; // Amount to send in local decimals.
uint256 minAmountLD; // Minimum amount to send in local decimals.
bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message.
bytes composeMsg; // The composed message for the send() operation.
bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations.
}

/**
* @dev Struct representing OFT limit information.
* @dev These amounts can change dynamically and are up the the specific oft implementation.
*/
#[derive(Debug, PartialEq)]
struct OFTLimit {
uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient.
uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient.
}

/**
* @dev Struct representing OFT receipt information.
*/
#[derive(Debug, PartialEq)]
struct OFTReceipt {
uint256 amountSentLD; // Amount of tokens ACTUALLY debited from the sender in local decimals.
// @dev In non-default implementations, the amountReceivedLD COULD differ from this value.
uint256 amountReceivedLD; // Amount of tokens to be received on the remote side.
}

#[derive(Debug, PartialEq)]
struct OFTFeeDetail {
int256 feeAmountLD; // Amount of the fee in local decimals.
string description; // Description of the fee.
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}

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

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Ticket {
uint56 ticketId;
bytes passenger;
}

#[derive(Debug, PartialEq)]
interface IStargate {
function quoteSend(
SendParam calldata _sendParam,
bool _payInLzToken
) external view returns (MessagingFee memory fee);

/**
* @notice Provides a quote for sending OFT to another chain.
* @dev Implements the IOFT interface
* @param _sendParam The parameters for the send operation
* @return limit The information on OFT transfer limits
* @return oftFeeDetails The details of OFT transaction cost or reward
* @return receipt The OFT receipt information, indicating how many tokens would be sent and received
*/
function quoteOFT(
SendParam calldata _sendParam
) external view returns (
OFTLimit memory limit,
OFTFeeDetail[] memory oftFeeDetails,
OFTReceipt memory receipt
);

/**
* @notice Executes the send() operation.
* @param _sendParam The parameters for the send operation.
* @param _fee The fee information supplied by the caller.
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
* @param _refundAddress The address to receive any excess funds from fees etc. on the src.
* @return receipt The LayerZero messaging receipt from the send() operation.
* @return oftReceipt The OFT receipt information.
*
* @dev MessagingReceipt: LayerZero msg receipt
* - guid: The unique identifier for the sent message.
* - nonce: The nonce of the sent message.
* - fee: The LayerZero fee incurred for the message.
*/
function send(
SendParam calldata _sendParam,
MessagingFee calldata _fee,
address _refundAddress
) external payable returns (
MessagingReceipt memory msgReceipt,
OFTReceipt memory oftReceipt
);

/**
* @dev This function is same as `send` in OFT interface but returns the ticket data if in the bus ride mode,
* which allows the caller to ride and drive the bus in the same transaction.
*/
function sendToken(
0xh3rman marked this conversation as resolved.
Show resolved Hide resolved
SendParam calldata _sendParam,
MessagingFee calldata _fee,
address _refundAddress
) external payable returns (
MessagingReceipt memory msgReceipt,
OFTReceipt memory oftReceipt,
Ticket memory ticket
);
}
}
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;
62 changes: 62 additions & 0 deletions gemstone/src/swapper/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const WBTC_NAME: &str = "Wrapped BTC";
const DAI_SYMBOL: &str = "DAI";
const WETH_NAME: &str = "Wrapped Ether";
const WETH_SYMBOL: &str = "WETH";
const METH_NAME: &str = "mETH (mETH)";
const METH_SYMBOL: &str = "mETH";
const CBBTC_NAME: &str = "Coinbase BTC";
const CBBTC_SYMBOL: &str = "cbBTC";

Expand All @@ -18,12 +20,19 @@ 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";
pub const AVALANCHE_USDC_TOKEN_ID: &str = "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E";
pub const BASE_USDC_TOKEN_ID: &str = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
pub const BASE_CBBTC_TOKEN_ID: &str = "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf";
pub const MANTLE_USDC_TOKEN_ID: &str = "0x09bc4e0d864854c6afb6eb9a9cdf58ac190d0df9";
pub const MANTLE_USDT_TOKEN_ID: &str = "0x201eba5cc46d216ce6dc03f6a759e8e766e956ae";
pub const MANTLE_WETH_TOKEN_ID: &str = "0xdeaddeaddeaddeaddeaddeaddeaddeaddead1111";
0xh3rman marked this conversation as resolved.
Show resolved Hide resolved
pub const MANTLE_METH_TOKEN_ID: &str = "0xcda86a272531e8640cd7f1a92c01839911b90bb0";
pub const SEI_USDC_TOKEN_ID: &str = "0x3894085Ef7Ff0f0aeDf52E2A2704928d1Ec074F1";
pub const SEI_USDT_TOKEN_ID: &str = "0x0dB9afb4C33be43a0a0e396Fd1383B4ea97aB10a";

lazy_static! {
// ethereum
Expand Down Expand Up @@ -62,6 +71,13 @@ lazy_static! {
decimals: 18,
asset_type: AssetType::ERC20,
};
pub static ref ETHEREUM_METH: Asset = Asset {
id: AssetId::from_token(Chain::Ethereum, ETHEREUM_METH_TOKEN_ID),
name: METH_NAME.into(),
symbol: METH_SYMBOL.into(),
decimals: 18,
asset_type: AssetType::ERC20,
};
// arbitrum
pub static ref ARBITRUM_WETH: Asset = Asset {
id: WETH_ARB_ASSET_ID.into(),
Expand Down Expand Up @@ -226,4 +242,50 @@ lazy_static! {
decimals: 6,
asset_type: AssetType::ERC20,
};
// mantle
pub static ref MANTLE_USDC: Asset = Asset {
id: AssetId::from_token(Chain::Mantle, MANTLE_USDC_TOKEN_ID),
name: USDC_NAME.to_owned(),
symbol: USDC_SYMBOL.to_owned(),
decimals: 6,
asset_type: AssetType::ERC20,
};
pub static ref MANTLE_USDT: Asset = Asset {
id: AssetId::from_token(Chain::Mantle, MANTLE_USDT_TOKEN_ID),
name: USDT_NAME.to_owned(),
symbol: USDT_SYMBOL.to_owned(),
decimals: 6,
asset_type: AssetType::ERC20,
};
pub static ref MANTLE_WETH: Asset = Asset {
id: AssetId::from_token(Chain::Mantle, MANTLE_WETH_TOKEN_ID),
name: WETH_NAME.to_owned(),
symbol: WETH_SYMBOL.to_owned(),
decimals: 18,
asset_type: AssetType::ERC20,
};
pub static ref MANTLE_METH: Asset = Asset {
id: AssetId::from_token(Chain::Mantle, MANTLE_METH_TOKEN_ID),
name: METH_NAME.to_owned(),
symbol: METH_SYMBOL.to_owned(),
decimals: 18,
asset_type: AssetType::ERC20,
};

// sei
pub static ref SEI_USDC: Asset = Asset {
id: AssetId::from_token(Chain::Sei, SEI_USDC_TOKEN_ID),
name: USDC_NAME.to_owned(),
symbol: USDC_SYMBOL.to_owned(),
decimals: 6,
asset_type: AssetType::ERC20,
};
pub static ref SEI_USDT: Asset = Asset {
id: AssetId::from_token(Chain::Sei, SEI_USDT_TOKEN_ID),
name: USDT_NAME.to_owned(),
symbol: USDT_SYMBOL.to_owned(),
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
Loading
Loading