From 98c761ee9ca3a496b4a368bdf12743d727644138 Mon Sep 17 00:00:00 2001 From: nicholaspai <9457025+nicholaspai@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:37:35 -0500 Subject: [PATCH] improve(ERC7683): Adjust for updated ERC specs (#705) * improve(ERC7683): Adjust for updated ERC specs Standard will likely be updated with changes [here](https://github.com/ethereum/ERCs/pull/689/files) so this PR adjusts for those changes: - `originChainId` of intent is now uint256 - `orderId` is a new parameter in the `ResolvedCrossChainOrder` struct, which in Across' system can be the hash of the `V3RelayData` * Update ERC7683OrderDepositor.sol --- contracts/erc7683/ERC7683.sol | 8 ++- contracts/erc7683/ERC7683Across.sol | 2 +- contracts/erc7683/ERC7683OrderDepositor.sol | 63 +++++++++++---------- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/contracts/erc7683/ERC7683.sol b/contracts/erc7683/ERC7683.sol index e9764d0e1..10c29757e 100644 --- a/contracts/erc7683/ERC7683.sol +++ b/contracts/erc7683/ERC7683.sol @@ -13,7 +13,7 @@ struct GaslessCrossChainOrder { /// @dev Nonce to be used as replay protection for the order uint256 nonce; /// @dev The chainId of the origin chain - uint64 originChainId; + uint256 originChainId; /// @dev The timestamp by which the order must be opened uint32 openDeadline; /// @dev The timestamp by which the order must be filled on the destination chain @@ -47,11 +47,13 @@ struct ResolvedCrossChainOrder { /// @dev The address of the user who is initiating the transfer address user; /// @dev The chainId of the origin chain - uint64 originChainId; + uint256 originChainId; /// @dev The timestamp by which the order must be opened uint32 openDeadline; /// @dev The timestamp by which the order must be filled on the destination chain(s) uint32 fillDeadline; + /// @dev The unique identifier for this order within this settlement system + bytes32 orderId; /// @dev The max outputs that the filler will send. It's possible the actual amount depends on the state of the destination /// chain (destination dutch auction, for instance), so these outputs should be considered a cap on filler liabilities. Output[] maxSpent; @@ -74,7 +76,7 @@ struct Output { /// @dev The address to receive the output tokens bytes32 recipient; /// @dev The destination chain for this output - uint64 chainId; + uint256 chainId; } /// @title FillInstruction type diff --git a/contracts/erc7683/ERC7683Across.sol b/contracts/erc7683/ERC7683Across.sol index 87c29c362..3ee47b8b0 100644 --- a/contracts/erc7683/ERC7683Across.sol +++ b/contracts/erc7683/ERC7683Across.sol @@ -52,7 +52,7 @@ library ERC7683Permit2Lib { "address originSettler,", "address user,", "uint256 nonce,", - "uint32 originChainId,", + "uint256 originChainId,", "uint32 openDeadline,", "uint32 fillDeadline,", "bytes32 orderDataType,", diff --git a/contracts/erc7683/ERC7683OrderDepositor.sol b/contracts/erc7683/ERC7683OrderDepositor.sol index bd5e7e03c..717560a10 100644 --- a/contracts/erc7683/ERC7683OrderDepositor.sol +++ b/contracts/erc7683/ERC7683OrderDepositor.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import "../external/interfaces/IPermit2.sol"; +import { V3SpokePoolInterface } from "../interfaces/V3SpokePoolInterface.sol"; import "@openzeppelin/contracts/utils/math/SafeCast.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -211,23 +212,23 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { }); FillInstruction[] memory fillInstructions = new FillInstruction[](1); + V3SpokePoolInterface.V3RelayData memory relayData; + relayData.depositor = order.user; + relayData.recipient = acrossOrderData.recipient; + relayData.exclusiveRelayer = acrossOriginFillerData.exclusiveRelayer; + relayData.inputToken = acrossOrderData.inputToken; + relayData.outputToken = acrossOrderData.outputToken; + relayData.inputAmount = acrossOrderData.inputAmount; + relayData.outputAmount = acrossOrderData.outputAmount; + relayData.originChainId = block.chainid; + relayData.depositId = _currentDepositId(); + relayData.fillDeadline = order.fillDeadline; + relayData.exclusivityDeadline = acrossOrderData.exclusivityPeriod; + relayData.message = acrossOrderData.message; fillInstructions[0] = FillInstruction({ destinationChainId: acrossOrderData.destinationChainId, destinationSettler: _toBytes32(_destinationSettler(acrossOrderData.destinationChainId)), - originData: abi.encode( - order.user, - acrossOrderData.recipient, - acrossOriginFillerData.exclusiveRelayer, - acrossOrderData.inputToken, - acrossOrderData.outputToken, - acrossOrderData.inputAmount, - acrossOrderData.outputAmount, - block.chainid, - _currentDepositId(), - order.fillDeadline, - acrossOrderData.exclusivityPeriod, - acrossOrderData.message - ) + originData: abi.encode(relayData) }); resolvedOrder = ResolvedCrossChainOrder({ @@ -237,7 +238,8 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { fillDeadline: order.fillDeadline, minReceived: minReceived, maxSpent: maxSpent, - fillInstructions: fillInstructions + fillInstructions: fillInstructions, + orderId: keccak256(abi.encode(relayData, acrossOrderData.destinationChainId)) }); } @@ -274,23 +276,23 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { }); FillInstruction[] memory fillInstructions = new FillInstruction[](1); + V3SpokePoolInterface.V3RelayData memory relayData; + relayData.depositor = msg.sender; + relayData.recipient = acrossOrderData.recipient; + relayData.exclusiveRelayer = acrossOrderData.exclusiveRelayer; + relayData.inputToken = acrossOrderData.inputToken; + relayData.outputToken = acrossOrderData.outputToken; + relayData.inputAmount = acrossOrderData.inputAmount; + relayData.outputAmount = acrossOrderData.outputAmount; + relayData.originChainId = block.chainid; + relayData.depositId = _currentDepositId(); + relayData.fillDeadline = order.fillDeadline; + relayData.exclusivityDeadline = acrossOrderData.exclusivityPeriod; + relayData.message = acrossOrderData.message; fillInstructions[0] = FillInstruction({ destinationChainId: acrossOrderData.destinationChainId, destinationSettler: _toBytes32(_destinationSettler(acrossOrderData.destinationChainId)), - originData: abi.encode( - msg.sender, - acrossOrderData.recipient, - acrossOrderData.exclusiveRelayer, - acrossOrderData.inputToken, - acrossOrderData.outputToken, - acrossOrderData.inputAmount, - acrossOrderData.outputAmount, - block.chainid, - _currentDepositId(), - order.fillDeadline, - acrossOrderData.exclusivityPeriod, - acrossOrderData.message - ) + originData: abi.encode(relayData) }); resolvedOrder = ResolvedCrossChainOrder({ @@ -300,7 +302,8 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { fillDeadline: order.fillDeadline, minReceived: minReceived, maxSpent: maxSpent, - fillInstructions: fillInstructions + fillInstructions: fillInstructions, + orderId: keccak256(abi.encode(relayData, acrossOrderData.destinationChainId)) }); }