Skip to content

Commit

Permalink
Regenesis cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
dvush committed Jul 27, 2021
1 parent 262165e commit e8783eb
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 253 deletions.
6 changes: 2 additions & 4 deletions contracts/contracts/AdditionalZkSync.sol
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,12 @@ contract AdditionalZkSync is Storage, Config, Events, ReentrancyGuard {
approvedUpgradeNoticePeriod = 2 weeks;
emit NoticePeriodChange(approvedUpgradeNoticePeriod);
}
}
if (numberOfApprovalsFromSecurityCouncil == SECURITY_COUNCIL_1_WEEK_THRESHOLD) {
} else if (numberOfApprovalsFromSecurityCouncil == SECURITY_COUNCIL_1_WEEK_THRESHOLD) {
if (approvedUpgradeNoticePeriod > 1 weeks) {
approvedUpgradeNoticePeriod = 1 weeks;
emit NoticePeriodChange(approvedUpgradeNoticePeriod);
}
}
if (numberOfApprovalsFromSecurityCouncil == SECURITY_COUNCIL_3_DAYS_THRESHOLD) {
} else if (numberOfApprovalsFromSecurityCouncil == SECURITY_COUNCIL_3_DAYS_THRESHOLD) {
if (approvedUpgradeNoticePeriod > 3 days) {
approvedUpgradeNoticePeriod = 3 days;
emit NoticePeriodChange(approvedUpgradeNoticePeriod);
Expand Down
45 changes: 2 additions & 43 deletions contracts/contracts/Operations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ library Operations {
/// @dev Signature (for example full exit signature) bytes length
uint8 internal constant SIGNATURE_BYTES = 64;

uint256 internal constant LEGACY_MAX_TOKEN = 65535; // 2^16 - 1

// Deposit pubdata
struct Deposit {
// uint8 opType
Expand Down Expand Up @@ -83,29 +81,9 @@ library Operations {
);
}

/// Serialize legacy deposit pubdata
function writeLegacyDepositPubdataForPriorityQueue(Deposit memory op) internal pure returns (bytes memory buf) {
buf = abi.encodePacked(
uint8(OpType.Deposit),
bytes4(0), // accountId (ignored) (update when ACCOUNT_ID_BYTES is changed)
uint16(op.tokenId), // tokenId
op.amount, // amount
op.owner // owner
);
}

/// @notice Write deposit pubdata for priority queue check.
function checkDepositInPriorityQueue(Deposit memory op, bytes20 hashedPubdata) internal pure returns (bool) {
if (Utils.hashBytesToBytes20(writeDepositPubdataForPriorityQueue(op)) == hashedPubdata) {
return true;
} else if (
op.tokenId <= LEGACY_MAX_TOKEN &&
Utils.hashBytesToBytes20(writeLegacyDepositPubdataForPriorityQueue(op)) == hashedPubdata
) {
return true;
} else {
return false;
}
return Utils.hashBytesToBytes20(writeDepositPubdataForPriorityQueue(op)) == hashedPubdata;
}

// FullExit pubdata
Expand Down Expand Up @@ -162,27 +140,8 @@ library Operations {
);
}

function writeLegacyFullExitPubdataForPriorityQueue(FullExit memory op) internal pure returns (bytes memory buf) {
buf = abi.encodePacked(
uint8(OpType.FullExit),
op.accountId, // accountId
op.owner, // owner
uint16(op.tokenId), // tokenId
uint128(0) // amount -- ignored
);
}

function checkFullExitInPriorityQueue(FullExit memory op, bytes20 hashedPubdata) internal pure returns (bool) {
if (Utils.hashBytesToBytes20(writeFullExitPubdataForPriorityQueue(op)) == hashedPubdata) {
return true;
} else if (
op.tokenId <= LEGACY_MAX_TOKEN &&
Utils.hashBytesToBytes20(writeLegacyFullExitPubdataForPriorityQueue(op)) == hashedPubdata
) {
return true;
} else {
return false;
}
return Utils.hashBytesToBytes20(writeFullExitPubdataForPriorityQueue(op)) == hashedPubdata;
}

// PartialExit pubdata
Expand Down
34 changes: 23 additions & 11 deletions contracts/contracts/ReentrancyGuard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,28 @@ contract ReentrancyGuard {
/// @dev Flag is placed at random memory location to not interfere with Storage contract.
uint256 private constant LOCK_FLAG_ADDRESS = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4; // keccak256("ReentrancyGuard") - 1;

// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/566a774222707e424896c0c390a84dc3c13bdcb2/contracts/security/ReentrancyGuard.sol
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;

function initializeReentrancyGuard() internal {
uint256 lockSlotOldValue;

// Storing an initial non-zero value makes deployment a bit more
// expensive, but in exchange the refund on every call to nonReentrant
// will be lower in amount. Since refunds are capped to a percetange of
// the total transaction's gas, it is best to keep them low in cases
// like this one, to increase the likelihood of the full refund coming
// into effect.
// expensive, but in exchange every call to nonReentrant
// will be cheaper.
assembly {
sstore(LOCK_FLAG_ADDRESS, 1)
lockSlotOldValue := sload(LOCK_FLAG_ADDRESS)
sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED)
}

// Check that storage slot for reentrancy guard is empty to rule out possibility of slot conflict
require(lockSlotOldValue == 0, "1B");
}

/**
Expand All @@ -46,25 +58,25 @@ contract ReentrancyGuard {
* `private` function that does the actual work.
*/
modifier nonReentrant() {
bool notEntered;
uint256 _status;
assembly {
notEntered := sload(LOCK_FLAG_ADDRESS)
_status := sload(LOCK_FLAG_ADDRESS)
}

// On the first call to nonReentrant, _notEntered will be true
require(notEntered, "1b");
require(_status == _NOT_ENTERED);

// Any calls to nonReentrant after this point will fail
assembly {
sstore(LOCK_FLAG_ADDRESS, 0)
sstore(LOCK_FLAG_ADDRESS, _ENTERED)
}

_;

// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
assembly {
sstore(LOCK_FLAG_ADDRESS, 1)
sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED)
}
}
}
2 changes: 1 addition & 1 deletion contracts/contracts/Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ contract Storage {
mapping(uint32 => bytes32) public storedBlockHashes;

/// @dev Total blocks proven.
uint32 internal totalBlocksProven;
uint32 public totalBlocksProven;

/// @notice Priority Operation container
/// @member hashedPubData Hashed priority operation public data
Expand Down
60 changes: 20 additions & 40 deletions contracts/contracts/ZkSync.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,8 @@ contract ZkSync is UpgradeableMaster, Storage, Config, Events, ReentrancyGuard {
require(block.timestamp >= upgradeStartTimestamp.add(approvedUpgradeNoticePeriod));
}

/// @notice Notification that upgrade canceled
/// @dev Can be external because Proxy contract intercepts illegal calls of this function
function upgradeCanceled() external override {
/// @dev When upgrade is finished or canceled we must clean upgrade-related state.
function clearUpgradeStatus() internal {
upgradePreparationActive = false;
upgradePreparationActivationTime = 0;
approvedUpgradeNoticePeriod = UPGRADE_NOTICE_PERIOD;
Expand All @@ -101,18 +100,16 @@ contract ZkSync is UpgradeableMaster, Storage, Config, Events, ReentrancyGuard {
numberOfApprovalsFromSecurityCouncil = 0;
}

/// @notice Notification that upgrade canceled
/// @dev Can be external because Proxy contract intercepts illegal calls of this function
function upgradeCanceled() external override {
clearUpgradeStatus();
}

/// @notice Notification that upgrade finishes
/// @dev Can be external because Proxy contract intercepts illegal calls of this function
function upgradeFinishes() external override {
upgradePreparationActive = false;
upgradePreparationActivationTime = 0;
approvedUpgradeNoticePeriod = UPGRADE_NOTICE_PERIOD;
emit NoticePeriodChange(approvedUpgradeNoticePeriod);
upgradeStartTimestamp = 0;
for (uint256 i = 0; i < SECURITY_COUNCIL_MEMBERS_NUMBER; ++i) {
securityCouncilApproves[i] = false;
}
numberOfApprovalsFromSecurityCouncil = 0;
clearUpgradeStatus();
}

/// @notice Checks that contract is ready for upgrade
Expand All @@ -129,12 +126,16 @@ contract ZkSync is UpgradeableMaster, Storage, Config, Events, ReentrancyGuard {
function initialize(bytes calldata initializationParameters) external {
initializeReentrancyGuard();

(address _governanceAddress, address _verifierAddress, address _additionalZkSync, bytes32 _genesisStateHash) =
abi.decode(initializationParameters, (address, address, address, bytes32));
(
Governance _governanceAddress,
Verifier _verifierAddress,
AdditionalZkSync _additionalZkSync,
bytes32 _genesisStateHash
) = abi.decode(initializationParameters, (Governance, Verifier, AdditionalZkSync, bytes32));

verifier = Verifier(_verifierAddress);
governance = Governance(_governanceAddress);
additionalZkSync = AdditionalZkSync(_additionalZkSync);
verifier = _verifierAddress;
governance = _governanceAddress;
additionalZkSync = _additionalZkSync;

StoredBlockInfo memory storedBlockZero =
StoredBlockInfo(0, 0, EMPTY_STRING_KECCAK, 0, _genesisStateHash, bytes32(0));
Expand All @@ -148,28 +149,7 @@ contract ZkSync is UpgradeableMaster, Storage, Config, Events, ReentrancyGuard {
/// @notice zkSync contract upgrade. Can be external because Proxy contract intercepts illegal calls of this function.
/// @param upgradeParameters Encoded representation of upgrade parameters
// solhint-disable-next-line no-empty-blocks
function upgrade(bytes calldata upgradeParameters) external nonReentrant {
require(totalBlocksCommitted == totalBlocksProven, "wq1"); // All the blocks must be proven
require(totalBlocksCommitted == totalBlocksExecuted, "w12"); // All the blocks must be executed

StoredBlockInfo memory lastBlockInfo;
(lastBlockInfo) = abi.decode(upgradeParameters, (StoredBlockInfo));
require(storedBlockHashes[totalBlocksExecuted] == hashStoredBlockInfo(lastBlockInfo), "wqqs"); // The provided block info should be equal to the current one

RegenesisMultisig multisig = RegenesisMultisig($$(REGENESIS_MULTISIG_ADDRESS));
bytes32 oldRootHash = multisig.oldRootHash();
require(oldRootHash == lastBlockInfo.stateHash, "wqqe");

bytes32 newRootHash = multisig.newRootHash();

// Overriding the old block's root hash with the new one
lastBlockInfo.stateHash = newRootHash;
storedBlockHashes[totalBlocksExecuted] = hashStoredBlockInfo(lastBlockInfo);
additionalZkSync = AdditionalZkSync(address($$(NEW_ADDITIONAL_ZKSYNC_ADDRESS)));

approvedUpgradeNoticePeriod = UPGRADE_NOTICE_PERIOD;
emit NoticePeriodChange(approvedUpgradeNoticePeriod);
}
function upgrade(bytes calldata upgradeParameters) external nonReentrant {}

function cutUpgradeNoticePeriod() external {
/// All functions delegated to additional contract should NOT be nonReentrant
Expand Down Expand Up @@ -971,7 +951,7 @@ contract ZkSync is UpgradeableMaster, Storage, Config, Events, ReentrancyGuard {
/// @notice Should be only use to delegate the external calls as it passes the calldata
/// @notice All functions delegated to additional contract should NOT be nonReentrant
function delegateAdditional() internal {
address _target = address(additionalZkSync);
AdditionalZkSync _target = additionalZkSync;
assembly {
// The pointer to the free memory slot
let ptr := mload(0x40)
Expand Down
Loading

0 comments on commit e8783eb

Please sign in to comment.