Simulator
The Simulator is a versatile utility designed to help offchain services and Relays obtain accurate gas estimates for intents efficiently.
It functions like an advanced multicall, enabling sophisticated operations such as searching for optimal combinedGas values, generating custom execution traces, and providing clearer error messages for transaction reverts.
It uses the primitive simulateExecute function exposed by the orchestrator, and adds custom logic on top of it.
Developers have the flexibility to utilize the default Simulator provided by Ithaca or deploy a custom one tailored to their specific needs.
Simulators operate without any special onchain privileges and any simulator can be used with any Orchestrator instance.
State Override Convention
Certain simulation modes, especially those designed to generate detailed logs for tools like eth_simulateV1, depend on specific state overrides to operate correctly.
A general principle for enabling special simulation behaviors, such as skipping signature verification checks, involves checking the native token balance of msg.sender. If this balance is type(uint256).max, it signals a trusted simulation environment where certain validation steps can be relaxed.
-
For
simulateV1Logs:- The simulateExecute function, when invoked with
isStateOverride = true, requires its direct caller (msg.sender) to possess a native token balance equal totype(uint256).max. - When
simulateV1Logscalls the Orchestrator, the Simulator contract acts as themsg.sender. -
Crucially, for
simulateV1Logsto successfully produce a non-reverting trace, the Simulator contract's native token balance must be externally set totype(uint256).maxbefore callingsimulateV1Logs. - Failure to meet this condition will typically cause the Orchestrator to revert with
StateOverrideError(), which is then propagated by the Simulator.
- The simulateExecute function, when invoked with
Endpoints
simulateGasUsed
-
Signature:
function simulateGasUsed( address oc, bool overrideCombinedGas, bytes calldata encodedIntent ) public payable virtual returns (uint256 gasUsed); - Description:
This function simulates the gas usage for a single encoded Intent. It calls the
simulateExecutefunction on the specified Orchestrator contract withisStateOverrideset tofalse. If the underlying simulation within the Orchestrator fails, this function will revert. -
Usage:
-
Parameters:
oc: Address of the Orchestrator contract.overrideCombinedGas: Boolean indicating howcombinedGasis handled:- If
true: ThecombinedGasfield in theencodedIntentis overridden totype(uint256).maxfor the simulation. This helps determine the raw gas cost without constraints from the Intent's specified gas limit. - If
false: ThecombinedGasvalue from theencodedIntentis respected.
- If
encodedIntent: The ABI-encoded Intent
-
Returns:
gasUsed: The amount of gas consumed by the simulated execution. This is extracted from theSimulationPassed(uint256 gasUsed)revert data from the Orchestrator.
-
Reverts:
- If the simulation fails (e.g., due to an error in Intent logic or insufficient gas if
overrideCombinedGasisfalse), it reverts with the Orchestrator's error.
- If the simulation fails (e.g., due to an error in Intent logic or insufficient gas if
-
Parameters:
simulateCombinedGas
-
Signature:
function simulateCombinedGas( address oc, bool isPrePayment, uint8 paymentPerGasPrecision, uint256 paymentPerGas, uint256 combinedGasIncrement, bytes calldata encodedIntent ) public payable virtual returns (uint256 gasUsed, uint256 combinedGas); - Description:
This function simulates an Intent's execution to iteratively find the minimum
combinedGasvalue required for it to pass successfully. The process involves two main stages:-
Baseline Simulation:
- Performs a primary simulation run by calling the Orchestrator's
simulateExecutefunction. isStateOverrideis set tofalse.combinedGasOverrideis set totype(uint256).max.- This initial run establishes a baseline
gasUsedfor the Intent.
- Performs a primary simulation run by calling the Orchestrator's
-
Iterative Search:
- Iteratively increases the
combinedGasfield in a copy of the Intent. - Starts from
baseline_gasUsed + original_Intent.combinedGas. - Associated payment amounts (
prePaymentAmount,totalPaymentAmount) are adjusted accordingly in each iteration. - Continues until a call to the Orchestrator's
simulateExecute(withisStateOverride = falseand nocombinedGasOverride) succeeds by reverting withSimulationPassed.
- Iteratively increases the
-
Baseline Simulation:
-
Usage:
-
Parameters:
oc: Address of the Orchestrator contract.isPrePayment: Boolean indicating how payment is handled:- If
true: The gas-based payment is added toprePaymentAmount(andtotalPaymentAmount). - If
false: The gas-based payment is added only tototalPaymentAmount.
- If
paymentPerGasPrecision: Defines precision forpaymentPerGas.- Example: If
paymentPerGasis in Gwei,paymentTokenhas 18 decimals, and you wantpaymentPerGasto represent units with 9 decimal places of precision, this field would be9. - Payment amount is calculated as:
gas * paymentPerGas / (10 ** paymentPerGasPrecision).
- Example: If
paymentPerGas: Amount ofpaymentTokenadded to Intent's payment fields per unit of gas.combinedGasIncrement: Basis points value forcombinedGasincrement step (e.g.,100for 1%,10000for 100%).-
combinedGasis updated in each iteration by:current_combinedGas * combinedGasIncrement / 10000 -
Ensure this value is greater than
10000(e.g.,10100for a 1% increment) to guaranteecombinedGasincreases.
-
encodedIntent: The ABI-encoded Intent
-
Returns:
gasUsed: Gas consumed in the first successful simulation identified during the iterative search (extracted fromSimulationPassedrevert data).combinedGas: ThecombinedGasvalue from the Intent that resulted in the first successful simulation.
-
Reverts:
- If the initial baseline simulation (with maximum
combinedGas) fails. - If a
PaymentErroris encountered during the iterative search (increasingcombinedGasand payments won't resolve this).
- If the initial baseline simulation (with maximum
-
Parameters:
simulateV1Logs
-
Signature:
function simulateV1Logs( address oc, bool isPrePayment, uint8 paymentPerGasPrecision, uint256 paymentPerGas, uint256 combinedGasIncrement, uint256 combinedGasVerificationOffset, bytes calldata encodedIntent ) public payable virtual returns (uint256 gasUsed, uint256 combinedGas); -
Description:
- Extends the functionality of
simulateCombinedGas. - After determining
combinedGasandgasUsediteratively, it introduces acombinedGasVerificationOffset. - A final simulation run is performed by calling
simulateExecuteon the Orchestrator withisStateOverrideset totrue. - Goal: Generate a successful, non-reverting simulation trace compatible with tools like
eth_simulateV1for detailed execution log retrieval. - Payment amounts in the Intent are updated based on the determined
combinedGas(including the offset).
- Extends the functionality of
-
Usage:
-
State override requirements are detailed here.
-
Parameters:
combinedGasVerificationOffset: A static gas amount added to thecombinedGasvalue found by the iterative search. This helps account for minor gas variations (e.g., with P256 signature schemes).- All other parameters function identically to those in
simulateCombinedGas.
-
Returns:
gasUsed: Gas consumed during the final verification run.combinedGas: FinalcombinedGasused in the verification run.
-
Reverts:
- If any underlying simulation step fails.
- If the necessary state override for the
Simulatorcontract's balance is not in place, the final call to Orchestrator will likely revert withStateOverrideError().
-