forked from stone4419/chainlink-gmx-automation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DepositAutomation.sol
128 lines (110 loc) · 5.45 KB
/
DepositAutomation.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {LibGMXEventLogDecoder} from "./libraries/LibGMXEventLogDecoder.sol";
import {GMXAutomationBase} from "./GMXAutomationBase.sol";
// gmx-synthetics
import {EventUtils} from "gmx-synthetics/event/EventUtils.sol";
import {DataStore} from "gmx-synthetics/data/DataStore.sol";
import {Reader} from "gmx-synthetics/reader/Reader.sol";
import {Market} from "gmx-synthetics/market/Market.sol";
import {OracleUtils} from "gmx-synthetics/oracle/OracleUtils.sol";
import {DepositHandler} from "gmx-synthetics/exchange/DepositHandler.sol";
// chainlink
import {FeedLookupCompatibleInterface} from "chainlink/dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol";
import {ILogAutomation, Log} from "chainlink/dev/automation/2_1/interfaces/ILogAutomation.sol";
/// @title Deposit Automation
/// @author Alex Roan - Cyfrin (@alexroan)
contract DepositAutomation is ILogAutomation, FeedLookupCompatibleInterface, GMXAutomationBase {
using LibGMXEventLogDecoder for Log;
using LibGMXEventLogDecoder for EventUtils.EventLogData;
// ERRORS
error DepositAutomation_IncorrectEventName(string eventName, string expectedEventName);
// CONSTANTS
string public constant EXPECTED_LOG_EVENTNAME = "DepositCreated";
string public constant STRING_DATASTREAMS_FEEDLABEL = "feedIDHex";
string public constant STRING_DATASTREAMS_QUERYLABEL = "BlockNumber";
// IMMUTABLES
DepositHandler public immutable i_depositHandler;
/// @param dataStore the DataStore contract address - immutable
/// @param reader the Reader contract address - immutable
/// @param depositHandler the DepositHandler contract address - immutable
constructor(DataStore dataStore, Reader reader, DepositHandler depositHandler)
GMXAutomationBase(dataStore, reader)
{
i_depositHandler = depositHandler;
}
///////////////////////////
// AUTOMATION FUNCTIONS
///////////////////////////
function checkLog(Log calldata log) external returns (bool, bytes memory) {
// Decode Event Log 1
(
, //msgSender,
string memory eventName,
EventUtils.EventLogData memory eventData
) = log.decodeEventLog();
// Ensure that the event name is equal to the expected event name
if (keccak256(abi.encode(eventName)) != keccak256(abi.encode(EXPECTED_LOG_EVENTNAME))) {
revert DepositAutomation_IncorrectEventName(eventName, EXPECTED_LOG_EVENTNAME);
}
// Decode the EventData struct to retrieve relevant data
(bytes32 key, address market,,, address[] memory longTokenSwapPath, address[] memory shortTokenSwapPath) =
eventData.decodeEventData();
// For each address in:
// - market
// - longTokenSwapPath[]
// - shortTokenSwapPath[]
// retrieve the Props struct from the DataStore. Use Props.marketToken to retrieve the feedId
// and add to a list of feedIds.
// Push the market feedId to the set
Market.Props memory marketProps = i_reader.getMarket(i_dataStore, market);
_addPropsToMapping(marketProps);
// Push the longTokenSwapPath feedIds to the set
for (uint256 i = 0; i < longTokenSwapPath.length; i++) {
Market.Props memory longTokenSwapPathProps = i_reader.getMarket(i_dataStore, longTokenSwapPath[i]);
_addPropsToMapping(longTokenSwapPathProps);
}
// Push the shortTokenSwapPath feedIds to the set
for (uint256 i = 0; i < shortTokenSwapPath.length; i++) {
Market.Props memory shortTokenSwapPathProps = i_reader.getMarket(i_dataStore, shortTokenSwapPath[i]);
_addPropsToMapping(shortTokenSwapPathProps);
}
// Clear the feedIdSet
(string[] memory feedIds, address[] memory addresses) = _flushMapping();
// Construct the data streams lookup error
revert FeedLookup(
STRING_DATASTREAMS_FEEDLABEL,
feedIds,
STRING_DATASTREAMS_QUERYLABEL,
log.blockNumber,
abi.encode(key, addresses)
);
}
/// @notice Check the callback
/// @dev Encode the values and extra data into performData and return true
function checkCallback(bytes[] calldata values, bytes calldata extraData)
external
pure
returns (bool, bytes memory)
{
return (true, abi.encode(values, extraData));
}
/// @notice Perform the upkeep
/// @param performData the data returned from checkCallback. Encoded:
/// - bytes[] values. Each value contains a signed report by the DON, and must be decoded:
/// - bytes32[3] memory reportContext,
/// - bytes memory reportData, <- This is where we can access the token and price
/// - bytes32[] memory rs,
/// - bytes32[] memory ss,
/// - bytes32 rawVs
/// - bytes extraData <- This is where the key is
/// @dev Decode the performData and call executeOrder
function performUpkeep(bytes calldata performData) external {
(bytes[] memory values, bytes memory extraData) = abi.decode(performData, (bytes[], bytes));
(bytes32 key, address[] memory addresses) = abi.decode(extraData, (bytes32, address[]));
OracleUtils.SetPricesParams memory oracleParams;
oracleParams.realtimeFeedTokens = addresses;
oracleParams.realtimeFeedData = values;
i_depositHandler.executeDeposit(key, oracleParams);
}
}