forked from 0xPolygon/cdk-validium-contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PolygonZkEVMGlobalExitRoot.sol
88 lines (74 loc) · 2.8 KB
/
PolygonZkEVMGlobalExitRoot.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
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.20;
import "./interfaces/IPolygonZkEVMGlobalExitRoot.sol";
import "./lib/GlobalExitRootLib.sol";
/**
* Contract responsible for managing the exit roots across multiple networks
*/
contract PolygonZkEVMGlobalExitRoot is IPolygonZkEVMGlobalExitRoot {
// PolygonZkEVMBridge address
address public immutable bridgeAddress;
// Rollup contract address
address public immutable rollupAddress;
// Rollup exit root, this will be updated every time a batch is verified
bytes32 public lastRollupExitRoot;
// Mainnet exit root, this will be updated every time a deposit is made in mainnet
bytes32 public lastMainnetExitRoot;
// Store every global exit root: Root --> timestamp
mapping(bytes32 => uint256) public globalExitRootMap;
/**
* @dev Emitted when the global exit root is updated
*/
event UpdateGlobalExitRoot(
bytes32 indexed mainnetExitRoot,
bytes32 indexed rollupExitRoot
);
/**
* @param _rollupAddress Rollup contract address
* @param _bridgeAddress PolygonZkEVMBridge contract address
*/
constructor(address _rollupAddress, address _bridgeAddress) {
rollupAddress = _rollupAddress;
bridgeAddress = _bridgeAddress;
}
/**
* @notice Update the exit root of one of the networks and the global exit root
* @param newRoot new exit tree root
*/
function updateExitRoot(bytes32 newRoot) external {
// Store storage variables into temporal variables since will be used multiple times
bytes32 cacheLastRollupExitRoot = lastRollupExitRoot;
bytes32 cacheLastMainnetExitRoot = lastMainnetExitRoot;
if (msg.sender == bridgeAddress) {
lastMainnetExitRoot = newRoot;
cacheLastMainnetExitRoot = newRoot;
} else if (msg.sender == rollupAddress) {
lastRollupExitRoot = newRoot;
cacheLastRollupExitRoot = newRoot;
} else {
revert OnlyAllowedContracts();
}
bytes32 newGlobalExitRoot = GlobalExitRootLib.calculateGlobalExitRoot(
cacheLastMainnetExitRoot,
cacheLastRollupExitRoot
);
// If it already exists, do not modify the timestamp
if (globalExitRootMap[newGlobalExitRoot] == 0) {
globalExitRootMap[newGlobalExitRoot] = block.timestamp;
emit UpdateGlobalExitRoot(
cacheLastMainnetExitRoot,
cacheLastRollupExitRoot
);
}
}
/**
* @notice Return last global exit root
*/
function getLastGlobalExitRoot() public view returns (bytes32) {
return
GlobalExitRootLib.calculateGlobalExitRoot(
lastMainnetExitRoot,
lastRollupExitRoot
);
}
}