Random task execution
In a scenario where user takes a flash loan, `_parseFLAndExecute()` gives the flash loan wrapper contract (FLAaveV2, FLDyDx) the permission to execute functions on behalf of the user's `DSProxy`. This execution permission is revoked only after the entire recipe execution is finished, which means that in case that any of the external calls along the recipe execution is malicious, it might call `executeAction()` back and inject any task it wishes (e.g. take user's funds out, drain approved tokens, etc)\\n```\\nfunction executeOperation(\\n    address[] memory \\_assets,\\n    uint256[] memory \\_amounts,\\n    uint256[] memory \\_fees,\\n    address \\_initiator,\\n    bytes memory \\_params\\n) public returns (bool) {\\n    require(msg.sender == AAVE\\_LENDING\\_POOL, ERR\\_ONLY\\_AAVE\\_CALLER);\\n    require(\\_initiator == address(this), ERR\\_SAME\\_CALLER);\\n\\n    (Task memory currTask, address proxy) = abi.decode(\\_params, (Task, address));\\n\\n    // Send FL amounts to user proxy\\n    for (uint256 i = 0; i < \\_assets.length; ++i) {\\n        \\_assets[i].withdrawTokens(proxy, \\_amounts[i]);\\n    }\\n\\n    address payable taskExecutor = payable(registry.getAddr(TASK\\_EXECUTOR\\_ID));\\n\\n    // call Action execution\\n    IDSProxy(proxy).execute{value: address(this).balance}(\\n        taskExecutor,\\n        abi.encodeWithSelector(CALLBACK\\_SELECTOR, currTask, bytes32(\\_amounts[0] + \\_fees[0]))\\n    );\\n\\n    // return FL\\n    for (uint256 i = 0; i < \\_assets.length; i++) {\\n        \\_assets[i].approveToken(address(AAVE\\_LENDING\\_POOL), \\_amounts[i] + \\_fees[i]);\\n    }\\n\\n    return true;\\n}\\n```\\n
A reentrancy guard (mutex) that covers the entire content of FLAaveV2.executeOperation/FLDyDx.callFunction should be used to prevent such attack.
```\\nfunction executeOperation(\\n    address[] memory \\_assets,\\n    uint256[] memory \\_amounts,\\n    uint256[] memory \\_fees,\\n    address \\_initiator,\\n    bytes memory \\_params\\n) public returns (bool) {\\n    require(msg.sender == AAVE\\_LENDING\\_POOL, ERR\\_ONLY\\_AAVE\\_CALLER);\\n    require(\\_initiator == address(this), ERR\\_SAME\\_CALLER);\\n\\n    (Task memory currTask, address proxy) = abi.decode(\\_params, (Task, address));\\n\\n    // Send FL amounts to user proxy\\n    for (uint256 i = 0; i < \\_assets.length; ++i) {\\n        \\_assets[i].withdrawTokens(proxy, \\_amounts[i]);\\n    }\\n\\n    address payable taskExecutor = payable(registry.getAddr(TASK\\_EXECUTOR\\_ID));\\n\\n    // call Action execution\\n    IDSProxy(proxy).execute{value: address(this).balance}(\\n        taskExecutor,\\n        abi.encodeWithSelector(CALLBACK\\_SELECTOR, currTask, bytes32(\\_amounts[0] + \\_fees[0]))\\n    );\\n\\n    // return FL\\n    for (uint256 i = 0; i < \\_assets.length; i++) {\\n        \\_assets[i].approveToken(address(AAVE\\_LENDING\\_POOL), \\_amounts[i] + \\_fees[i]);\\n    }\\n\\n    return true;\\n}\\n```\\n