diff --git a/contracts/ConnectGelato.sol b/contracts/ConnectGelato.sol index d7dba7e..6680bc3 100644 --- a/contracts/ConnectGelato.sol +++ b/contracts/ConnectGelato.sol @@ -17,16 +17,17 @@ import { } from "@gelatonetwork/core/contracts/provider_modules/IGelatoProviderModule.sol"; import {Address} from "@gelatonetwork/core/contracts/external/Address.sol"; import {SafeMath} from "@gelatonetwork/core/contracts/external/SafeMath.sol"; +import {Stores} from "./instadapp/Stores.sol"; interface ConnectorInterface { - function connectorID() external view returns(uint _type, uint _id); function name() external pure returns (string memory); } /// @title ConnectGelato /// @notice Allows InstaDapp DSA to enter and exit Gelato Network +/// @dev Check out https://github.com/gelatodigital/gelato-kyber#how-gelato-works for an explanation /// @author gitpusha -contract ConnectGelato is ConnectorInterface { +contract ConnectGelato is ConnectorInterface, Stores { using Address for address payable; using SafeMath for uint256; @@ -49,7 +50,7 @@ contract ConnectGelato is ConnectorInterface { } /// @dev _id must be InstaConnectors.connectorLength+1 - function connectorID() external view override returns(uint _type, uint _id) { + function connectorID() public view override returns(uint _type, uint _id) { (_type, _id) = (1, id); } @@ -62,16 +63,26 @@ contract ConnectGelato is ConnectorInterface { } // ===== Gelato ENTRY APIs ====== + + /** + * @dev Enables first time users to pre-fund eth, whitelist an executor & register the + * ProviderModuleDSA.sol to be able to use Gelato + * @param _executor address of single execot node or gelato'S decentralized execution market + * @param _taskSpecs enables external providers to whitelist TaskSpecs on gelato + * @param _modules address of ProviderModuleDSA + * @param _ethToDeposit amount of eth to deposit on Gelato, only for self-providers + */ function multiProvide( address _executor, TaskSpec[] calldata _taskSpecs, - IGelatoProviderModule[] calldata _modules + IGelatoProviderModule[] calldata _modules, + uint256 _ethToDeposit ) public payable delegatecallOnly("ConnectGelato.multiProvide") { - try IGelatoProviders(gelatoCore).multiProvide{value: msg.value}( + try IGelatoProviders(gelatoCore).multiProvide{value: _ethToDeposit}( _executor, _taskSpecs, _modules @@ -83,6 +94,13 @@ contract ConnectGelato is ConnectorInterface { } } + /** + * @dev Submits a single, one-time task to Gelato + * @param _provider Consists of proxy module address (DSA) and provider address () + * who will pay for the transaction execution + * @param _task Task specifying the condition and the action connectors + * @param _expiryDate Default 0, othweise timestamp after which the task expires + */ function submitTask( Provider calldata _provider, Task calldata _task, @@ -99,11 +117,84 @@ contract ConnectGelato is ConnectorInterface { } } + /** + * @dev Submits single or mulitple Task Sequences to Gelato + * @param _provider Consists of proxy module address (DSA) and provider address () + * who will pay for the transaction execution + * @param _tasks A sequence of Tasks, can be a single or multiples + * @param _expiryDate Default 0, othweise timestamp after which the task expires + * @param _cycles How often the Task List should be executed, e.g. 5 times + */ + function submitTaskCycle( + Provider calldata _provider, + Task[] memory _tasks, + uint256 _expiryDate, + uint256 _cycles + ) + public + delegatecallOnly("ConnectGelato.submitTaskCycle") + { + try IGelatoCore(gelatoCore).submitTaskCycle( + _provider, + _tasks, + _expiryDate, + _cycles + ) { + } catch Error(string memory error) { + revert(string(abi.encodePacked("ConnectGelato.submitTaskCycle:", error))); + } catch { + revert("ConnectGelato.submitTaskCycle: unknown error"); + } + } + + /** + * @dev Submits single or mulitple Task Chains to Gelato + * @param _provider Consists of proxy module address (DSA) and provider address () + * who will pay for the transaction execution + * @param _tasks A sequence of Tasks, can be a single or multiples + * @param _expiryDate Default 0, othweise timestamp after which the task expires + * @param _sumOfRequestedTaskSubmits The TOTAL number of Task auto-submits + * that should have occured once the cycle is complete + */ + function submitTaskChain( + Provider calldata _provider, + Task[] memory _tasks, + uint256 _expiryDate, + uint256 _sumOfRequestedTaskSubmits + ) + public + delegatecallOnly("ConnectGelato.submitTaskChain") + { + try IGelatoCore(gelatoCore).submitTaskChain( + _provider, + _tasks, + _expiryDate, + _sumOfRequestedTaskSubmits + ) { + } catch Error(string memory error) { + revert(string(abi.encodePacked("ConnectGelato.submitTaskChain:", error))); + } catch { + revert("ConnectGelato.submitTaskChain: unknown error"); + } + } + + + + // ===== Gelato EXIT APIs ====== + + /** + * @dev Withdraws funds from Gelato, de-whitelists TaskSpecs and Provider Modules + * in one tx + * @param _withdrawAmount Amount of ETH to withdraw from Gelato + * @param _taskSpecs List of Task Specs to de-whitelist, default empty [] + * @param _modules List of Provider Modules to de-whitelist, default empty [] + */ function multiUnprovide( uint256 _withdrawAmount, TaskSpec[] memory _taskSpecs, - IGelatoProviderModule[] memory _modules + IGelatoProviderModule[] memory _modules, + uint256 _setId ) external delegatecallOnly("ConnectGelato.multiUnprovide") @@ -114,7 +205,7 @@ contract ConnectGelato is ConnectorInterface { _taskSpecs, _modules ) { - msg.sender.sendValue(address(this).balance.sub(balanceBefore)); + setUint(_setId, address(this).balance.sub(balanceBefore)); } catch Error(string memory error) { revert(string(abi.encodePacked("ConnectGelato.multiUnprovide:", error))); } catch { @@ -122,6 +213,10 @@ contract ConnectGelato is ConnectorInterface { } } + /** + * @dev Cancels outstanding Tasks + * @param _taskReceipts List of Task Receipts to cancel + */ function multiCancelTasks(TaskReceipt[] calldata _taskReceipts) external delegatecallOnly("ConnectGelato.multiCancelTasks") diff --git a/contracts/instadapp/Stores.sol b/contracts/instadapp/Stores.sol new file mode 100644 index 0000000..f2e3f62 --- /dev/null +++ b/contracts/instadapp/Stores.sol @@ -0,0 +1,66 @@ +// "SPDX-License-Identifier: MIT" +pragma solidity ^0.6.0; + +interface MemoryInterface { + function getUint(uint id) external returns (uint num); + function setUint(uint id, uint val) external; +} + +interface EventInterface { + function emitEvent(uint connectorType, uint connectorID, bytes32 eventCode, bytes calldata eventData) external; +} + + +contract Stores { + + /** + * @dev Return ethereum address + */ + function getEthAddr() internal pure returns (address) { + return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // ETH Address + } + + /** + * @dev Return memory variable address + */ + function getMemoryAddr() internal pure returns (address) { + return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address + } + + /** + * @dev Return InstaEvent Address. + */ + function getEventAddr() internal pure returns (address) { + return 0x2af7ea6Cb911035f3eb1ED895Cb6692C39ecbA97; // InstaEvent Address + } + + /** + * @dev Get Uint value from InstaMemory Contract. + */ + function getUint(uint getId, uint val) internal returns (uint returnVal) { + returnVal = getId == 0 ? val : MemoryInterface(getMemoryAddr()).getUint(getId); + } + + /** + * @dev Set Uint value in InstaMemory Contract. + */ + function setUint(uint setId, uint val) virtual internal { + if (setId != 0) MemoryInterface(getMemoryAddr()).setUint(setId, val); + } + + /** + * @dev emit event on event contract + */ + function emitEvent(bytes32 eventCode, bytes memory eventData) virtual internal { + (uint model, uint id) = connectorID(); + EventInterface(getEventAddr()).emitEvent(model, id, eventCode, eventData); + } + + /** + * @dev Connector Details - needs to be changed before deployment + */ + function connectorID() public view virtual returns(uint model, uint id) { + (model, id) = (0, 0); + } + +} diff --git a/test/1_mv-DAI-DSR-Compound.test.js b/test/1_mv-DAI-DSR-Compound.test.js index 724010c..936ba44 100644 --- a/test/1_mv-DAI-DSR-Compound.test.js +++ b/test/1_mv-DAI-DSR-Compound.test.js @@ -305,7 +305,12 @@ describe("Move DAI lending from DSR to Compound", function () { await bre.run("abi-encode-withselector", { abi: require("../artifacts/ConnectGelato.json").abi, functionname: "multiProvide", - inputs: [userAddress, [], [providerModuleDSA.address]], + inputs: [ + userAddress, + [], + [providerModuleDSA.address], + TASK_AUTOMATION_FUNDS, + ], }), ], // datas userAddress, // origin