Fee Estimation
Learn more about estimating fees associated with Stargate transfers.
Stargate offers five distinct methods to estimate transfer fees. Let’s begin by exploring the most commonly utilized ones.
quoteOFT
This method provides a quote for sending OFT to another chain. It can be used to calculate minimum amount of tokens you will receive on destination chain after you transfer.
Part of the IStargate
interface.
This function also returns maximum number of tokens possible to bridge to a particular chain. It is very important taking into consideration the Credits mechanism in Stargate.
This is how the interface of the function looks like:
/// @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
)
As you can see, the only input parameter is SendParam
:
/**
* @dev Struct representing token parameters for the OFT send() operation.
*/
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.
}
It contains all the information required to send the transfer. If you want to learn more about preparing this struct please read How to Transfer.
Now, let’s analyze the output of quoteOFT()
:
OFTLimit limit
- it returns minimum and maximum amounts of tokens in local decimals that can be transferred to the receiver. The maximum amount of tokens received on the destination chain might be limited by the credits mechanism in Stargate. Example value:
OFTLimit({ minAmountLD: 1000000000000 [1e12], maxAmountLD: 18446744073709551615000000000000 [1.844e31] })
OFTFeeDetail[] oftFeeDetails
- array of structs containing information about fees or rewards in local decimals with their descriptions. Note thatfeeAmountLD
isint256
so it can be positive or negative. If you would like to learn more read Treasury fees and rewards . Example value:
`[OFTFeeDetail({ feeAmountLD: 1000000000000 [1e12], description: "reward" })]`
- OFTReceipt receipt:
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.
}
Example value:
OFTReceipt({ amountSentLD: 100000000000000 [1e14], amountReceivedLD: 100000000000000 [1.01e14] })
amountReceivedLD
from quoteOFT()
can be used to override SendParam.minAmountLD
that is later passed to quoteSend()
. minAmountLD
is minimum amount of tokens to send. If due to applied fees/reward the actual amount sent would drop below this value then the fee library will revert with SlippageTooHigh
.
quoteSend
This method provides a way to calculate total fee for a given send()
operation. It reverts with InvalidAmount
if send mode is drive but value is specified.
This is an interface of the function:
function quoteSend(
SendParam calldata _sendParam,
bool _payInLzToken
) external view returns (MessagingFee memory fee)
It accepts SendParam
and a boolean
whether to pay in LayerZero token. For more information on how to prepare the SendParam
please read How to Swap .
quoteSend
returns MessagingFee
struct:
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}
Lower level functions
Below you can see some of the lower level functions which might be useful for advanced use cases. In a typical use case, when you call quoteSend
these lower level functions are called automatically and there’s no need to call them directly.
quoteTaxi
This function is part of ITokenMessaging
interface:
function quoteTaxi(
TaxiParams calldata _params,
bool _payInLzToken
) external view returns (MessagingFee memory fee);
This function accepts TaxiParams
and a boolean indicating whether to pay in LayerZero token as input parameters. It returns a quote for how much needs to be paid for the transfer.
Let’s focus on the TaxiParams
here:
struct TaxiParams {
address sender;
uint32 dstEid;
bytes32 receiver;
uint64 amountSD;
bytes composeMsg;
bytes extraOptions;
}
This is what you need to provide to the above function. You can also programatically convert SendParam
to TaxiParams
by calling:
using MessagingHelper for SendParam;
// ...
function _ld2sd(uint256 _amountLD) internal view returns (uint64 amountSD) {
unchecked {
amountSD = SafeCast.toUint64(_amountLD / convertRate);
}
}
// ...
uint64 amountSD = _ld2sd(sendParam.amountLD);
sendParam.toTaxiParams(amountSD)
quoteRideBus
This function is part of theITokenMessaging
interface:
function quoteRideBus(
uint32 _dstEid, bool _nativeDrop
) external view returns (MessagingFee memory fee);
It returns a total fee for the bus ride transfer and accepts Destination Endpoint Id (_dstEid
) and a boolean that represents whether to pay for a native drop on the destination.
Treasury fees and rewards
There are two types of Stargate token instances that can exist on particular chain. Only one instance will exist per asset per chain. A token on specific chain is either using a Pool or it is a Hydra OFT.
When sending tokens from Pool it can either charge a treasury fee or reward you for the transfer.
If you transfer from Hydra OFT there is no reward, but the treasury fee can be charged.
As a reminder you can query treasury fees or rewards using quoteOFT()
. Fees within the Stargate protocol are dynamic, and are set by the AI Planning Module on a per pathway basis.
Reward
The reward is capped by the treasury fee pool. The function addTreasuryFee()
can be called by the treasurer, which will emit the following event:
event TreasuryFeeAdded(uint64 amountSD);