Skip to content

Commit e05964b

Browse files
committed
feat: disallow deposits with output token set to 0x0
Signed-off-by: Matt Rice <[email protected]>
1 parent a5fbdf1 commit e05964b

File tree

5 files changed

+14
-581
lines changed

5 files changed

+14
-581
lines changed

contracts/SpokePool.sol

Lines changed: 3 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -342,90 +342,6 @@ abstract contract SpokePool is
342342
emit EmergencyDeletedRootBundle(rootBundleId);
343343
}
344344

345-
/**************************************
346-
* LEGACY DEPOSITOR FUNCTIONS *
347-
**************************************/
348-
349-
/**
350-
* @dev DEPRECATION NOTICE: this function is deprecated and will be removed in the future.
351-
* Please use deposit (under DEPOSITOR FUNCTIONS below) or depositV3 instead.
352-
* @notice Called by user to bridge funds from origin to destination chain. Depositor will effectively lock
353-
* tokens in this contract and receive a destination token on the destination chain. The origin => destination
354-
* token mapping is stored on the L1 HubPool.
355-
* @notice The caller must first approve this contract to spend amount of originToken.
356-
* @notice The originToken => destinationChainId must be enabled.
357-
* @notice This method is payable because the caller is able to deposit native token if the originToken is
358-
* wrappedNativeToken and this function will handle wrapping the native token to wrappedNativeToken.
359-
* @dev Produces a FundsDeposited event with an infinite expiry, meaning that this deposit can never expire.
360-
* Moreover, the event's outputToken is set to 0x0 meaning that this deposit can always be slow filled.
361-
* @param recipient Address to receive funds at on destination chain.
362-
* @param originToken Token to lock into this contract to initiate deposit.
363-
* @param amount Amount of tokens to deposit. Will be amount of tokens to receive less fees.
364-
* @param destinationChainId Denotes network where user will receive funds from SpokePool by a relayer.
365-
* @param relayerFeePct % of deposit amount taken out to incentivize a fast relayer.
366-
* @param quoteTimestamp Timestamp used by relayers to compute this deposit's realizedLPFeePct which is paid
367-
* to LP pool on HubPool.
368-
* @param message Arbitrary data that can be used to pass additional information to the recipient along with the tokens.
369-
* Note: this is intended to be used to pass along instructions for how a contract should use or allocate the tokens.
370-
*/
371-
function depositDeprecated_5947912356(
372-
address recipient,
373-
address originToken,
374-
uint256 amount,
375-
uint256 destinationChainId,
376-
int64 relayerFeePct,
377-
uint32 quoteTimestamp,
378-
bytes memory message,
379-
uint256 // maxCount. Deprecated.
380-
) public payable nonReentrant unpausedDeposits {
381-
_deposit(
382-
msg.sender,
383-
recipient,
384-
originToken,
385-
amount,
386-
destinationChainId,
387-
relayerFeePct,
388-
quoteTimestamp,
389-
message
390-
);
391-
}
392-
393-
/**
394-
* @dev DEPRECATION NOTICE: this function is deprecated and will be removed in the future.
395-
* Please use the other deposit or depositV3 instead.
396-
* @notice The only difference between depositFor and deposit is that the depositor address stored
397-
* in the relay hash can be overridden by the caller. This means that the passed in depositor
398-
* can speed up the deposit, which is useful if the deposit is taken from the end user to a middle layer
399-
* contract, like an aggregator or the SpokePoolVerifier, before calling deposit on this contract.
400-
* @notice The caller must first approve this contract to spend amount of originToken.
401-
* @notice The originToken => destinationChainId must be enabled.
402-
* @notice This method is payable because the caller is able to deposit native token if the originToken is
403-
* wrappedNativeToken and this function will handle wrapping the native token to wrappedNativeToken.
404-
* @param depositor Address who is credited for depositing funds on origin chain and can speed up the deposit.
405-
* @param recipient Address to receive funds at on destination chain.
406-
* @param originToken Token to lock into this contract to initiate deposit.
407-
* @param amount Amount of tokens to deposit. Will be amount of tokens to receive less fees.
408-
* @param destinationChainId Denotes network where user will receive funds from SpokePool by a relayer.
409-
* @param relayerFeePct % of deposit amount taken out to incentivize a fast relayer.
410-
* @param quoteTimestamp Timestamp used by relayers to compute this deposit's realizedLPFeePct which is paid
411-
* to LP pool on HubPool.
412-
* @param message Arbitrary data that can be used to pass additional information to the recipient along with the tokens.
413-
* Note: this is intended to be used to pass along instructions for how a contract should use or allocate the tokens.
414-
*/
415-
function depositFor(
416-
address depositor,
417-
address recipient,
418-
address originToken,
419-
uint256 amount,
420-
uint256 destinationChainId,
421-
int64 relayerFeePct,
422-
uint32 quoteTimestamp,
423-
bytes memory message,
424-
uint256 // maxCount. Deprecated.
425-
) public payable nonReentrant unpausedDeposits {
426-
_deposit(depositor, recipient, originToken, amount, destinationChainId, relayerFeePct, quoteTimestamp, message);
427-
}
428-
429345
/********************************************
430346
* DEPOSITOR FUNCTIONS *
431347
********************************************/
@@ -1294,6 +1210,9 @@ abstract contract SpokePool is
12941210
// Verify depositor is a valid EVM address.
12951211
params.depositor.checkAddress();
12961212

1213+
// Verify output token is not zero address.
1214+
if (params.outputToken == bytes32(0)) revert InvalidOutputToken();
1215+
12971216
// Require that quoteTimestamp has a maximum age so that depositors pay an LP fee based on recent HubPool usage.
12981217
// It is assumed that cross-chain timestamps are normally loosely in-sync, but clock drift can occur. If the
12991218
// SpokePool time stalls or lags significantly, it is still possible to make deposits by setting quoteTimestamp
@@ -1369,71 +1288,6 @@ abstract contract SpokePool is
13691288
);
13701289
}
13711290

1372-
function _deposit(
1373-
address depositor,
1374-
address recipient,
1375-
address originToken,
1376-
uint256 amount,
1377-
uint256 destinationChainId,
1378-
int64 relayerFeePct,
1379-
uint32 quoteTimestamp,
1380-
bytes memory message
1381-
) internal {
1382-
// We limit the relay fees to prevent the user spending all their funds on fees.
1383-
if (SignedMath.abs(relayerFeePct) >= 0.5e18) revert InvalidRelayerFeePct();
1384-
if (amount > MAX_TRANSFER_SIZE) revert MaxTransferSizeExceeded();
1385-
1386-
// Require that quoteTimestamp has a maximum age so that depositors pay an LP fee based on recent HubPool usage.
1387-
// It is assumed that cross-chain timestamps are normally loosely in-sync, but clock drift can occur. If the
1388-
// SpokePool time stalls or lags significantly, it is still possible to make deposits by setting quoteTimestamp
1389-
// within the configured buffer. The owner should pause deposits if this is undesirable. This will underflow if
1390-
// quoteTimestamp is more than depositQuoteTimeBuffer; this is safe but will throw an unintuitive error.
1391-
1392-
// slither-disable-next-line timestamp
1393-
if (getCurrentTime() - quoteTimestamp > depositQuoteTimeBuffer) revert InvalidQuoteTimestamp();
1394-
1395-
// Increment count of deposits so that deposit ID for this spoke pool is unique.
1396-
uint32 newDepositId = numberOfDeposits++;
1397-
1398-
// If the address of the origin token is a wrappedNativeToken contract and there is a msg.value with the
1399-
// transaction then the user is sending ETH. In this case, the ETH should be deposited to wrappedNativeToken.
1400-
if (originToken == address(wrappedNativeToken) && msg.value > 0) {
1401-
if (msg.value != amount) revert MsgValueDoesNotMatchInputAmount();
1402-
wrappedNativeToken.deposit{ value: msg.value }();
1403-
// Else, it is a normal ERC20. In this case pull the token from the user's wallet as per normal.
1404-
// Note: this includes the case where the L2 user has WETH (already wrapped ETH) and wants to bridge them.
1405-
// In this case the msg.value will be set to 0, indicating a "normal" ERC20 bridging action.
1406-
} else {
1407-
IERC20Upgradeable(originToken).safeTransferFrom(msg.sender, address(this), amount);
1408-
}
1409-
1410-
emit FundsDeposited(
1411-
originToken.toBytes32(), // inputToken
1412-
bytes32(0), // outputToken. Setting this to 0x0 means that the outputToken should be assumed to be the
1413-
// canonical token for the destination chain matching the inputToken. Therefore, this deposit
1414-
// can always be slow filled.
1415-
// - setting token to 0x0 will signal to off-chain validator that the "equivalent"
1416-
// token as the inputToken for the destination chain should be replaced here.
1417-
amount, // inputAmount
1418-
_computeAmountPostFees(amount, relayerFeePct), // outputAmount
1419-
// - output amount will be the deposit amount less relayerFeePct, which should now be set
1420-
// equal to realizedLpFeePct + gasFeePct + capitalCostFeePct where (gasFeePct + capitalCostFeePct)
1421-
// is equal to the old usage of `relayerFeePct`.
1422-
destinationChainId,
1423-
newDepositId,
1424-
quoteTimestamp,
1425-
INFINITE_FILL_DEADLINE, // fillDeadline. Default to infinite expiry because
1426-
// expired deposits refunds could be a breaking change for existing users of this function.
1427-
0, // exclusivityDeadline. Setting this to 0 along with the exclusiveRelayer to 0x0 means that there
1428-
// is no exclusive deadline
1429-
depositor.toBytes32(),
1430-
recipient.toBytes32(),
1431-
bytes32(0), // exclusiveRelayer. Setting this to 0x0 will signal to off-chain validator that there
1432-
// is no exclusive relayer.
1433-
message
1434-
);
1435-
}
1436-
14371291
function _distributeRelayerRefunds(
14381292
uint256 _chainId,
14391293
uint256 amountToReturn,

contracts/interfaces/SpokePoolInterface.sol

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,29 +46,6 @@ interface SpokePoolInterface {
4646

4747
function emergencyDeleteRootBundle(uint256 rootBundleId) external;
4848

49-
function depositDeprecated_5947912356(
50-
address recipient,
51-
address originToken,
52-
uint256 amount,
53-
uint256 destinationChainId,
54-
int64 relayerFeePct,
55-
uint32 quoteTimestamp,
56-
bytes memory message,
57-
uint256 maxCount
58-
) external payable;
59-
60-
function depositFor(
61-
address depositor,
62-
address recipient,
63-
address originToken,
64-
uint256 amount,
65-
uint256 destinationChainId,
66-
int64 relayerFeePct,
67-
uint32 quoteTimestamp,
68-
bytes memory message,
69-
uint256 maxCount
70-
) external payable;
71-
7249
function executeRelayerRefundLeaf(
7350
uint32 rootBundleId,
7451
SpokePoolInterface.RelayerRefundLeaf memory relayerRefundLeaf,

contracts/interfaces/V3SpokePoolInterface.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ interface V3SpokePoolInterface {
327327
error InvalidQuoteTimestamp();
328328
error InvalidFillDeadline();
329329
error InvalidExclusiveRelayer();
330+
error InvalidOutputToken();
330331
error MsgValueDoesNotMatchInputAmount();
331332
error NotExclusiveRelayer();
332333
error NoSlowFillsInExclusivityWindow();

test/evm/foundry/local/SpokePoolDeprecatedMethods.t.sol

Lines changed: 0 additions & 141 deletions
This file was deleted.

0 commit comments

Comments
 (0)