DeFi Saver
Search…
Recipe Executor
Recipe Executor is the main entry point of execution of recipes; it can be called directly (when a user manually executes a set of actions) or is called through StrategyExecutor when the Recipe is part of a strategy. The contract checks if the first action is a special flash loan action type and adequately sets up the code to execute the flash loan.
Recipe Executor is always called through a DSProxy and can't hold any state. executeRecipe() is used when the recipe is executed manually and executeRecipeFromStrategy() is called by StrategyExecutor when it's part of a strategy.
1
/// @dev List of actions grouped as a recipe
2
/// @param name Name of the recipe useful for logging what recipe is executing
3
/// @param callData Array of calldata inputs to each action
4
/// @param subData Used only as part of strategy, subData injected from StrategySub.subData
5
/// @param actionIds Array of identifiers for actions - bytes4(keccak256(ActionName))
6
/// @param paramMapping Describes how inputs to functions are piped from return/subbed values
7
struct Recipe {
8
string name;
9
bytes[] callData;
10
bytes32[] subData;
11
bytes4[] actionIds;
12
uint8[][] paramMapping;
13
}
Copied!
When the recipe is called through the StrategyExecutor there are additional checks if the triggers are executed correctly. All triggers must return true for the execution to continue. After that, from the Strategy data a new Recipe object is created and goes through the same flow as a manually executed recipe.
Triggers can be changeable! If Trigger returns true to a isChangeable() call after the trigger is checked, the sub-data of that trigger can be updated. Useful for strategies, for example, where on every five days some recipe happens, trigger adds five days from the last execution as the next trigger date.
Recipe Executor also handles a particular type of actions Flash loan actions. Flash loan actions are always sent first, and they callback the Recipe Executor through the _executeActionsFromFL function.
Below is the interface of the contract:
1
contract RecipeExecutor {
2
3
/// @notice Called directly through DsProxy to execute a recipe
4
/// @dev This is the main entry point for Recipes executed manually
5
/// @param _currRecipe Recipe to be executed
6
function executeRecipe(Recipe calldata _currRecipe) public payable;
7
8
/// @notice Called by users DSProxy through the ProxyAuth to execute a recipe & check triggers
9
/// @param _subId Id of the subscription we want to execute
10
/// @param _actionCallData All input data needed to execute actions
11
/// @param _triggerCallData All input data needed to check triggers
12
/// @param _strategyIndex Which strategy in a bundle, need to specify because when sub is part of a bundle
13
/// @param _sub All the data related to the strategies Recipe
14
function executeRecipeFromStrategy(
15
uint256 _subId,
16
bytes[] calldata _actionCallData,
17
bytes[] calldata _triggerCallData,
18
uint256 _strategyIndex,
19
StrategySub memory _sub
20
) public payable
21
22
function _executeActionsFromFL(Recipe calldata _currRecipe, bytes32 _flAmount) public payable
23
}
Copied!
Last modified 1d ago
Copy link