Skip to content

Commit 95c4f92

Browse files
nicholaspaimrice32
andauthored
feat: Add ERC7683 depositor (#492)
* WIP: feat: Add ERC7683 depositor The Permit2 stuff doesn't compile yet, need to model this off of the Permit2OrderLib * compiles * WIP Signed-off-by: Matt Rice <[email protected]> * update Signed-off-by: Matt Rice <[email protected]> * fix Signed-off-by: Matt Rice <[email protected]> * WIP Signed-off-by: Matt Rice <[email protected]> * layouts Signed-off-by: Matt Rice <[email protected]> * WIP Signed-off-by: Matt Rice <[email protected]> --------- Signed-off-by: Matt Rice <[email protected]> Co-authored-by: Matt Rice <[email protected]>
1 parent f955f4a commit 95c4f92

12 files changed

+748
-305
lines changed

contracts/erc7683/ERC7683.sol

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity ^0.8.0;
3+
4+
/// @notice Tokens sent by the swapper as inputs to the order
5+
struct Input {
6+
/// @dev The address of the ERC20 token on the origin chain
7+
address token;
8+
/// @dev The amount of the token to be sent
9+
uint256 amount;
10+
}
11+
12+
/// @notice Tokens that must be receive for a valid order fulfillment
13+
struct Output {
14+
/// @dev The address of the ERC20 token on the destination chain
15+
/// @dev address(0) used as a sentinel for the native token
16+
address token;
17+
/// @dev The amount of the token to be sent
18+
uint256 amount;
19+
/// @dev The address to receive the output tokens
20+
address recipient;
21+
/// @dev The destination chain for this output
22+
uint32 chainId;
23+
}
24+
25+
/// @title CrossChainOrder type
26+
/// @notice Standard order struct to be signed by swappers, disseminated to fillers, and submitted to settlement contracts
27+
struct CrossChainOrder {
28+
/// @dev The contract address that the order is meant to be settled by.
29+
/// Fillers send this order to this contract address on the origin chain
30+
address settlementContract;
31+
/// @dev The address of the user who is initiating the swap,
32+
/// whose input tokens will be taken and escrowed
33+
address swapper;
34+
/// @dev Nonce to be used as replay protection for the order
35+
uint256 nonce;
36+
/// @dev The chainId of the origin chain
37+
uint32 originChainId;
38+
/// @dev The timestamp by which the order must be initiated
39+
uint32 initiateDeadline;
40+
/// @dev The timestamp by which the order must be filled on the destination chain
41+
uint32 fillDeadline;
42+
/// @dev Arbitrary implementation-specific data
43+
/// Can be used to define tokens, amounts, destination chains, fees, settlement parameters,
44+
/// or any other order-type specific information
45+
bytes orderData;
46+
}
47+
48+
/// @title ResolvedCrossChainOrder type
49+
/// @notice An implementation-generic representation of an order
50+
/// @dev Defines all requirements for filling an order by unbundling the implementation-specific orderData.
51+
/// @dev Intended to improve integration generalization by allowing fillers to compute the exact input and output information of any order
52+
struct ResolvedCrossChainOrder {
53+
/// @dev The contract address that the order is meant to be settled by.
54+
address settlementContract;
55+
/// @dev The address of the user who is initiating the swap
56+
address swapper;
57+
/// @dev Nonce to be used as replay protection for the order
58+
uint256 nonce;
59+
/// @dev The chainId of the origin chain
60+
uint32 originChainId;
61+
/// @dev The timestamp by which the order must be initiated
62+
uint32 initiateDeadline;
63+
/// @dev The timestamp by which the order must be filled on the destination chain(s)
64+
uint32 fillDeadline;
65+
/// @dev The inputs to be taken from the swapper as part of order initiation
66+
Input[] swapperInputs;
67+
/// @dev The outputs to be given to the swapper as part of order fulfillment
68+
Output[] swapperOutputs;
69+
/// @dev The outputs to be given to the filler as part of order settlement
70+
Output[] fillerOutputs;
71+
}
72+
73+
/// @title ISettlementContract
74+
/// @notice Standard interface for settlement contracts
75+
interface ISettlementContract {
76+
/// @notice Initiates the settlement of a cross-chain order
77+
/// @dev To be called by the filler
78+
/// @param order The CrossChainOrder definition
79+
/// @param signature The swapper's signature over the order
80+
/// @param fillerData Any filler-defined data required by the settler
81+
function initiate(
82+
CrossChainOrder memory order,
83+
bytes memory signature,
84+
bytes memory fillerData
85+
) external;
86+
87+
/// @notice Resolves a specific CrossChainOrder into a generic ResolvedCrossChainOrder
88+
/// @dev Intended to improve standardized integration of various order types and settlement contracts
89+
/// @param order The CrossChainOrder definition
90+
/// @param fillerData Any filler-defined data required by the settler
91+
/// @return ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order
92+
function resolve(CrossChainOrder memory order, bytes memory fillerData)
93+
external
94+
view
95+
returns (ResolvedCrossChainOrder memory);
96+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.0;
3+
4+
import "../external/interfaces/IPermit2.sol";
5+
import { CrossChainOrder } from "./ERC7683.sol";
6+
7+
// Data unique to every CrossChainOrder settled on Across
8+
struct AcrossOrderData {
9+
address inputToken;
10+
uint256 inputAmount;
11+
address outputToken;
12+
uint256 outputAmount;
13+
uint32 destinationChainId;
14+
address recipient;
15+
uint32 exclusivityDeadline;
16+
bytes message;
17+
}
18+
19+
struct AcrossFillerData {
20+
address exclusiveRelayer;
21+
}
22+
23+
/**
24+
* @notice ERC7683Permit2Lib knows how to process a particular type of external Permit2Order so that it can be used in Across.
25+
* @dev This library is responsible for definining the ERC712 type strings/hashes and performing hashes on the types.
26+
*/
27+
library ERC7683Permit2Lib {
28+
bytes private constant ACROSS_ORDER_DATA_TYPE =
29+
abi.encodePacked(
30+
"AcrossOrderData(",
31+
"address inputToken,",
32+
"uint256 inputAmount,",
33+
"address outputToken,",
34+
"uint256 outputAmount,",
35+
"uint32 destinationChainId,",
36+
"address recipient,",
37+
"uint32 exclusivityDeadline,",
38+
"bytes message)"
39+
);
40+
41+
bytes32 private constant ACROSS_ORDER_DATA_TYPE_HASH = keccak256(ACROSS_ORDER_DATA_TYPE);
42+
43+
bytes internal constant CROSS_CHAIN_ORDER_TYPE =
44+
abi.encodePacked(
45+
"CrossChainOrder(",
46+
"address settlerContract,",
47+
"address swapper,",
48+
"uint256 nonce,",
49+
"uint32 originChainId,",
50+
"uint32 initiateDeadline,",
51+
"uint32 fillDeadline,",
52+
"AcrossOrderData orderData)",
53+
ACROSS_ORDER_DATA_TYPE
54+
);
55+
bytes32 internal constant CROSS_CHAIN_ORDER_TYPE_HASH = keccak256(CROSS_CHAIN_ORDER_TYPE);
56+
string private constant TOKEN_PERMISSIONS_TYPE = "TokenPermissions(address token,uint256 amount)";
57+
string internal constant PERMIT2_ORDER_TYPE =
58+
string(abi.encodePacked("CrossChainOrder witness)", CROSS_CHAIN_ORDER_TYPE, TOKEN_PERMISSIONS_TYPE));
59+
60+
// Hashes an order to get an order hash. Needed for permit2.
61+
function hashOrder(CrossChainOrder memory order, bytes32 orderDataHash) internal pure returns (bytes32) {
62+
return
63+
keccak256(
64+
abi.encodePacked(
65+
CROSS_CHAIN_ORDER_TYPE_HASH,
66+
order.settlementContract,
67+
order.swapper,
68+
order.nonce,
69+
order.originChainId,
70+
order.initiateDeadline,
71+
order.fillDeadline,
72+
orderDataHash
73+
)
74+
);
75+
}
76+
77+
function hashOrderData(AcrossOrderData memory orderData) internal pure returns (bytes32) {
78+
return
79+
keccak256(
80+
abi.encodePacked(
81+
ACROSS_ORDER_DATA_TYPE_HASH,
82+
orderData.inputToken,
83+
orderData.inputAmount,
84+
orderData.outputToken,
85+
orderData.outputAmount,
86+
orderData.destinationChainId,
87+
orderData.recipient,
88+
orderData.exclusivityDeadline,
89+
orderData.message
90+
)
91+
);
92+
}
93+
}

0 commit comments

Comments
 (0)