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