@@ -125,7 +125,7 @@ abstract contract SpokePool is
125125
126126 bytes32 public constant UPDATE_V3_DEPOSIT_DETAILS_HASH =
127127 keccak256 (
128- "UpdateDepositDetails(uint256 depositId,uint256 originChainId,uint256 updatedOutputAmount,address updatedRecipient,bytes updatedMessage) "
128+ "UpdateDepositDetails(uint32 depositId,uint256 originChainId,uint256 updatedOutputAmount,address updatedRecipient,bytes updatedMessage) "
129129 );
130130
131131 // Default chain Id used to signify that no repayment is requested, for example when executing a slow fill.
@@ -549,92 +549,59 @@ abstract contract SpokePool is
549549 uint32 exclusivityPeriod ,
550550 bytes calldata message
551551 ) public payable override nonReentrant unpausedDeposits {
552- _depositV3 (
553- depositor,
554- recipient,
552+ // Check that deposit route is enabled for the input token. There are no checks required for the output token
553+ // which is pulled from the relayer at fill time and passed through this contract atomically to the recipient.
554+ if (! enabledDepositRoutes[inputToken][destinationChainId]) revert DisabledRoute ();
555+
556+ // Require that quoteTimestamp has a maximum age so that depositors pay an LP fee based on recent HubPool usage.
557+ // It is assumed that cross-chain timestamps are normally loosely in-sync, but clock drift can occur. If the
558+ // SpokePool time stalls or lags significantly, it is still possible to make deposits by setting quoteTimestamp
559+ // within the configured buffer. The owner should pause deposits/fills if this is undesirable.
560+ // This will underflow if quoteTimestamp is more than depositQuoteTimeBuffer;
561+ // this is safe but will throw an unintuitive error.
562+
563+ // slither-disable-next-line timestamp
564+ uint256 currentTime = getCurrentTime ();
565+ if (currentTime - quoteTimestamp > depositQuoteTimeBuffer) revert InvalidQuoteTimestamp ();
566+
567+ // fillDeadline is relative to the destination chain.
568+ // Don’t allow fillDeadline to be more than several bundles into the future.
569+ // This limits the maximum required lookback for dataworker and relayer instances.
570+ // Also, don't allow fillDeadline to be in the past. This poses a potential UX issue if the destination
571+ // chain time keeping and this chain's time keeping are out of sync but is not really a practical hurdle
572+ // unless they are significantly out of sync or the depositor is setting very short fill deadlines. This latter
573+ // situation won't be a problem for honest users.
574+ if (fillDeadline < currentTime || fillDeadline > currentTime + fillDeadlineBuffer) revert InvalidFillDeadline ();
575+
576+ // If the address of the origin token is a wrappedNativeToken contract and there is a msg.value with the
577+ // transaction then the user is sending the native token. In this case, the native token should be
578+ // wrapped.
579+ if (inputToken == address (wrappedNativeToken) && msg .value > 0 ) {
580+ if (msg .value != inputAmount) revert MsgValueDoesNotMatchInputAmount ();
581+ wrappedNativeToken.deposit { value: msg .value }();
582+ // Else, it is a normal ERC20. In this case pull the token from the caller as per normal.
583+ // Note: this includes the case where the L2 caller has WETH (already wrapped ETH) and wants to bridge them.
584+ // In this case the msg.value will be set to 0, indicating a "normal" ERC20 bridging action.
585+ } else {
586+ // msg.value should be 0 if input token isn't the wrapped native token.
587+ if (msg .value != 0 ) revert MsgValueDoesNotMatchInputAmount ();
588+ IERC20Upgradeable (inputToken).safeTransferFrom (msg .sender , address (this ), inputAmount);
589+ }
590+
591+ emit V3FundsDeposited (
555592 inputToken,
556593 outputToken,
557594 inputAmount,
558595 outputAmount,
559596 destinationChainId,
560- exclusiveRelayer,
561597 // Increment count of deposits so that deposit ID for this spoke pool is unique.
562- // @dev Implicitly casts from uint32 to uint256 by padding the left-most bytes with zeros. Guarantees
563- // that the 24 most significant bytes are 0.
564598 numberOfDeposits++ ,
565599 quoteTimestamp,
566600 fillDeadline,
567- uint32 (getCurrentTime ()) + exclusivityPeriod,
568- message
569- );
570- }
571-
572- /**
573- * @notice See depositV3 for details. This function is identical to depositV3 except that it does not use the
574- * global deposit ID counter as a deposit nonce, instead allowing the caller to pass in a deposit nonce. This
575- * function is designed to be used by anyone who wants to pre-compute their resultant relay data hash, which
576- * could be useful for filling a deposit faster and avoiding any risk of a relay hash unexpectedly changing
577- * due to another deposit front-running this one and incrementing the global deposit ID counter.
578- * @dev This is labeled "unsafe" because there is no guarantee that the depositId emitted in the resultant
579- * V3FundsDeposited event is unique which means that the
580- * corresponding fill might collide with an existing relay hash on the destination chain SpokePool,
581- * which would make this deposit unfillable. In this case, the depositor would subsequently receive a refund
582- * of `inputAmount` of `inputToken` on the origin chain after the fill deadline.
583- * @dev On the destination chain, the hash of the deposit data will be used to uniquely identify this deposit, so
584- * modifying any params in it will result in a different hash and a different deposit. The hash will comprise
585- * all parameters to this function along with this chain's chainId(). Relayers are only refunded for filling
586- * deposits with deposit hashes that map exactly to the one emitted by this contract.
587- * @param depositNonce The nonce that uniquely identifies this deposit. This function will combine this parameter
588- * with the msg.sender address to create a unique uint256 depositNonce and ensure that the msg.sender cannot
589- * use this function to front-run another depositor's unsafe deposit. This function guarantees that the resultant
590- * deposit nonce will not collide with a safe uint256 deposit nonce whose 24 most significant bytes are always 0.
591- * @param depositor See identically named parameter in depositV3() comments.
592- * @param recipient See identically named parameter in depositV3() comments.
593- * @param inputToken See identically named parameter in depositV3() comments.
594- * @param outputToken See identically named parameter in depositV3() comments.
595- * @param inputAmount See identically named parameter in depositV3() comments.
596- * @param outputAmount See identically named parameter in depositV3() comments.
597- * @param destinationChainId See identically named parameter in depositV3() comments.
598- * @param exclusiveRelayer See identically named parameter in depositV3() comments.
599- * @param quoteTimestamp See identically named parameter in depositV3() comments.
600- * @param fillDeadline See identically named parameter in depositV3() comments.
601- * @param exclusivityPeriod See identically named parameter in depositV3() comments.
602- * @param message See identically named parameter in depositV3() comments.
603- */
604- function unsafeDepositV3 (
605- address depositor ,
606- address recipient ,
607- address inputToken ,
608- address outputToken ,
609- uint256 inputAmount ,
610- uint256 outputAmount ,
611- uint256 destinationChainId ,
612- address exclusiveRelayer ,
613- uint256 depositNonce ,
614- uint32 quoteTimestamp ,
615- uint32 fillDeadline ,
616- uint32 exclusivityPeriod ,
617- bytes calldata message
618- ) public payable nonReentrant unpausedDeposits {
619- // @dev Create the uint256 deposit ID by concatenating the msg.sender and depositor address with the inputted
620- // depositNonce parameter. The resultant 32 byte string will be hashed and then casted to an "unsafe"
621- // uint256 deposit ID. The probability that the resultant ID collides with a "safe" deposit ID is
622- // equal to the chance that the first 28 bytes of the hash are 0, which is too small for us to consider.
623-
624- uint256 depositId = getUnsafeDepositId (msg .sender , depositor, depositNonce);
625- _depositV3 (
601+ uint32 (currentTime) + exclusivityPeriod,
626602 depositor,
627603 recipient,
628- inputToken,
629- outputToken,
630- inputAmount,
631- outputAmount,
632- destinationChainId,
633604 exclusiveRelayer,
634- depositId,
635- quoteTimestamp,
636- fillDeadline,
637- uint32 (getCurrentTime ()) + exclusivityPeriod,
638605 message
639606 );
640607 }
@@ -788,7 +755,7 @@ abstract contract SpokePool is
788755 */
789756 function speedUpV3Deposit (
790757 address depositor ,
791- uint256 depositId ,
758+ uint32 depositId ,
792759 uint256 updatedOutputAmount ,
793760 address updatedRecipient ,
794761 bytes calldata updatedMessage ,
@@ -1117,99 +1084,10 @@ abstract contract SpokePool is
11171084 return block .timestamp ; // solhint-disable-line not-rely-on-time
11181085 }
11191086
1120- /**
1121- * @notice Returns the deposit ID for an unsafe deposit. This function is used to compute the deposit ID
1122- * in unsafeDepositV3 and is provided as a convenience.
1123- * @dev msgSenderand depositor are both used as inputs to allow passthrough depositors to create unique
1124- * deposit hash spaces for unique depositors.
1125- * @param msgSender The caller of the transaction used as input to produce the deposit ID.
1126- * @param depositor The depositor address used as input to produce the deposit ID.
1127- * @param depositNonce The nonce used as input to produce the deposit ID.
1128- * @return The deposit ID for the unsafe deposit.
1129- */
1130- function getUnsafeDepositId (
1131- address msgSender ,
1132- address depositor ,
1133- uint256 depositNonce
1134- ) public pure returns (uint256 ) {
1135- return uint256 (keccak256 (abi.encodePacked (msgSender, depositor, depositNonce)));
1136- }
1137-
11381087 /**************************************
11391088 * INTERNAL FUNCTIONS *
11401089 **************************************/
11411090
1142- function _depositV3 (
1143- address depositor ,
1144- address recipient ,
1145- address inputToken ,
1146- address outputToken ,
1147- uint256 inputAmount ,
1148- uint256 outputAmount ,
1149- uint256 destinationChainId ,
1150- address exclusiveRelayer ,
1151- uint256 depositId ,
1152- uint32 quoteTimestamp ,
1153- uint32 fillDeadline ,
1154- uint32 exclusivityDeadline ,
1155- bytes calldata message
1156- ) internal {
1157- // Check that deposit route is enabled for the input token. There are no checks required for the output token
1158- // which is pulled from the relayer at fill time and passed through this contract atomically to the recipient.
1159- if (! enabledDepositRoutes[inputToken][destinationChainId]) revert DisabledRoute ();
1160-
1161- // Require that quoteTimestamp has a maximum age so that depositors pay an LP fee based on recent HubPool usage.
1162- // It is assumed that cross-chain timestamps are normally loosely in-sync, but clock drift can occur. If the
1163- // SpokePool time stalls or lags significantly, it is still possible to make deposits by setting quoteTimestamp
1164- // within the configured buffer. The owner should pause deposits/fills if this is undesirable.
1165- // This will underflow if quoteTimestamp is more than depositQuoteTimeBuffer;
1166- // this is safe but will throw an unintuitive error.
1167-
1168- // slither-disable-next-line timestamp
1169- uint256 currentTime = getCurrentTime ();
1170- if (currentTime - quoteTimestamp > depositQuoteTimeBuffer) revert InvalidQuoteTimestamp ();
1171-
1172- // fillDeadline is relative to the destination chain.
1173- // Don’t allow fillDeadline to be more than several bundles into the future.
1174- // This limits the maximum required lookback for dataworker and relayer instances.
1175- // Also, don't allow fillDeadline to be in the past. This poses a potential UX issue if the destination
1176- // chain time keeping and this chain's time keeping are out of sync but is not really a practical hurdle
1177- // unless they are significantly out of sync or the depositor is setting very short fill deadlines. This latter
1178- // situation won't be a problem for honest users.
1179- if (fillDeadline < currentTime || fillDeadline > currentTime + fillDeadlineBuffer) revert InvalidFillDeadline ();
1180-
1181- // If the address of the origin token is a wrappedNativeToken contract and there is a msg.value with the
1182- // transaction then the user is sending the native token. In this case, the native token should be
1183- // wrapped.
1184- if (inputToken == address (wrappedNativeToken) && msg .value > 0 ) {
1185- if (msg .value != inputAmount) revert MsgValueDoesNotMatchInputAmount ();
1186- wrappedNativeToken.deposit { value: msg .value }();
1187- // Else, it is a normal ERC20. In this case pull the token from the caller as per normal.
1188- // Note: this includes the case where the L2 caller has WETH (already wrapped ETH) and wants to bridge them.
1189- // In this case the msg.value will be set to 0, indicating a "normal" ERC20 bridging action.
1190- } else {
1191- // msg.value should be 0 if input token isn't the wrapped native token.
1192- if (msg .value != 0 ) revert MsgValueDoesNotMatchInputAmount ();
1193- IERC20Upgradeable (inputToken).safeTransferFrom (msg .sender , address (this ), inputAmount);
1194- }
1195-
1196- emit V3FundsDeposited (
1197- inputToken,
1198- outputToken,
1199- inputAmount,
1200- outputAmount,
1201- destinationChainId,
1202- depositId,
1203- quoteTimestamp,
1204- fillDeadline,
1205- exclusivityDeadline,
1206- depositor,
1207- recipient,
1208- exclusiveRelayer,
1209- message
1210- );
1211- }
1212-
12131091 function _deposit (
12141092 address depositor ,
12151093 address recipient ,
@@ -1336,7 +1214,7 @@ abstract contract SpokePool is
13361214
13371215 function _verifyUpdateV3DepositMessage (
13381216 address depositor ,
1339- uint256 depositId ,
1217+ uint32 depositId ,
13401218 uint256 originChainId ,
13411219 uint256 updatedOutputAmount ,
13421220 address updatedRecipient ,
0 commit comments