Skip to content

Commit 028ca35

Browse files
Merge branch 'staging' into proxy-storage
2 parents 2bf1549 + 557b73d commit 028ca35

File tree

13 files changed

+123
-86
lines changed

13 files changed

+123
-86
lines changed

contracts/interfaces/IWatcherPrecompile.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ interface IWatcherPrecompile {
6767
/// @param proof_ The watcher's proof
6868
function finalized(
6969
bytes32 payloadId_,
70-
uint256 signatureNonce_,
7170
bytes calldata proof_,
71+
uint256 signatureNonce_,
7272
bytes calldata signature_
7373
) external;
7474

@@ -80,8 +80,8 @@ interface IWatcherPrecompile {
8080
/// @notice Resolves multiple promises with their return data
8181
/// @param resolvedPromises_ Array of resolved promises and their return data
8282
function resolvePromises(
83-
uint256 signatureNonce_,
8483
ResolvedPromises[] calldata resolvedPromises_,
84+
uint256 signatureNonce_,
8585
bytes calldata signature_
8686
) external;
8787

contracts/protocol/AddressResolver.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ abstract contract AddressResolverStorage is IAddressResolver {
5858
/// @dev Inherits the Ownable contract and implements the IAddressResolver interface.
5959
contract AddressResolver is AddressResolverStorage, Initializable, Ownable {
6060
/// @notice Error thrown if AppGateway contract was already set by a different address
61-
error InvalidCaller(address contractAddress_);
61+
error InvalidAppGateway(address contractAddress_);
6262

6363
event PlugAdded(address appGateway, uint32 chainSlug, address plug);
6464
event ForwarderDeployed(address newForwarder, bytes32 salt);
@@ -188,7 +188,7 @@ contract AddressResolver is AddressResolverStorage, Initializable, Ownable {
188188
contractsToGateways[contractAddress_] != address(0) &&
189189
contractsToGateways[contractAddress_] != msg.sender
190190
) {
191-
revert InvalidCaller(contractAddress_);
191+
revert InvalidAppGateway(contractAddress_);
192192
}
193193
contractsToGateways[contractAddress_] = msg.sender;
194194
}

contracts/protocol/payload-delivery/AuctionManager.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ abstract contract AuctionManagerStorage is IAuctionManager {
1818
uint256[50] _gap_before;
1919

2020
// slot 50
21-
uint32 public evmxChainSlug;
21+
uint32 public evmxSlug;
2222

2323
// slot 51
2424
mapping(bytes32 => Bid) public winningBids;
@@ -52,19 +52,19 @@ contract AuctionManager is AuctionManagerStorage, Initializable, Ownable, Addres
5252
}
5353

5454
/// @notice Initializer function to replace constructor
55-
/// @param evmxChainSlug_ The chain slug for the VM
55+
/// @param evmxSlug_ The chain slug for the VM
5656
/// @param auctionEndDelaySeconds_ The delay in seconds before an auction can end
5757
/// @param addressResolver_ The address of the address resolver
5858
/// @param owner_ The address of the contract owner
5959
function initialize(
60-
uint32 evmxChainSlug_,
60+
uint32 evmxSlug_,
6161
uint256 auctionEndDelaySeconds_,
6262
address addressResolver_,
6363
address owner_
6464
) public reinitializer(1) {
6565
_setAddressResolver(addressResolver_);
6666
_initializeOwner(owner_);
67-
evmxChainSlug = evmxChainSlug_;
67+
evmxSlug = evmxSlug_;
6868
auctionEndDelaySeconds = auctionEndDelaySeconds_;
6969
}
7070

@@ -93,7 +93,7 @@ contract AuctionManager is AuctionManagerStorage, Initializable, Ownable, Addres
9393
if (auctionClosed[asyncId_]) revert AuctionClosed();
9494

9595
address transmitter = _recoverSigner(
96-
keccak256(abi.encode(address(this), evmxChainSlug, asyncId_, fee, extraData)),
96+
keccak256(abi.encode(address(this), evmxSlug, asyncId_, fee, extraData)),
9797
transmitterSignature
9898
);
9999

contracts/protocol/payload-delivery/FeesManager.sol

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pragma solidity ^0.8.0;
33

44
import {Ownable} from "solady/auth/Ownable.sol";
55
import "solady/utils/Initializable.sol";
6+
import "solady/utils/ECDSA.sol";
67

78
import {IFeesPlug} from "../../interfaces/IFeesPlug.sol";
89
import {IFeesManager} from "../../interfaces/IFeesManager.sol";
@@ -18,6 +19,7 @@ abstract contract FeesManagerStorage is IFeesManager {
1819

1920
// slot 50
2021
uint256 public feesCounter;
22+
uint32 public evmxSlug;
2123

2224
/// @notice Struct containing fee amounts and status
2325
struct TokenBalance {
@@ -41,11 +43,16 @@ abstract contract FeesManagerStorage is IFeesManager {
4143
/// @dev transmitter => chainSlug => token => amount
4244
mapping(address => mapping(uint32 => mapping(address => uint256))) public transmitterFees;
4345

44-
// slots [54-103] reserved for gap
46+
// slot 54
47+
/// @notice Mapping to track nonce to whether it has been used
48+
/// @dev signatureNonce => isValid
49+
mapping(uint256 => bool) public isNonceUsed;
50+
51+
// slots [55-104] reserved for gap
4552
uint256[50] _gap_after;
4653

47-
// slots 104-153 reserved for addr resolver util
48-
}
54+
// slots 105-154 reserved for addr resolver util
55+
}
4956

5057
/// @title FeesManager
5158
/// @notice Contract for managing fees
@@ -105,6 +112,10 @@ contract FeesManager is FeesManagerStorage, Initializable, Ownable, AddressResol
105112
error NoFeesForTransmitter();
106113
/// @notice Error thrown when no fees was blocked
107114
error NoFeesBlocked();
115+
/// @notice Error thrown when watcher signature is invalid
116+
error InvalidWatcherSignature();
117+
/// @notice Error thrown when nonce is used
118+
error NonceUsed();
108119

109120
constructor() {
110121
_disableInitializers(); // disable for implementation
@@ -113,7 +124,13 @@ contract FeesManager is FeesManagerStorage, Initializable, Ownable, AddressResol
113124
/// @notice Initializer function to replace constructor
114125
/// @param addressResolver_ The address of the address resolver
115126
/// @param owner_ The address of the owner
116-
function initialize(address addressResolver_, address owner_) public reinitializer(1) {
127+
/// @param evmxSlug_ The evmx chain slug
128+
function initialize(
129+
address addressResolver_,
130+
address owner_,
131+
uint32 evmxSlug_
132+
) public reinitializer(1) {
133+
evmxSlug = evmxSlug_;
117134
_setAddressResolver(addressResolver_);
118135
_initializeOwner(owner_);
119136
}
@@ -142,8 +159,16 @@ contract FeesManager is FeesManagerStorage, Initializable, Ownable, AddressResol
142159
uint32 chainSlug_,
143160
address originAppGateway_,
144161
address token_,
145-
uint256 amount_
146-
) external onlyOwner {
162+
uint256 amount_,
163+
uint256 signatureNonce_,
164+
bytes memory signature_
165+
) external {
166+
_isWatcherSignatureValid(
167+
abi.encode(chainSlug_, originAppGateway_, token_, amount_),
168+
signatureNonce_,
169+
signature_
170+
);
171+
147172
address appGateway = _getCoreAppGateway(originAppGateway_);
148173

149174
TokenBalance storage tokenBalance = appGatewayFeeBalances[appGateway][chainSlug_][token_];
@@ -351,4 +376,19 @@ contract FeesManager is FeesManagerStorage, Initializable, Ownable, AddressResol
351376
function _getFeesPlugAddress(uint32 chainSlug_) internal view returns (address) {
352377
return watcherPrecompile__().feesPlug(chainSlug_);
353378
}
379+
380+
function _isWatcherSignatureValid(
381+
bytes memory digest_,
382+
uint256 signatureNonce_,
383+
bytes memory signature_
384+
) internal {
385+
if (isNonceUsed[signatureNonce_]) revert NonceUsed();
386+
isNonceUsed[signatureNonce_] = true;
387+
388+
bytes32 digest = keccak256(abi.encode(address(this), evmxSlug, signatureNonce_, digest_));
389+
digest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest));
390+
// recovered signer is checked for the valid roles later
391+
address signer = ECDSA.recover(digest, signature_);
392+
if (signer != owner()) revert InvalidWatcherSignature();
393+
}
354394
}

contracts/protocol/watcherPrecompile/WatcherPrecompile.sol

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
7878
address addressResolver_,
7979
uint256 defaultLimit_,
8080
uint256 expiryTime_,
81-
uint32 evmxChainSlug_
81+
uint32 evmxSlug_
8282
) public reinitializer(1) {
8383
_setAddressResolver(addressResolver_);
8484
_initializeOwner(owner_);
@@ -90,7 +90,7 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
9090
// limit per second
9191
defaultRatePerSecond = defaultLimit / (24 * 60 * 60);
9292

93-
evmxChainSlug = evmxChainSlug_;
93+
evmxSlug = evmxSlug_;
9494
}
9595

9696
// ================== Timeout functions ==================
@@ -108,7 +108,7 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
108108
// from auction manager
109109
_consumeLimit(appGateway_, SCHEDULE, 1);
110110
uint256 executeAt = block.timestamp + delayInSeconds_;
111-
bytes32 timeoutId = _encodeId(evmxChainSlug, address(this));
111+
bytes32 timeoutId = _encodeId(evmxSlug, address(this));
112112
timeoutRequests[timeoutId] = TimeoutRequest(
113113
timeoutId,
114114
msg.sender,
@@ -130,8 +130,8 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
130130
bytes calldata signature_
131131
) external {
132132
_isWatcherSignatureValid(
133+
abi.encode(this.resolveTimeout.selector, timeoutId_),
133134
signatureNonce_,
134-
keccak256(abi.encode(address(this), evmxChainSlug, signatureNonce_, timeoutId_)),
135135
signature_
136136
);
137137

@@ -253,7 +253,7 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
253253
// from payload delivery
254254
_consumeLimit(appGateway_, QUERY, 1);
255255
// Generate unique payload ID from query counter
256-
payloadId = _encodeId(evmxChainSlug, address(this));
256+
payloadId = _encodeId(evmxSlug, address(this));
257257

258258
// Create async request with minimal information for queries
259259
// Note: addresses set to 0 as they're not needed for queries
@@ -282,15 +282,13 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
282282
/// @dev keccak256(abi.encode(switchboard, digest))
283283
function finalized(
284284
bytes32 payloadId_,
285-
uint256 signatureNonce_,
286285
bytes calldata proof_,
286+
uint256 signatureNonce_,
287287
bytes calldata signature_
288288
) external {
289289
_isWatcherSignatureValid(
290+
abi.encode(this.finalized.selector, payloadId_, proof_),
290291
signatureNonce_,
291-
keccak256(
292-
abi.encode(address(this), evmxChainSlug, signatureNonce_, payloadId_, proof_)
293-
),
294292
signature_
295293
);
296294

@@ -302,13 +300,13 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
302300
/// @param resolvedPromises_ Array of resolved promises and their return data
303301
/// @dev Only callable by the contract owner
304302
function resolvePromises(
305-
uint256 signatureNonce_,
306303
ResolvedPromises[] calldata resolvedPromises_,
304+
uint256 signatureNonce_,
307305
bytes calldata signature_
308306
) external {
309307
_isWatcherSignatureValid(
308+
abi.encode(this.resolvePromises.selector, resolvedPromises_),
310309
signatureNonce_,
311-
keccak256(abi.encode(address(this), evmxChainSlug, signatureNonce_, resolvedPromises_)),
312310
signature_
313311
);
314312

@@ -345,16 +343,8 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
345343
bytes calldata signature_
346344
) external {
347345
_isWatcherSignatureValid(
346+
abi.encode(this.markRevert.selector, isRevertingOnchain_, payloadId_),
348347
signatureNonce_,
349-
keccak256(
350-
abi.encode(
351-
address(this),
352-
evmxChainSlug,
353-
signatureNonce_,
354-
payloadId_,
355-
isRevertingOnchain_
356-
)
357-
),
358348
signature_
359349
);
360350

@@ -406,8 +396,8 @@ contract WatcherPrecompile is WatcherPrecompileConfig {
406396
bytes calldata signature_
407397
) external {
408398
_isWatcherSignatureValid(
399+
abi.encode(this.callAppGateways.selector, params_),
409400
signatureNonce_,
410-
keccak256(abi.encode(address(this), evmxChainSlug, signatureNonce_, params_)),
411401
signature_
412402
);
413403

contracts/protocol/watcherPrecompile/WatcherPrecompileConfig.sol

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ abstract contract WatcherPrecompileConfig is WatcherPrecompileLimits {
4646
bytes calldata signature_
4747
) external {
4848
_isWatcherSignatureValid(
49+
abi.encode(this.setAppGateways.selector, configs_),
4950
signatureNonce_,
50-
keccak256(abi.encode(address(this), evmxChainSlug, signatureNonce_, configs_)),
5151
signature_
5252
);
5353

@@ -109,14 +109,16 @@ abstract contract WatcherPrecompileConfig is WatcherPrecompileLimits {
109109
}
110110

111111
function _isWatcherSignatureValid(
112+
bytes memory digest_,
112113
uint256 signatureNonce_,
113-
bytes32 digest_,
114114
bytes memory signature_
115115
) internal {
116116
if (isNonceUsed[signatureNonce_]) revert NonceUsed();
117117
isNonceUsed[signatureNonce_] = true;
118118

119-
bytes32 digest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest_));
119+
bytes32 digest = keccak256(abi.encode(address(this), evmxSlug, signatureNonce_, digest_));
120+
digest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest));
121+
120122
// recovered signer is checked for the valid roles later
121123
address signer = ECDSA.recover(digest, signature_);
122124
if (signer != owner()) revert InvalidWatcherSignature();

hardhat-scripts/deploy/1.deploy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ const deployEVMxContracts = async () => {
107107
deployUtils = await deployContractWithProxy(
108108
EVMxCoreContracts.FeesManager,
109109
`contracts/protocol/payload-delivery/app-gateway/FeesManager.sol`,
110-
[addressResolver.address, EVMxOwner],
110+
[addressResolver.address, EVMxOwner, EVMX_CHAIN_ID],
111111
proxyFactory,
112112
deployUtils
113113
);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"publishConfig": {
1010
"access": "public"
1111
},
12-
"version": "1.0.11",
12+
"version": "1.0.12",
1313
"description": "socket protocol",
1414
"scripts": {
1515
"build": "hardhat export-abi && tsc --project lib.tsconfig.json",

0 commit comments

Comments
 (0)