@@ -28,17 +28,13 @@ contract L1GNS is GNS, L1GNSV1Storage, L1ArbitrumMessenger {
28
28
29
29
/// @dev Emitted when a subgraph was sent to L2 through the bridge
30
30
event SubgraphSentToL2 (uint256 indexed _subgraphID , address indexed _l2Owner );
31
- /// @dev Emitted when the address of the Arbitrum Inbox was updated
32
- event ArbitrumInboxAddressUpdated (address _inbox );
33
31
34
- /**
35
- * @dev sets the addresses for L1 inbox provided by Arbitrum
36
- * @param _inbox Address of the Inbox that is part of the Arbitrum Bridge
37
- */
38
- function setArbitrumInboxAddress (address _inbox ) external onlyGovernor {
39
- arbitrumInboxAddress = _inbox;
40
- emit ArbitrumInboxAddressUpdated (_inbox);
41
- }
32
+ /// @dev Emitted when a curator's balance for a subgraph was sent to L2
33
+ event CuratorBalanceSentToL2 (
34
+ uint256 indexed _subgraphID ,
35
+ address indexed _curator ,
36
+ uint256 _tokens
37
+ );
42
38
43
39
/**
44
40
* @notice Send a subgraph's data and tokens to L2.
@@ -72,29 +68,41 @@ contract L1GNS is GNS, L1GNSV1Storage, L1ArbitrumMessenger {
72
68
subgraphData.disabled = true ;
73
69
subgraphData.vSignal = 0 ;
74
70
75
- bytes memory extraData = _encodeSubgraphDataForL2 (_subgraphID, _l2Owner, subgraphData);
71
+ // We send only the subgraph owner's tokens and nsignal to L2,
72
+ // and for everyone else we set the withdrawableGRT so that they can choose
73
+ // to withdraw or migrate their signal.
74
+ uint256 ownerNSignal = subgraphData.curatorNSignal[msg .sender ];
75
+ uint256 totalSignal = subgraphData.nSignal;
76
76
77
- bytes memory data = abi.encode (_maxSubmissionCost, extraData);
78
- IGraphToken grt = graphToken ();
79
- ITokenGateway gateway = graphTokenGateway ();
80
- grt.approve (address (gateway), curationTokens);
81
- gateway.outboundTransfer { value: msg .value }({
82
- _token: address (grt),
83
- _to: counterpartGNSAddress,
84
- _amount: curationTokens,
85
- _maxGas: _maxGas,
86
- _gasPriceBid: _gasPriceBid,
87
- _data: data
88
- });
77
+ // Get owner share of tokens to be sent to L2
78
+ uint256 tokensForL2 = ownerNSignal.mul (curationTokens).div (totalSignal);
79
+ // This leaves the subgraph as if it was deprecated,
80
+ // so other curators can withdraw:
81
+ subgraphData.curatorNSignal[msg .sender ] = 0 ;
82
+ subgraphData.nSignal = totalSignal.sub (ownerNSignal);
83
+ subgraphData.withdrawableGRT = curationTokens.sub (tokensForL2);
84
+
85
+ bytes memory extraData = abi.encode (
86
+ uint8 (IL2GNS.L1MessageCodes.RECEIVE_SUBGRAPH_CODE),
87
+ abi.encode (_subgraphID, _l2Owner)
88
+ );
89
+
90
+ _sendTokensAndMessageToL2GNS (
91
+ tokensForL2,
92
+ _maxGas,
93
+ _gasPriceBid,
94
+ _maxSubmissionCost,
95
+ extraData
96
+ );
89
97
90
98
subgraphData.reserveRatioDeprecated = 0 ;
91
99
_burnNFT (_subgraphID);
92
100
emit SubgraphSentToL2 (_subgraphID, _l2Owner);
93
101
}
94
102
95
103
/**
96
- * @notice Claim the balance for a curator's signal in a subgraph that was
97
- * migrated to L2, by sending a retryable ticket to the L2GNS .
104
+ * @notice Send the balance for a curator's signal in a subgraph that was
105
+ * migrated to L2, using the L1GraphTokenGateway .
98
106
* The balance will be claimed for a beneficiary address, as this method can be
99
107
* used by curators that use a contract address in L1 that may not exist in L2.
100
108
* This will set the curator's signal on L1 to zero, so the caller must ensure
@@ -105,87 +113,73 @@ contract L1GNS is GNS, L1GNSV1Storage, L1ArbitrumMessenger {
105
113
* @param _maxGas Max gas to use for the L2 retryable ticket
106
114
* @param _gasPriceBid Gas price bid for the L2 retryable ticket
107
115
* @param _maxSubmissionCost Max submission cost for the L2 retryable ticket
108
- * @return The sequence ID for the retryable ticket, as returned by the Arbitrum inbox.
109
116
*/
110
- function claimCuratorBalanceToBeneficiaryOnL2 (
117
+ function sendCuratorBalanceToBeneficiaryOnL2 (
111
118
uint256 _subgraphID ,
112
119
address _beneficiary ,
113
120
uint256 _maxGas ,
114
121
uint256 _gasPriceBid ,
115
122
uint256 _maxSubmissionCost
116
- ) external payable notPartialPaused returns ( bytes memory ) {
123
+ ) external payable notPartialPaused {
117
124
require (subgraphMigratedToL2[_subgraphID], "!MIGRATED " );
118
125
119
126
// The Arbitrum bridge will check this too, we just check here for an early exit
120
127
require (_maxSubmissionCost != 0 , "NO_SUBMISSION_COST " );
121
128
122
- L2GasParams memory gasParams = L2GasParams (_maxSubmissionCost, _maxGas, _gasPriceBid);
123
-
124
- uint256 curatorNSignal = getCuratorSignal (_subgraphID, msg .sender );
129
+ SubgraphData storage subgraphData = _getSubgraphData (_subgraphID);
130
+ uint256 curatorNSignal = subgraphData.curatorNSignal[msg .sender ];
125
131
require (curatorNSignal != 0 , "NO_SIGNAL " );
126
- bytes memory outboundCalldata = getClaimCuratorBalanceOutboundCalldata (
127
- _subgraphID,
128
- curatorNSignal,
129
- msg .sender ,
130
- _beneficiary
132
+ uint256 subgraphNSignal = subgraphData.nSignal;
133
+ require (subgraphNSignal != 0 , "NO_SUBGRAPH_SIGNAL " );
134
+
135
+ uint256 tokensForL2 = curatorNSignal.mul (subgraphData.withdrawableGRT).div (subgraphNSignal);
136
+ bytes memory extraData = abi.encode (
137
+ uint8 (IL2GNS.L1MessageCodes.RECEIVE_CURATOR_BALANCE_CODE),
138
+ abi.encode (_subgraphID, _beneficiary)
131
139
);
132
140
133
- // Similarly to withdrawing from a deprecated subgraph,
134
- // we remove the curator's signal from the subgraph.
135
- SubgraphData storage subgraphData = _getSubgraphData (_subgraphID);
141
+ // Set the subgraph as if the curator had withdrawn their tokens
136
142
subgraphData.curatorNSignal[msg .sender ] = 0 ;
137
- subgraphData.nSignal = subgraphData.nSignal.sub (curatorNSignal);
138
-
139
- uint256 seqNum = sendTxToL2 ({
140
- _inbox: arbitrumInboxAddress,
141
- _to: counterpartGNSAddress,
142
- _user: msg .sender ,
143
- _l1CallValue: msg .value ,
144
- _l2CallValue: 0 ,
145
- _l2GasParams: gasParams,
146
- _data: outboundCalldata
147
- });
148
-
149
- return abi.encode (seqNum);
150
- }
151
-
152
- /**
153
- * @notice Get the outbound calldata that will be sent to L2
154
- * when calling claimCuratorBalanceToBeneficiaryOnL2.
155
- * This can be useful to estimate the L2 retryable ticket parameters.
156
- * @param _subgraphID Subgraph ID
157
- * @param _curatorNSignal Curator's signal in the subgraph
158
- * @param _curator Curator address
159
- * @param _beneficiary Address that will own the signal in L2
160
- */
161
- function getClaimCuratorBalanceOutboundCalldata (
162
- uint256 _subgraphID ,
163
- uint256 _curatorNSignal ,
164
- address _curator ,
165
- address _beneficiary
166
- ) public pure returns (bytes memory ) {
167
- return
168
- abi.encodeWithSelector (
169
- IL2GNS.claimL1CuratorBalanceToBeneficiary.selector ,
170
- _subgraphID,
171
- _curator,
172
- _curatorNSignal,
173
- _beneficiary
174
- );
143
+ subgraphData.nSignal = subgraphNSignal.sub (curatorNSignal);
144
+ subgraphData.withdrawableGRT = subgraphData.withdrawableGRT.sub (tokensForL2);
145
+
146
+ // Send the tokens and data to L2 using the L1GraphTokenGateway
147
+ _sendTokensAndMessageToL2GNS (
148
+ tokensForL2,
149
+ _maxGas,
150
+ _gasPriceBid,
151
+ _maxSubmissionCost,
152
+ extraData
153
+ );
175
154
}
176
155
177
156
/**
178
- * @dev Encodes the subgraph data as callhook parameters
179
- * for the L2 migration.
180
- * @param _subgraphID Subgraph ID
181
- * @param _l2Owner Owner of the subgraph on L2
182
- * @param _subgraphData Subgraph data
157
+ * @notice Sends a message to the L2GNS with some extra data,
158
+ * also sending some tokens, using the L1GraphTokenGateway.
159
+ * @param _tokens Amount of tokens to send to L2
160
+ * @param _maxGas Max gas to use for the L2 retryable ticket
161
+ * @param _gasPriceBid Gas price bid for the L2 retryable ticket
162
+ * @param _maxSubmissionCost Max submission cost for the L2 retryable ticket
163
+ * @param _extraData Extra data for the callhook on L2GNS
183
164
*/
184
- function _encodeSubgraphDataForL2 (
185
- uint256 _subgraphID ,
186
- address _l2Owner ,
187
- SubgraphData storage _subgraphData
188
- ) internal view returns (bytes memory ) {
189
- return abi.encode (_subgraphID, _l2Owner, _subgraphData.nSignal);
165
+ function _sendTokensAndMessageToL2GNS (
166
+ uint256 _tokens ,
167
+ uint256 _maxGas ,
168
+ uint256 _gasPriceBid ,
169
+ uint256 _maxSubmissionCost ,
170
+ bytes memory _extraData
171
+ ) internal {
172
+ bytes memory data = abi.encode (_maxSubmissionCost, _extraData);
173
+ IGraphToken grt = graphToken ();
174
+ ITokenGateway gateway = graphTokenGateway ();
175
+ grt.approve (address (gateway), _tokens);
176
+ gateway.outboundTransfer { value: msg .value }(
177
+ address (grt),
178
+ counterpartGNSAddress,
179
+ _tokens,
180
+ _maxGas,
181
+ _gasPriceBid,
182
+ data
183
+ );
190
184
}
191
185
}
0 commit comments