Skip to content

Commit

Permalink
Refactor gerManagerSovereigns
Browse files Browse the repository at this point in the history
  • Loading branch information
ignasirv committed Oct 10, 2024
1 parent 3e8ba6f commit af6bc64
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 108 deletions.
11 changes: 8 additions & 3 deletions contracts/interfaces/IBasePolygonZkEVMGlobalExitRoot.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ interface IBasePolygonZkEVMGlobalExitRoot {
/**
* @dev Thrown when the caller is not the coinbase
*/
error OnlyCoinbase();
error OnlyAggOracleOrCoinbase();

/**
* @dev Thrown when trying to insert a global exit root that is already set
*/
error GlobalExitRootAlreadySet();

/**
* @dev Thrown when trying to remove a global exit root that is not found
* @dev Thrown when trying to remove more global exit roots thank inserted
*/
error GlobalExitRootNotFound();
error NotEnoughGlobalExitRootsInserted();

/**
* @dev Thrown when trying to remove a ger that is not the last one
*/
error NotLastInsertedGlobalExitRoot();

function updateExitRoot(bytes32 newRollupExitRoot) external;

Expand Down
2 changes: 2 additions & 0 deletions contracts/v2/sovereignChains/BridgeL2SovereignChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pragma solidity 0.8.20;
import "../interfaces/IBridgeL2SovereignChains.sol";
import "../PolygonZkEVMBridgeV2.sol";

// WARNING: not audited

/**
* Sovereign chains bridge that will be deployed on Ethereum and all Sovereign chains
* Contract responsible to manage the token interactions with other networks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,40 @@

pragma solidity 0.8.20;
import "../../PolygonZkEVMGlobalExitRootL2.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

// WARNING: not audited

/**
* Contract responsible for managing the exit roots for the Sovereign chains and global exit roots
*/
contract GlobalExitRootManagerL2SovereignChain is PolygonZkEVMGlobalExitRootL2 {
contract GlobalExitRootManagerL2SovereignChain is
PolygonZkEVMGlobalExitRootL2,
Initializable
{
// aggOracleAddress address
address public aggOracleAddress;

// Inserted GER counter
uint256 public insertedGERCount;

/**
* @dev Emitted when a new global exit root is inserted
*/
event InsertGlobalExitRoot(bytes32 indexed newGlobalExitRoot);

/**
* @dev Emitted when a new global exit root is removed
* @dev Emitted when the last global exit root is removed
*/
event RemoveGlobalExitRoot(bytes32 indexed removedGlobalExitRoot);
event RemoveLastGlobalExitRoot(bytes32 indexed removedGlobalExitRoot);

modifier onlyCoinbase() {
// Only allowed to be called by coinbase
if (block.coinbase != msg.sender) {
revert OnlyCoinbase();
modifier onlyAggOracleOrCoinbase() {
// Only allowed to be called by aggOracle or coinbase if aggOracle is zero
if (
(aggOracleAddress == address(0) && block.coinbase != msg.sender) ||
(aggOracleAddress != address(0) && aggOracleAddress != msg.sender)
) {
revert OnlyAggOracleOrCoinbase();
}
_;
}
Expand All @@ -30,33 +45,64 @@ contract GlobalExitRootManagerL2SovereignChain is PolygonZkEVMGlobalExitRootL2 {
*/
constructor(
address _bridgeAddress
) PolygonZkEVMGlobalExitRootL2(_bridgeAddress) {}
) PolygonZkEVMGlobalExitRootL2(_bridgeAddress) {
_disableInitializers();
}

/**
* @notice Initialize contract setting the aggOracleAddress
*/
function initialize(
address _aggOracleAddress
) external virtual initializer {
// set aggOracleAddress
aggOracleAddress = _aggOracleAddress;
}

/**
* @notice Insert a new global exit root
* @param _newRoot new global exit root to insert
*/
function insertGlobalExitRoot(bytes32 _newRoot) external onlyCoinbase {
// do not update timestamp if already set
function insertGlobalExitRoot(
bytes32 _newRoot
) external onlyAggOracleOrCoinbase {
// do not insert GER if already set
if (globalExitRootMap[_newRoot] == 0) {
globalExitRootMap[_newRoot] = block.timestamp;
globalExitRootMap[_newRoot] = ++insertedGERCount;
emit InsertGlobalExitRoot(_newRoot);
} else {
revert GlobalExitRootAlreadySet();
}
}

/**
* @notice Remove a global exit root
* @param _root global exit root to remove
* @notice Remove last global exit roots
* @param gersToRemove Array of gers to remove in inserted order where first element of the array is the last inserted
*/
function removeGlobalExitRoot(bytes32 _root) external onlyCoinbase {
// do not update timestamp if already set
if (globalExitRootMap[_root] == 0) {
revert GlobalExitRootNotFound();
} else {
globalExitRootMap[_root] = 0;
emit RemoveGlobalExitRoot(_root);
function removeLastGlobalExitRoots(
bytes32[] calldata gersToRemove
) external onlyAggOracleOrCoinbase {
// Can't remove if not enough roots have been inserted
if (gersToRemove.length > insertedGERCount) {
revert NotEnoughGlobalExitRootsInserted();
}
// Iterate through the array of roots to remove them one by one
for (uint256 i = 0; i < gersToRemove.length; i++) {
bytes32 rootToRemove = gersToRemove[i];

// Check that the root to remove is the last inserted
uint256 lastInsertedIndex = globalExitRootMap[rootToRemove];
if (lastInsertedIndex != insertedGERCount) {
revert NotLastInsertedGlobalExitRoot();
}

// Remove from the mapping
delete globalExitRootMap[rootToRemove]; // Delete from the mapping
// Decrement the counter
insertedGERCount--;

// Emit the removal event
emit RemoveLastGlobalExitRoot(rootToRemove);
}
}
}
2 changes: 1 addition & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const config: HardhatUserConfig = {
settings: {
optimizer: {
enabled: true,
runs: 100,
runs: 0,
},
evmVersion: "shanghai",
}, // try yul optimizer
Expand Down
Loading

0 comments on commit af6bc64

Please sign in to comment.