-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathSocketUtils.sol
142 lines (128 loc) · 4.98 KB
/
SocketUtils.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.21;
import "../utils/RescueFundsLib.sol";
import "./SocketConfig.sol";
import {ECDSA} from "solady/utils/ECDSA.sol";
/**
* @title SocketUtils
* @notice A contract that is responsible for common storage for src and dest contracts, governance
* setters and inherits SocketConfig
*/
abstract contract SocketUtils is SocketConfig {
////////////////////////////////////////////////////////////
////////////////////// State Vars //////////////////////////
////////////////////////////////////////////////////////////
// Version string for this socket instance
bytes32 public immutable version;
// ChainSlug for this deployed socket instance
uint32 public immutable chainSlug;
uint64 public callCounter;
/**
* @dev keeps track of whether a payload has been executed or not using payload id
*/
mapping(bytes32 => ExecutionStatus) public payloadExecuted;
/*
* @notice constructor for creating a new Socket contract instance.
* @param chainSlug_ The unique identifier of the chain this socket is deployed on.
* @param owner_ The address of the owner who has the initial admin role.
* @param version_ The version string which is hashed and stored in socket.
*/
constructor(uint32 chainSlug_, address owner_, string memory version_) {
chainSlug = chainSlug_;
version = keccak256(bytes(version_));
_initializeOwner(owner_);
}
////////////////////////////////////////////////////////
////////////////////// ERRORS //////////////////////////
////////////////////////////////////////////////////////
/**
* @dev Error thrown when non-transmitter tries to execute
*/
error InvalidTransmitter();
/**
* @notice creates the digest for the payload
* @param transmitter_ The address of the transmitter
* @param payloadId_ The ID of the payload
* @param appGateway_ The address of the app gateway
* @param executeParams_ The parameters of the payload
* @return The packed payload as a bytes32 hash
*/
function _createDigest(
address transmitter_,
bytes32 payloadId_,
address appGateway_,
ExecuteParams memory executeParams_
) internal view returns (bytes32) {
return
keccak256(
abi.encode(
transmitter_,
payloadId_,
executeParams_.deadline,
executeParams_.callType,
executeParams_.writeFinality,
executeParams_.gasLimit,
msg.value,
executeParams_.readAt,
executeParams_.payload,
executeParams_.target,
appGateway_,
executeParams_.prevDigestsHash
)
);
}
/**
* @notice creates the payload ID
* @param switchboard_ The address of the switchboard
* @param executeParams_ The parameters of the payload
*/
function _createPayloadId(
address switchboard_,
ExecuteParams memory executeParams_
) internal view returns (bytes32) {
return
keccak256(
abi.encode(
executeParams_.requestCount,
executeParams_.batchCount,
executeParams_.payloadCount,
switchboard_,
chainSlug
)
);
}
function _recoverSigner(
bytes32 digest_,
bytes memory signature_
) internal view returns (address signer) {
bytes32 digest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest_));
// recovered signer is checked for the valid roles later
signer = ECDSA.recover(digest, signature_);
}
// Packs the local plug, local chain slug, remote chain slug and nonce
// callCount++ will take care of call id overflow as well
// callId(256) = localChainSlug(32) | appGateway_(160) | nonce(64)
function _encodeCallId(address appGateway_) internal returns (bytes32) {
return
bytes32(
(uint256(chainSlug) << 224) | (uint256(uint160(appGateway_)) << 64) | callCounter++
);
}
//////////////////////////////////////////////
//////////// Rescue role actions ////////////
/////////////////////////////////////////////
/**
* @notice Rescues funds from the contract if they are locked by mistake. This contract does not
* theoretically need this function but it is added for safety.
* @param token_ The address of the token contract.
* @param rescueTo_ The address where rescued tokens need to be sent.
* @param amount_ The amount of tokens to be rescued.
*/
function rescueFunds(
address token_,
address rescueTo_,
uint256 amount_
) external onlyRole(RESCUE_ROLE) {
RescueFundsLib._rescueFunds(token_, rescueTo_, amount_);
}
}