Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
0x60806040 | 20018415 | 292 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
DefaultUpgrade
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 9999999 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {Diamond} from "../state-transition/libraries/Diamond.sol"; import {BaseZkSyncUpgrade, ProposedUpgrade} from "./BaseZkSyncUpgrade.sol"; /// @author Matter Labs /// @custom:security-contact [email protected] contract DefaultUpgrade is BaseZkSyncUpgrade { /// @notice The main function that will be called by the upgrade proxy. /// @param _proposedUpgrade The upgrade to be executed. function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) { super.upgrade(_proposedUpgrade); return Diamond.DIAMOND_INIT_SUCCESS_RETURN_VALUE; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @dev `keccak256("")` bytes32 constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; /// @dev Bytes in raw L2 log /// @dev Equal to the bytes size of the tuple - (uint8 ShardId, bool isService, uint16 txNumberInBatch, address sender, /// bytes32 key, bytes32 value) uint256 constant L2_TO_L1_LOG_SERIALIZE_SIZE = 88; /// @dev The maximum length of the bytes array with L2 -> L1 logs uint256 constant MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES = 4 + L2_TO_L1_LOG_SERIALIZE_SIZE * 512; /// @dev The value of default leaf hash for L2 -> L1 logs Merkle tree /// @dev An incomplete fixed-size tree is filled with this value to be a full binary tree /// @dev Actually equal to the `keccak256(new bytes(L2_TO_L1_LOG_SERIALIZE_SIZE))` bytes32 constant L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH = 0x72abee45b59e344af8a6e520241c4744aff26ed411f4c4b00f8af09adada43ba; // TODO: change constant to the real root hash of empty Merkle tree (SMA-184) bytes32 constant DEFAULT_L2_LOGS_TREE_ROOT_HASH = bytes32(0); /// @dev Denotes the type of the zkSync transaction that came from L1. uint256 constant PRIORITY_OPERATION_L2_TX_TYPE = 255; /// @dev Denotes the type of the zkSync transaction that is used for system upgrades. uint256 constant SYSTEM_UPGRADE_L2_TX_TYPE = 254; /// @dev The maximal allowed difference between protocol minor versions in an upgrade. The 100 gap is needed /// in case a protocol version has been tested on testnet, but then not launched on mainnet, e.g. /// due to a bug found. /// We are allowed to jump at most 100 minor versions at a time. The major version is always expected to be 0. uint256 constant MAX_ALLOWED_MINOR_VERSION_DELTA = 100; /// @dev The amount of time in seconds the validator has to process the priority transaction /// NOTE: The constant is set to zero for the Alpha release period uint256 constant PRIORITY_EXPIRATION = 0 days; /// @dev Timestamp - seconds since unix epoch. uint256 constant COMMIT_TIMESTAMP_NOT_OLDER = 3 days; /// @dev Maximum available error between real commit batch timestamp and analog used in the verifier (in seconds) /// @dev Must be used cause miner's `block.timestamp` value can differ on some small value (as we know - 12 seconds) uint256 constant COMMIT_TIMESTAMP_APPROXIMATION_DELTA = 1 hours; /// @dev Shift to apply to verify public input before verifying. uint256 constant PUBLIC_INPUT_SHIFT = 32; /// @dev The maximum number of L2 gas that a user can request for an L2 transaction uint256 constant MAX_GAS_PER_TRANSACTION = 80_000_000; /// @dev Even though the price for 1 byte of pubdata is 16 L1 gas, we have a slightly increased /// value. uint256 constant L1_GAS_PER_PUBDATA_BYTE = 17; /// @dev The intrinsic cost of the L1->l2 transaction in computational L2 gas uint256 constant L1_TX_INTRINSIC_L2_GAS = 167_157; /// @dev The intrinsic cost of the L1->l2 transaction in pubdata uint256 constant L1_TX_INTRINSIC_PUBDATA = 88; /// @dev The minimal base price for L1 transaction uint256 constant L1_TX_MIN_L2_GAS_BASE = 173_484; /// @dev The number of L2 gas the transaction starts costing more with each 544 bytes of encoding uint256 constant L1_TX_DELTA_544_ENCODING_BYTES = 1656; /// @dev The number of L2 gas an L1->L2 transaction gains with each new factory dependency uint256 constant L1_TX_DELTA_FACTORY_DEPS_L2_GAS = 2473; /// @dev The number of L2 gas an L1->L2 transaction gains with each new factory dependency uint256 constant L1_TX_DELTA_FACTORY_DEPS_PUBDATA = 64; /// @dev The number of pubdata an L1->L2 transaction requires with each new factory dependency uint256 constant MAX_NEW_FACTORY_DEPS = 32; /// @dev The L2 gasPricePerPubdata required to be used in bridges. uint256 constant REQUIRED_L2_GAS_PRICE_PER_PUBDATA = 800; /// @dev The mask which should be applied to the packed batch and L2 block timestamp in order /// to obtain the L2 block timestamp. Applying this mask is equivalent to calculating modulo 2**128 uint256 constant PACKED_L2_BLOCK_TIMESTAMP_MASK = 0xffffffffffffffffffffffffffffffff; /// @dev Address of the point evaluation precompile used for EIP-4844 blob verification. address constant POINT_EVALUATION_PRECOMPILE_ADDR = address(0x0A); /// @dev The overhead for a transaction slot in L2 gas. /// It is roughly equal to 80kk/MAX_TRANSACTIONS_IN_BATCH, i.e. how many gas would an L1->L2 transaction /// need to pay to compensate for the batch being closed. /// @dev It is expected that the L1 contracts will enforce that the L2 gas price will be high enough to compensate /// the operator in case the batch is closed because of tx slots filling up. uint256 constant TX_SLOT_OVERHEAD_L2_GAS = 10000; /// @dev The overhead for each byte of the bootloader memory that the encoding of the transaction. /// It is roughly equal to 80kk/BOOTLOADER_MEMORY_FOR_TXS, i.e. how many gas would an L1->L2 transaction /// need to pay to compensate for the batch being closed. /// @dev It is expected that the L1 contracts will enforce that the L2 gas price will be high enough to compensate /// the operator in case the batch is closed because of the memory for transactions being filled up. uint256 constant MEMORY_OVERHEAD_GAS = 10; /// @dev The maximum gas limit for a priority transaction in L2. uint256 constant PRIORITY_TX_MAX_GAS_LIMIT = 72_000_000; address constant ETH_TOKEN_ADDRESS = address(1); bytes32 constant TWO_BRIDGES_MAGIC_VALUE = bytes32(uint256(keccak256("TWO_BRIDGES_MAGIC_VALUE")) - 1); /// @dev https://eips.ethereum.org/EIPS/eip-1352 address constant BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS = address(uint160(type(uint16).max));
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /** * @author Matter Labs * @custom:security-contact [email protected] * @notice Helper library for working with L2 contracts on L1. */ library L2ContractHelper { /// @dev The prefix used to create CREATE2 addresses. bytes32 private constant CREATE2_PREFIX = keccak256("zksyncCreate2"); /// @notice Validate the bytecode format and calculate its hash. /// @param _bytecode The bytecode to hash. /// @return hashedBytecode The 32-byte hash of the bytecode. /// Note: The function reverts the execution if the bytecode has non expected format: /// - Bytecode bytes length is not a multiple of 32 /// - Bytecode bytes length is not less than 2^21 bytes (2^16 words) /// - Bytecode words length is not odd function hashL2Bytecode(bytes memory _bytecode) internal pure returns (bytes32 hashedBytecode) { // Note that the length of the bytecode must be provided in 32-byte words. require(_bytecode.length % 32 == 0, "pq"); uint256 bytecodeLenInWords = _bytecode.length / 32; require(bytecodeLenInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words require(bytecodeLenInWords % 2 == 1, "ps"); // bytecode length in words must be odd hashedBytecode = sha256(_bytecode) & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // Setting the version of the hash hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248))); // Setting the length hashedBytecode = hashedBytecode | bytes32(bytecodeLenInWords << 224); } /// @notice Validates the format of the given bytecode hash. /// @dev Due to the specification of the L2 bytecode hash, not every 32 bytes could be a legit bytecode hash. /// @dev The function reverts on invalid bytecode hash format. /// @param _bytecodeHash The hash of the bytecode to validate. function validateBytecodeHash(bytes32 _bytecodeHash) internal pure { uint8 version = uint8(_bytecodeHash[0]); require(version == 1 && _bytecodeHash[1] == bytes1(0), "zf"); // Incorrectly formatted bytecodeHash require(bytecodeLen(_bytecodeHash) % 2 == 1, "uy"); // Code length in words must be odd } /// @notice Returns the length of the bytecode associated with the given hash. /// @param _bytecodeHash The hash of the bytecode. /// @return codeLengthInWords The length of the bytecode in words. function bytecodeLen(bytes32 _bytecodeHash) internal pure returns (uint256 codeLengthInWords) { codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3])); } /// @notice Computes the create2 address for a Layer 2 contract. /// @param _sender The address of the sender. /// @param _salt The salt value to use in the create2 address computation. /// @param _bytecodeHash The contract bytecode hash. /// @param _constructorInputHash The hash of the constructor input data. /// @return The create2 address of the contract. /// NOTE: L2 create2 derivation is different from L1 derivation! function computeCreate2Address( address _sender, bytes32 _salt, bytes32 _bytecodeHash, bytes32 _constructorInputHash ) internal pure returns (address) { bytes32 senderBytes = bytes32(uint256(uint160(_sender))); bytes32 data = keccak256( // solhint-disable-next-line func-named-parameters bytes.concat(CREATE2_PREFIX, senderBytes, _salt, _bytecodeHash, _constructorInputHash) ); return address(uint160(uint256(data))); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @dev The number of bits dedicated to the "patch" portion of the protocol version. /// This also defines the bit starting from which the "minor" part is located. uint256 constant SEMVER_MINOR_OFFSET = 32; /// @dev The number of bits dedicated to the "patch" and "minor" portions of the protocol version. /// This also defines the bit starting from which the "major" part is located. /// Note, that currently, only major version of "0" is supported. uint256 constant SEMVER_MAJOR_OFFSET = 64; /** * @author Matter Labs * @custom:security-contact [email protected] * @notice The library for managing SemVer for the protocol version. */ library SemVer { /// @notice Unpacks the SemVer version from a single uint256 into major, minor and patch components. /// @param _packedProtocolVersion The packed protocol version. /// @return major The major version. /// @return minor The minor version. /// @return patch The patch version. function unpackSemVer( uint96 _packedProtocolVersion ) internal pure returns (uint32 major, uint32 minor, uint32 patch) { patch = uint32(_packedProtocolVersion); minor = uint32(_packedProtocolVersion >> SEMVER_MINOR_OFFSET); major = uint32(_packedProtocolVersion >> SEMVER_MAJOR_OFFSET); } /// @notice Packs the SemVer version from the major, minor and patch components into a single uint96. /// @param _major The major version. /// @param _minor The minor version. /// @param _patch The patch version. /// @return packedProtocolVersion The packed protocol version. function packSemVer( uint32 _major, uint32 _minor, uint32 _patch ) internal pure returns (uint96 packedProtocolVersion) { packedProtocolVersion = uint96(_patch) | (uint96(_minor) << SEMVER_MINOR_OFFSET) | (uint96(_major) << SEMVER_MAJOR_OFFSET); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /** * @author Matter Labs * @custom:security-contact [email protected] * @notice The library for unchecked math. */ library UncheckedMath { function uncheckedInc(uint256 _number) internal pure returns (uint256) { unchecked { return _number + 1; } } function uncheckedAdd(uint256 _lhs, uint256 _rhs) internal pure returns (uint256) { unchecked { return _lhs + _rhs; } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @dev The enum that represents the transaction execution status /// @param Failure The transaction execution failed /// @param Success The transaction execution succeeded enum TxStatus { Failure, Success } /// @dev The log passed from L2 /// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter /// All other values are not used but are reserved for the future /// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address. /// This field is required formally but does not have any special meaning /// @param txNumberInBatch The L2 transaction number in a Batch, in which the log was sent /// @param sender The L2 address which sent the log /// @param key The 32 bytes of information that was sent in the log /// @param value The 32 bytes of information that was sent in the log // Both `key` and `value` are arbitrary 32-bytes selected by the log sender struct L2Log { uint8 l2ShardId; bool isService; uint16 txNumberInBatch; address sender; bytes32 key; bytes32 value; } /// @dev An arbitrary length message passed from L2 /// @notice Under the hood it is `L2Log` sent from the special system L2 contract /// @param txNumberInBatch The L2 transaction number in a Batch, in which the message was sent /// @param sender The address of the L2 account from which the message was passed /// @param data An arbitrary length message struct L2Message { uint16 txNumberInBatch; address sender; bytes data; } /// @dev Internal structure that contains the parameters for the writePriorityOp /// internal function. /// @param txId The id of the priority transaction. /// @param l2GasPrice The gas price for the l2 priority operation. /// @param expirationTimestamp The timestamp by which the priority operation must be processed by the operator. /// @param request The external calldata request for the priority operation. struct WritePriorityOpParams { uint256 txId; uint256 l2GasPrice; uint64 expirationTimestamp; BridgehubL2TransactionRequest request; } /// @dev Structure that includes all fields of the L2 transaction /// @dev The hash of this structure is the "canonical L2 transaction hash" and can /// be used as a unique identifier of a tx /// @param txType The tx type number, depending on which the L2 transaction can be /// interpreted differently /// @param from The sender's address. `uint256` type for possible address format changes /// and maintaining backward compatibility /// @param to The recipient's address. `uint256` type for possible address format changes /// and maintaining backward compatibility /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an /// L1 transactions /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata /// (every piece of data that will be stored on L1 as calldata) /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get /// the transaction included in a Batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator /// to incentivize them to include the transaction in a Batch. Analog to the EIP-1559 /// `maxPriorityFeePerGas` on an L1 transactions /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the /// transaction. `uint256` type for possible address format changes and maintaining backward compatibility /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority /// operation Id /// @param value The value to pass with the transaction /// @param reserved The fixed-length fields for usage in a future extension of transaction /// formats /// @param data The calldata that is transmitted for the transaction call /// @param signature An abstract set of bytes that are used for transaction authorization /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1 /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats struct L2CanonicalTransaction { uint256 txType; uint256 from; uint256 to; uint256 gasLimit; uint256 gasPerPubdataByteLimit; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; uint256 paymaster; uint256 nonce; uint256 value; // In the future, we might want to add some // new fields to the struct. The `txData` struct // is to be passed to account and any changes to its structure // would mean a breaking change to these accounts. To prevent this, // we should keep some fields as "reserved" // It is also recommended that their length is fixed, since // it would allow easier proof integration (in case we will need // some special circuit for preprocessing transactions) uint256[4] reserved; bytes data; bytes signature; uint256[] factoryDeps; bytes paymasterInput; // Reserved dynamic type for the future use-case. Using it should be avoided, // But it is still here, just in case we want to enable some additional functionality bytes reservedDynamic; } /// @param sender The sender's address. /// @param contractAddressL2 The address of the contract on L2 to call. /// @param valueToMint The amount of base token that should be minted on L2 as the result of this transaction. /// @param l2Value The msg.value of the L2 transaction. /// @param l2Calldata The calldata for the L2 transaction. /// @param l2GasLimit The limit of the L2 gas for the L2 transaction /// @param l2GasPerPubdataByteLimit The price for a single pubdata byte in L2 gas. /// @param factoryDeps The array of L2 bytecodes that the tx depends on. /// @param refundRecipient The recipient of the refund for the transaction on L2. If the transaction fails, then /// this address will receive the `l2Value`. struct BridgehubL2TransactionRequest { address sender; address contractL2; uint256 mintValue; uint256 l2Value; bytes l2Calldata; uint256 l2GasLimit; uint256 l2GasPerPubdataByteLimit; bytes[] factoryDeps; address refundRecipient; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /** * @custom:security-contact [email protected] * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. * * _Since v2.5.0:_ this module is now much more gas efficient, given net gas * metering changes introduced in the Istanbul hardfork. */ abstract contract ReentrancyGuard { /// @dev Address of lock flag variable. /// @dev Flag is placed at random memory location to not interfere with Storage contract. // keccak256("ReentrancyGuard") - 1; uint256 private constant LOCK_FLAG_ADDRESS = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4; // solhint-disable-next-line max-line-length // 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; modifier reentrancyGuardInitializer() { _initializeReentrancyGuard(); _; } function _initializeReentrancyGuard() private { uint256 lockSlotOldValue; // Storing an initial non-zero value makes deployment a bit more // expensive but in exchange every call to nonReentrant // will be cheaper. assembly { 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"); } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { uint256 _status; assembly { _status := sload(LOCK_FLAG_ADDRESS) } // On the first call to nonReentrant, _notEntered will be true require(_status == _NOT_ENTERED, "r1"); // Any calls to nonReentrant after this point will fail assembly { 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, _NOT_ENTERED) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {ZkSyncHyperchainStorage} from "../ZkSyncHyperchainStorage.sol"; import {ReentrancyGuard} from "../../../common/ReentrancyGuard.sol"; /// @title Base contract containing functions accessible to the other facets. /// @author Matter Labs /// @custom:security-contact [email protected] contract ZkSyncHyperchainBase is ReentrancyGuard { // slither-disable-next-line uninitialized-state ZkSyncHyperchainStorage internal s; /// @notice Checks that the message sender is an active admin modifier onlyAdmin() { require(msg.sender == s.admin, "Hyperchain: not admin"); _; } /// @notice Checks if validator is active modifier onlyValidator() { require(s.validators[msg.sender], "Hyperchain: not validator"); _; } modifier onlyStateTransitionManager() { require(msg.sender == s.stateTransitionManager, "Hyperchain: not state transition manager"); _; } modifier onlyBridgehub() { require(msg.sender == s.bridgehub, "Hyperchain: not bridgehub"); _; } modifier onlyAdminOrStateTransitionManager() { require( msg.sender == s.admin || msg.sender == s.stateTransitionManager, "Hyperchain: Only by admin or state transition manager" ); _; } modifier onlyValidatorOrStateTransitionManager() { require( s.validators[msg.sender] || msg.sender == s.stateTransitionManager, "Hyperchain: Only by validator or state transition manager" ); _; } modifier onlyBaseTokenBridge() { require(msg.sender == s.baseTokenBridge, "Hyperchain: Only base token bridge can call this function"); _; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {IVerifier, VerifierParams} from "../chain-interfaces/IVerifier.sol"; import {PriorityQueue} from "../../state-transition/libraries/PriorityQueue.sol"; /// @notice Indicates whether an upgrade is initiated and if yes what type /// @param None Upgrade is NOT initiated /// @param Transparent Fully transparent upgrade is initiated, upgrade data is publicly known /// @param Shadow Shadow upgrade is initiated, upgrade data is hidden enum UpgradeState { None, Transparent, Shadow } /// @dev Logically separated part of the storage structure, which is responsible for everything related to proxy /// upgrades and diamond cuts /// @param proposedUpgradeHash The hash of the current upgrade proposal, zero if there is no active proposal /// @param state Indicates whether an upgrade is initiated and if yes what type /// @param securityCouncil Address which has the permission to approve instant upgrades (expected to be a Gnosis /// multisig) /// @param approvedBySecurityCouncil Indicates whether the security council has approved the upgrade /// @param proposedUpgradeTimestamp The timestamp when the upgrade was proposed, zero if there are no active proposals /// @param currentProposalId The serial number of proposed upgrades, increments when proposing a new one struct UpgradeStorage { bytes32 proposedUpgradeHash; UpgradeState state; address securityCouncil; bool approvedBySecurityCouncil; uint40 proposedUpgradeTimestamp; uint40 currentProposalId; } /// @notice The struct that describes whether users will be charged for pubdata for L1->L2 transactions. /// @param Rollup The users are charged for pubdata & it is priced based on the gas price on Ethereum. /// @param Validium The pubdata is considered free with regard to the L1 gas price. enum PubdataPricingMode { Rollup, Validium } /// @notice The fee params for L1->L2 transactions for the network. /// @param pubdataPricingMode How the users will charged for pubdata in L1->L2 transactions. /// @param batchOverheadL1Gas The amount of L1 gas required to process the batch (except for the calldata). /// @param maxPubdataPerBatch The maximal number of pubdata that can be emitted per batch. /// @param priorityTxMaxPubdata The maximal amount of pubdata a priority transaction is allowed to publish. /// It can be slightly less than maxPubdataPerBatch in order to have some margin for the bootloader execution. /// @param minimalL2GasPrice The minimal L2 gas price to be used by L1->L2 transactions. It should represent /// the price that a single unit of compute costs. struct FeeParams { PubdataPricingMode pubdataPricingMode; uint32 batchOverheadL1Gas; uint32 maxPubdataPerBatch; uint32 maxL2GasPerBatch; uint32 priorityTxMaxPubdata; uint64 minimalL2GasPrice; } /// @dev storing all storage variables for hyperchain diamond facets /// NOTE: It is used in a proxy, so it is possible to add new variables to the end /// but NOT to modify already existing variables or change their order. /// NOTE: variables prefixed with '__DEPRECATED_' are deprecated and shouldn't be used. /// Their presence is maintained for compatibility and to prevent storage collision. struct ZkSyncHyperchainStorage { /// @dev Storage of variables needed for deprecated diamond cut facet uint256[7] __DEPRECATED_diamondCutStorage; /// @notice Address which will exercise critical changes to the Diamond Proxy (upgrades, freezing & unfreezing). Replaced by STM address __DEPRECATED_governor; /// @notice Address that the governor proposed as one that will replace it address __DEPRECATED_pendingGovernor; /// @notice List of permitted validators mapping(address validatorAddress => bool isValidator) validators; /// @dev Verifier contract. Used to verify aggregated proof for batches IVerifier verifier; /// @notice Total number of executed batches i.e. batches[totalBatchesExecuted] points at the latest executed batch /// (batch 0 is genesis) uint256 totalBatchesExecuted; /// @notice Total number of proved batches i.e. batches[totalBatchesProved] points at the latest proved batch uint256 totalBatchesVerified; /// @notice Total number of committed batches i.e. batches[totalBatchesCommitted] points at the latest committed /// batch uint256 totalBatchesCommitted; /// @dev Stored hashed StoredBatch for batch number mapping(uint256 batchNumber => bytes32 batchHash) storedBatchHashes; /// @dev Stored root hashes of L2 -> L1 logs mapping(uint256 batchNumber => bytes32 l2LogsRootHash) l2LogsRootHashes; /// @dev Container that stores transactions requested from L1 PriorityQueue.Queue priorityQueue; /// @dev The smart contract that manages the list with permission to call contract functions address __DEPRECATED_allowList; VerifierParams __DEPRECATED_verifierParams; /// @notice Bytecode hash of bootloader program. /// @dev Used as an input to zkp-circuit. bytes32 l2BootloaderBytecodeHash; /// @notice Bytecode hash of default account (bytecode for EOA). /// @dev Used as an input to zkp-circuit. bytes32 l2DefaultAccountBytecodeHash; /// @dev Indicates that the porter may be touched on L2 transactions. /// @dev Used as an input to zkp-circuit. bool zkPorterIsAvailable; /// @dev The maximum number of the L2 gas that a user can request for L1 -> L2 transactions /// @dev This is the maximum number of L2 gas that is available for the "body" of the transaction, i.e. /// without overhead for proving the batch. uint256 priorityTxMaxGasLimit; /// @dev Storage of variables needed for upgrade facet UpgradeStorage __DEPRECATED_upgrades; /// @dev A mapping L2 batch number => message number => flag. /// @dev The L2 -> L1 log is sent for every withdrawal, so this mapping is serving as /// a flag to indicate that the message was already processed. /// @dev Used to indicate that eth withdrawal was already processed mapping(uint256 l2BatchNumber => mapping(uint256 l2ToL1MessageNumber => bool isFinalized)) isEthWithdrawalFinalized; /// @dev The most recent withdrawal time and amount reset uint256 __DEPRECATED_lastWithdrawalLimitReset; /// @dev The accumulated withdrawn amount during the withdrawal limit window uint256 __DEPRECATED_withdrawnAmountInWindow; /// @dev A mapping user address => the total deposited amount by the user mapping(address => uint256) __DEPRECATED_totalDepositedAmountPerUser; /// @dev Stores the protocol version. Note, that the protocol version may not only encompass changes to the /// smart contracts, but also to the node behavior. uint256 protocolVersion; /// @dev Hash of the system contract upgrade transaction. If 0, then no upgrade transaction needs to be done. bytes32 l2SystemContractsUpgradeTxHash; /// @dev Batch number where the upgrade transaction has happened. If 0, then no upgrade transaction has happened /// yet. uint256 l2SystemContractsUpgradeBatchNumber; /// @dev Address which will exercise non-critical changes to the Diamond Proxy (changing validator set & unfreezing) address admin; /// @notice Address that the admin proposed as one that will replace admin role address pendingAdmin; /// @dev Fee params used to derive gasPrice for the L1->L2 transactions. For L2 transactions, /// the bootloader gives enough freedom to the operator. FeeParams feeParams; /// @dev Address of the blob versioned hash getter smart contract used for EIP-4844 versioned hashes. address blobVersionedHashRetriever; /// @dev The chainId of the chain uint256 chainId; /// @dev The address of the bridgehub address bridgehub; /// @dev The address of the StateTransitionManager address stateTransitionManager; /// @dev The address of the baseToken contract. Eth is address(1) address baseToken; /// @dev The address of the baseTokenbridge. Eth also uses the shared bridge address baseTokenBridge; /// @notice gasPriceMultiplier for each baseToken, so that each L1->L2 transaction pays for its transaction on the destination /// we multiply by the nominator, and divide by the denominator uint128 baseTokenGasPriceMultiplierNominator; uint128 baseTokenGasPriceMultiplierDenominator; /// @dev The optional address of the contract that has to be used for transaction filtering/whitelisting address transactionFilterer; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @notice Part of the configuration parameters of ZKP circuits struct VerifierParams { bytes32 recursionNodeLevelVkHash; bytes32 recursionLeafLevelVkHash; bytes32 recursionCircuitsSetVksHash; } /// @title The interface of the Verifier contract, responsible for the zero knowledge proof verification. /// @author Matter Labs /// @custom:security-contact [email protected] interface IVerifier { /// @dev Verifies a zk-SNARK proof. /// @return A boolean value indicating whether the zk-SNARK proof is valid. /// Note: The function may revert execution instead of returning false in some cases. function verify( uint256[] calldata _publicInputs, uint256[] calldata _proof, uint256[] calldata _recursiveAggregationInput ) external view returns (bool); /// @notice Calculates a keccak256 hash of the runtime loaded verification keys. /// @return vkHash The keccak256 hash of the loaded verification keys. function verificationKeyHash() external pure returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; /// @author Matter Labs /// @custom:security-contact [email protected] /// @notice The helper library for managing the EIP-2535 diamond proxy. library Diamond { using UncheckedMath for uint256; using SafeCast for uint256; /// @dev Magic value that should be returned by diamond cut initialize contracts. /// @dev Used to distinguish calls to contracts that were supposed to be used as diamond initializer from other contracts. bytes32 internal constant DIAMOND_INIT_SUCCESS_RETURN_VALUE = 0x33774e659306e47509050e97cb651e731180a42d458212294d30751925c551a2; // keccak256("diamond.zksync.init") - 1 /// @dev Storage position of `DiamondStorage` structure. bytes32 private constant DIAMOND_STORAGE_POSITION = 0xc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131b; // keccak256("diamond.standard.diamond.storage") - 1; event DiamondCut(FacetCut[] facetCuts, address initAddress, bytes initCalldata); /// @dev Utility struct that contains associated facet & meta information of selector /// @param facetAddress address of the facet which is connected with selector /// @param selectorPosition index in `FacetToSelectors.selectors` array, where is selector stored /// @param isFreezable denotes whether the selector can be frozen. struct SelectorToFacet { address facetAddress; uint16 selectorPosition; bool isFreezable; } /// @dev Utility struct that contains associated selectors & meta information of facet /// @param selectors list of all selectors that belong to the facet /// @param facetPosition index in `DiamondStorage.facets` array, where is facet stored struct FacetToSelectors { bytes4[] selectors; uint16 facetPosition; } /// @notice The structure that holds all diamond proxy associated parameters /// @dev According to the EIP-2535 should be stored on a special storage key - `DIAMOND_STORAGE_POSITION` /// @param selectorToFacet A mapping from the selector to the facet address and its meta information /// @param facetToSelectors A mapping from facet address to its selectors with meta information /// @param facets The array of all unique facet addresses that belong to the diamond proxy /// @param isFrozen Denotes whether the diamond proxy is frozen and all freezable facets are not accessible struct DiamondStorage { mapping(bytes4 selector => SelectorToFacet selectorInfo) selectorToFacet; mapping(address facetAddress => FacetToSelectors facetInfo) facetToSelectors; address[] facets; bool isFrozen; } /// @dev Parameters for diamond changes that touch one of the facets /// @param facet The address of facet that's affected by the cut /// @param action The action that is made on the facet /// @param isFreezable Denotes whether the facet & all their selectors can be frozen /// @param selectors An array of unique selectors that belongs to the facet address struct FacetCut { address facet; Action action; bool isFreezable; bytes4[] selectors; } /// @dev Structure of the diamond proxy changes /// @param facetCuts The set of changes (adding/removing/replacement) of implementation contracts /// @param initAddress The address that's delegate called after setting up new facet changes /// @param initCalldata Calldata for the delegate call to `initAddress` struct DiamondCutData { FacetCut[] facetCuts; address initAddress; bytes initCalldata; } /// @dev Type of change over diamond: add/replace/remove facets enum Action { Add, Replace, Remove } /// @return diamondStorage The pointer to the storage where all specific diamond proxy parameters stored function getDiamondStorage() internal pure returns (DiamondStorage storage diamondStorage) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { diamondStorage.slot := position } } /// @dev Add/replace/remove any number of selectors and optionally execute a function with delegatecall /// @param _diamondCut Diamond's facet changes and the parameters to optional initialization delegatecall function diamondCut(DiamondCutData memory _diamondCut) internal { FacetCut[] memory facetCuts = _diamondCut.facetCuts; address initAddress = _diamondCut.initAddress; bytes memory initCalldata = _diamondCut.initCalldata; uint256 facetCutsLength = facetCuts.length; for (uint256 i = 0; i < facetCutsLength; i = i.uncheckedInc()) { Action action = facetCuts[i].action; address facet = facetCuts[i].facet; bool isFacetFreezable = facetCuts[i].isFreezable; bytes4[] memory selectors = facetCuts[i].selectors; require(selectors.length > 0, "B"); // no functions for diamond cut if (action == Action.Add) { _addFunctions(facet, selectors, isFacetFreezable); } else if (action == Action.Replace) { _replaceFunctions(facet, selectors, isFacetFreezable); } else if (action == Action.Remove) { _removeFunctions(facet, selectors); } else { revert("C"); // undefined diamond cut action } } _initializeDiamondCut(initAddress, initCalldata); emit DiamondCut(facetCuts, initAddress, initCalldata); } /// @dev Add new functions to the diamond proxy /// NOTE: expect but NOT enforce that `_selectors` is NON-EMPTY array function _addFunctions(address _facet, bytes4[] memory _selectors, bool _isFacetFreezable) private { DiamondStorage storage ds = getDiamondStorage(); // Facet with no code cannot be added. // This check also verifies that the facet does not have zero address, since it is the // address with which 0x00000000 selector is associated. require(_facet.code.length > 0, "G"); // Add facet to the list of facets if the facet address is new one _saveFacetIfNew(_facet); uint256 selectorsLength = _selectors.length; for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) { bytes4 selector = _selectors[i]; SelectorToFacet memory oldFacet = ds.selectorToFacet[selector]; require(oldFacet.facetAddress == address(0), "J"); // facet for this selector already exists _addOneFunction(_facet, selector, _isFacetFreezable); } } /// @dev Change associated facets to already known function selectors /// NOTE: expect but NOT enforce that `_selectors` is NON-EMPTY array function _replaceFunctions(address _facet, bytes4[] memory _selectors, bool _isFacetFreezable) private { DiamondStorage storage ds = getDiamondStorage(); // Facet with no code cannot be added. // This check also verifies that the facet does not have zero address, since it is the // address with which 0x00000000 selector is associated. require(_facet.code.length > 0, "K"); uint256 selectorsLength = _selectors.length; for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) { bytes4 selector = _selectors[i]; SelectorToFacet memory oldFacet = ds.selectorToFacet[selector]; require(oldFacet.facetAddress != address(0), "L"); // it is impossible to replace the facet with zero address _removeOneFunction(oldFacet.facetAddress, selector); // Add facet to the list of facets if the facet address is a new one _saveFacetIfNew(_facet); _addOneFunction(_facet, selector, _isFacetFreezable); } } /// @dev Remove association with function and facet /// NOTE: expect but NOT enforce that `_selectors` is NON-EMPTY array function _removeFunctions(address _facet, bytes4[] memory _selectors) private { DiamondStorage storage ds = getDiamondStorage(); require(_facet == address(0), "a1"); // facet address must be zero uint256 selectorsLength = _selectors.length; for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) { bytes4 selector = _selectors[i]; SelectorToFacet memory oldFacet = ds.selectorToFacet[selector]; require(oldFacet.facetAddress != address(0), "a2"); // Can't delete a non-existent facet _removeOneFunction(oldFacet.facetAddress, selector); } } /// @dev Add address to the list of known facets if it is not on the list yet /// NOTE: should be called ONLY before adding a new selector associated with the address function _saveFacetIfNew(address _facet) private { DiamondStorage storage ds = getDiamondStorage(); uint256 selectorsLength = ds.facetToSelectors[_facet].selectors.length; // If there are no selectors associated with facet then save facet as new one if (selectorsLength == 0) { ds.facetToSelectors[_facet].facetPosition = ds.facets.length.toUint16(); ds.facets.push(_facet); } } /// @dev Add one function to the already known facet /// NOTE: It is expected but NOT enforced that: /// - `_facet` is NON-ZERO address /// - `_facet` is already stored address in `DiamondStorage.facets` /// - `_selector` is NOT associated by another facet function _addOneFunction(address _facet, bytes4 _selector, bool _isSelectorFreezable) private { DiamondStorage storage ds = getDiamondStorage(); uint16 selectorPosition = (ds.facetToSelectors[_facet].selectors.length).toUint16(); // if selectorPosition is nonzero, it means it is not a new facet // so the freezability of the first selector must be matched to _isSelectorFreezable // so all the selectors in a facet will have the same freezability if (selectorPosition != 0) { bytes4 selector0 = ds.facetToSelectors[_facet].selectors[0]; require(_isSelectorFreezable == ds.selectorToFacet[selector0].isFreezable, "J1"); } ds.selectorToFacet[_selector] = SelectorToFacet({ facetAddress: _facet, selectorPosition: selectorPosition, isFreezable: _isSelectorFreezable }); ds.facetToSelectors[_facet].selectors.push(_selector); } /// @dev Remove one associated function with facet /// NOTE: It is expected but NOT enforced that `_facet` is NON-ZERO address function _removeOneFunction(address _facet, bytes4 _selector) private { DiamondStorage storage ds = getDiamondStorage(); // Get index of `FacetToSelectors.selectors` of the selector and last element of array uint256 selectorPosition = ds.selectorToFacet[_selector].selectorPosition; uint256 lastSelectorPosition = ds.facetToSelectors[_facet].selectors.length - 1; // If the selector is not at the end of the array then move the last element to the selector position if (selectorPosition != lastSelectorPosition) { bytes4 lastSelector = ds.facetToSelectors[_facet].selectors[lastSelectorPosition]; ds.facetToSelectors[_facet].selectors[selectorPosition] = lastSelector; ds.selectorToFacet[lastSelector].selectorPosition = selectorPosition.toUint16(); } // Remove last element from the selectors array ds.facetToSelectors[_facet].selectors.pop(); // Finally, clean up the association with facet delete ds.selectorToFacet[_selector]; // If there are no selectors for facet then remove the facet from the list of known facets if (lastSelectorPosition == 0) { _removeFacet(_facet); } } /// @dev remove facet from the list of known facets /// NOTE: It is expected but NOT enforced that there are no selectors associated with `_facet` function _removeFacet(address _facet) private { DiamondStorage storage ds = getDiamondStorage(); // Get index of `DiamondStorage.facets` of the facet and last element of array uint256 facetPosition = ds.facetToSelectors[_facet].facetPosition; uint256 lastFacetPosition = ds.facets.length - 1; // If the facet is not at the end of the array then move the last element to the facet position if (facetPosition != lastFacetPosition) { address lastFacet = ds.facets[lastFacetPosition]; ds.facets[facetPosition] = lastFacet; ds.facetToSelectors[lastFacet].facetPosition = facetPosition.toUint16(); } // Remove last element from the facets array ds.facets.pop(); } /// @dev Delegates call to the initialization address with provided calldata /// @dev Used as a final step of diamond cut to execute the logic of the initialization for changed facets function _initializeDiamondCut(address _init, bytes memory _calldata) private { if (_init == address(0)) { require(_calldata.length == 0, "H"); // Non-empty calldata for zero address } else { // Do not check whether `_init` is a contract since later we check that it returns data. (bool success, bytes memory data) = _init.delegatecall(_calldata); if (!success) { // If the returndata is too small, we still want to produce some meaningful error if (data.length <= 4) { revert("I"); // delegatecall failed } assembly { revert(add(data, 0x20), mload(data)) } } // Check that called contract returns magic value to make sure that contract logic // supposed to be used as diamond cut initializer. require(data.length == 32, "lp"); require(abi.decode(data, (bytes32)) == DIAMOND_INIT_SUCCESS_RETURN_VALUE, "lp1"); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @notice The structure that contains meta information of the L2 transaction that was requested from L1 /// @dev The weird size of fields was selected specifically to minimize the structure storage size /// @param canonicalTxHash Hashed L2 transaction data that is needed to process it /// @param expirationTimestamp Expiration timestamp for this request (must be satisfied before) /// @param layer2Tip Additional payment to the validator as an incentive to perform the operation struct PriorityOperation { bytes32 canonicalTxHash; uint64 expirationTimestamp; uint192 layer2Tip; } /// @author Matter Labs /// @custom:security-contact [email protected] /// @dev The library provides the API to interact with the priority queue container /// @dev Order of processing operations from queue - FIFO (Fist in - first out) library PriorityQueue { using PriorityQueue for Queue; /// @notice Container that stores priority operations /// @param data The inner mapping that saves priority operation by its index /// @param head The pointer to the first unprocessed priority operation, equal to the tail if the queue is empty /// @param tail The pointer to the free slot struct Queue { mapping(uint256 priorityOpId => PriorityOperation priorityOp) data; uint256 tail; uint256 head; } /// @notice Returns zero if and only if no operations were processed from the queue /// @return Index of the oldest priority operation that wasn't processed yet function getFirstUnprocessedPriorityTx(Queue storage _queue) internal view returns (uint256) { return _queue.head; } /// @return The total number of priority operations that were added to the priority queue, including all processed ones function getTotalPriorityTxs(Queue storage _queue) internal view returns (uint256) { return _queue.tail; } /// @return The total number of unprocessed priority operations in a priority queue function getSize(Queue storage _queue) internal view returns (uint256) { return uint256(_queue.tail - _queue.head); } /// @return Whether the priority queue contains no operations function isEmpty(Queue storage _queue) internal view returns (bool) { return _queue.tail == _queue.head; } /// @notice Add the priority operation to the end of the priority queue function pushBack(Queue storage _queue, PriorityOperation memory _operation) internal { // Save value into the stack to avoid double reading from the storage uint256 tail = _queue.tail; _queue.data[tail] = _operation; _queue.tail = tail + 1; } /// @return The first unprocessed priority operation from the queue function front(Queue storage _queue) internal view returns (PriorityOperation memory) { require(!_queue.isEmpty(), "D"); // priority queue is empty return _queue.data[_queue.head]; } /// @notice Remove the first unprocessed priority operation from the queue /// @return priorityOperation that was popped from the priority queue function popFront(Queue storage _queue) internal returns (PriorityOperation memory priorityOperation) { require(!_queue.isEmpty(), "s"); // priority queue is empty // Save value into the stack to avoid double reading from the storage uint256 head = _queue.head; priorityOperation = _queue.data[head]; delete _queue.data[head]; _queue.head = head + 1; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {L2CanonicalTransaction} from "../../common/Messaging.sol"; import {TX_SLOT_OVERHEAD_L2_GAS, MEMORY_OVERHEAD_GAS, L1_TX_INTRINSIC_L2_GAS, L1_TX_DELTA_544_ENCODING_BYTES, L1_TX_DELTA_FACTORY_DEPS_L2_GAS, L1_TX_MIN_L2_GAS_BASE, L1_TX_INTRINSIC_PUBDATA, L1_TX_DELTA_FACTORY_DEPS_PUBDATA} from "../../common/Config.sol"; /// @title zkSync Library for validating L1 -> L2 transactions /// @author Matter Labs /// @custom:security-contact [email protected] library TransactionValidator { /// @dev Used to validate key properties of an L1->L2 transaction /// @param _transaction The transaction to validate /// @param _encoded The abi encoded bytes of the transaction /// @param _priorityTxMaxGasLimit The max gas limit, generally provided from Storage.sol /// @param _priorityTxMaxPubdata The maximal amount of pubdata that a single L1->L2 transaction can emit function validateL1ToL2Transaction( L2CanonicalTransaction memory _transaction, bytes memory _encoded, uint256 _priorityTxMaxGasLimit, uint256 _priorityTxMaxPubdata ) internal pure { uint256 l2GasForTxBody = getTransactionBodyGasLimit(_transaction.gasLimit, _encoded.length); // Ensuring that the transaction is provable require(l2GasForTxBody <= _priorityTxMaxGasLimit, "ui"); // Ensuring that the transaction cannot output more pubdata than is processable require(l2GasForTxBody / _transaction.gasPerPubdataByteLimit <= _priorityTxMaxPubdata, "uk"); // Ensuring that the transaction covers the minimal costs for its processing: // hashing its content, publishing the factory dependencies, etc. require( getMinimalPriorityTransactionGasLimit( _encoded.length, _transaction.factoryDeps.length, _transaction.gasPerPubdataByteLimit ) <= l2GasForTxBody, "up" ); } /// @dev Used to validate upgrade transactions /// @param _transaction The transaction to validate function validateUpgradeTransaction(L2CanonicalTransaction memory _transaction) internal pure { // Restrict from to be within system contract range (0...2^16 - 1) require(_transaction.from <= type(uint16).max, "ua"); require(_transaction.to <= type(uint160).max, "ub"); require(_transaction.paymaster == 0, "uc"); require(_transaction.value == 0, "ud"); require(_transaction.maxFeePerGas == 0, "uq"); require(_transaction.maxPriorityFeePerGas == 0, "ux"); require(_transaction.reserved[0] == 0, "ue"); require(_transaction.reserved[1] <= type(uint160).max, "uf"); require(_transaction.reserved[2] == 0, "ug"); require(_transaction.reserved[3] == 0, "uo"); require(_transaction.signature.length == 0, "uh"); require(_transaction.paymasterInput.length == 0, "ul1"); require(_transaction.reservedDynamic.length == 0, "um"); } /// @dev Calculates the approximate minimum gas limit required for executing a priority transaction. /// @param _encodingLength The length of the priority transaction encoding in bytes. /// @param _numberOfFactoryDependencies The number of new factory dependencies that will be added. /// @param _l2GasPricePerPubdata The L2 gas price for publishing the priority transaction on L2. /// @return The minimum gas limit required to execute the priority transaction. /// Note: The calculation includes the main cost of the priority transaction, however, in reality, the operator can spend a little more gas on overheads. function getMinimalPriorityTransactionGasLimit( uint256 _encodingLength, uint256 _numberOfFactoryDependencies, uint256 _l2GasPricePerPubdata ) internal pure returns (uint256) { uint256 costForComputation; { // Adding the intrinsic cost for the transaction, i.e. auxiliary prices which cannot be easily accounted for costForComputation = L1_TX_INTRINSIC_L2_GAS; // Taking into account the hashing costs that depend on the length of the transaction // Note that L1_TX_DELTA_544_ENCODING_BYTES is the delta in the price for every 544 bytes of // the transaction's encoding. It is taken as LCM between 136 and 32 (the length for each keccak256 round // and the size of each new encoding word). costForComputation += Math.ceilDiv(_encodingLength * L1_TX_DELTA_544_ENCODING_BYTES, 544); // Taking into the account the additional costs of providing new factory dependencies costForComputation += _numberOfFactoryDependencies * L1_TX_DELTA_FACTORY_DEPS_L2_GAS; // There is a minimal amount of computational L2 gas that the transaction should cover costForComputation = Math.max(costForComputation, L1_TX_MIN_L2_GAS_BASE); } uint256 costForPubdata = 0; { // Adding the intrinsic cost for the transaction, i.e. auxiliary prices which cannot be easily accounted for costForPubdata = L1_TX_INTRINSIC_PUBDATA * _l2GasPricePerPubdata; // Taking into the account the additional costs of providing new factory dependencies costForPubdata += _numberOfFactoryDependencies * L1_TX_DELTA_FACTORY_DEPS_PUBDATA * _l2GasPricePerPubdata; } return costForComputation + costForPubdata; } /// @notice Based on the full L2 gas limit (that includes the batch overhead) and other /// properties of the transaction, returns the l2GasLimit for the body of the transaction (the actual execution). /// @param _totalGasLimit The L2 gas limit that includes both the overhead for processing the batch /// and the L2 gas needed to process the transaction itself (i.e. the actual l2GasLimit that will be used for the transaction). /// @param _encodingLength The length of the ABI-encoding of the transaction. function getTransactionBodyGasLimit( uint256 _totalGasLimit, uint256 _encodingLength ) internal pure returns (uint256 txBodyGasLimit) { uint256 overhead = getOverheadForTransaction(_encodingLength); require(_totalGasLimit >= overhead, "my"); // provided gas limit doesn't cover transaction overhead unchecked { // We enforce the fact that `_totalGasLimit >= overhead` explicitly above. txBodyGasLimit = _totalGasLimit - overhead; } } /// @notice Based on the total L2 gas limit and several other parameters of the transaction /// returns the part of the L2 gas that will be spent on the batch's overhead. /// @dev The details of how this function works can be checked in the documentation /// of the fee model of zkSync. The appropriate comments are also present /// in the Rust implementation description of function `get_maximal_allowed_overhead`. /// @param _encodingLength The length of the binary encoding of the transaction in bytes function getOverheadForTransaction( uint256 _encodingLength ) internal pure returns (uint256 batchOverheadForTransaction) { // The overhead from taking up the transaction's slot batchOverheadForTransaction = TX_SLOT_OVERHEAD_L2_GAS; // The overhead for occupying the bootloader memory can be derived from encoded_len uint256 overheadForLength = MEMORY_OVERHEAD_GAS * _encodingLength; batchOverheadForTransaction = Math.max(batchOverheadForTransaction, overheadForLength); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import {ZkSyncHyperchainBase} from "../state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol"; import {VerifierParams} from "../state-transition/chain-interfaces/IVerifier.sol"; import {IVerifier} from "../state-transition/chain-interfaces/IVerifier.sol"; import {L2ContractHelper} from "../common/libraries/L2ContractHelper.sol"; import {TransactionValidator} from "../state-transition/libraries/TransactionValidator.sol"; import {MAX_NEW_FACTORY_DEPS, SYSTEM_UPGRADE_L2_TX_TYPE, MAX_ALLOWED_MINOR_VERSION_DELTA} from "../common/Config.sol"; import {L2CanonicalTransaction} from "../common/Messaging.sol"; import {SemVer} from "../common/libraries/SemVer.sol"; /// @notice The struct that represents the upgrade proposal. /// @param l2ProtocolUpgradeTx The system upgrade transaction. /// @param factoryDeps The list of factory deps for the l2ProtocolUpgradeTx. /// @param bootloaderHash The hash of the new bootloader bytecode. If zero, it will not be updated. /// @param defaultAccountHash The hash of the new default account bytecode. If zero, it will not be updated. /// @param verifier The address of the new verifier. If zero, the verifier will not be updated. /// @param verifierParams The new verifier params. If all of its fields are 0, the params will not be updated. /// @param l1ContractsUpgradeCalldata Custom calldata for L1 contracts upgrade, it may be interpreted differently /// in each upgrade. Usually empty. /// @param postUpgradeCalldata Custom calldata for post upgrade hook, it may be interpreted differently in each /// upgrade. Usually empty. /// @param upgradeTimestamp The timestamp after which the upgrade can be executed. /// @param newProtocolVersion The new version number for the protocol after this upgrade. Should be greater than /// the previous protocol version. struct ProposedUpgrade { L2CanonicalTransaction l2ProtocolUpgradeTx; bytes[] factoryDeps; bytes32 bootloaderHash; bytes32 defaultAccountHash; address verifier; VerifierParams verifierParams; bytes l1ContractsUpgradeCalldata; bytes postUpgradeCalldata; uint256 upgradeTimestamp; uint256 newProtocolVersion; } /// @author Matter Labs /// @custom:security-contact [email protected] /// @notice Interface to which all the upgrade implementations should adhere abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { /// @notice Changes the protocol version event NewProtocolVersion(uint256 indexed previousProtocolVersion, uint256 indexed newProtocolVersion); /// @notice Сhanges to the bytecode that is used in L2 as a bootloader (start program) event NewL2BootloaderBytecodeHash(bytes32 indexed previousBytecodeHash, bytes32 indexed newBytecodeHash); /// @notice Сhanges to the bytecode that is used in L2 as a default account event NewL2DefaultAccountBytecodeHash(bytes32 indexed previousBytecodeHash, bytes32 indexed newBytecodeHash); /// @notice Verifier address changed event NewVerifier(address indexed oldVerifier, address indexed newVerifier); /// @notice Verifier parameters changed event NewVerifierParams(VerifierParams oldVerifierParams, VerifierParams newVerifierParams); /// @notice Notifies about complete upgrade event UpgradeComplete(uint256 indexed newProtocolVersion, bytes32 indexed l2UpgradeTxHash, ProposedUpgrade upgrade); /// @notice The main function that will be provided by the upgrade proxy /// @dev This is a virtual function and should be overridden by custom upgrade implementations. /// @param _proposedUpgrade The upgrade to be executed. /// @return txHash The hash of the L2 system contract upgrade transaction. function upgrade(ProposedUpgrade calldata _proposedUpgrade) public virtual returns (bytes32 txHash) { // Note that due to commitment delay, the timestamp of the L2 upgrade batch may be earlier than the timestamp // of the L1 block at which the upgrade occurred. This means that using timestamp as a signifier of "upgraded" // on the L2 side would be inaccurate. The effects of this "back-dating" of L2 upgrade batches will be reduced // as the permitted delay window is reduced in the future. require(block.timestamp >= _proposedUpgrade.upgradeTimestamp, "Upgrade is not ready yet"); (uint32 newMinorVersion, bool isPatchOnly) = _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); _upgradeL1Contract(_proposedUpgrade.l1ContractsUpgradeCalldata); _upgradeVerifier(_proposedUpgrade.verifier, _proposedUpgrade.verifierParams); _setBaseSystemContracts(_proposedUpgrade.bootloaderHash, _proposedUpgrade.defaultAccountHash, isPatchOnly); txHash = _setL2SystemContractUpgrade( _proposedUpgrade.l2ProtocolUpgradeTx, _proposedUpgrade.factoryDeps, newMinorVersion, isPatchOnly ); _postUpgrade(_proposedUpgrade.postUpgradeCalldata); emit UpgradeComplete(_proposedUpgrade.newProtocolVersion, txHash, _proposedUpgrade); } /// @notice Change default account bytecode hash, that is used on L2 /// @param _l2DefaultAccountBytecodeHash The hash of default account L2 bytecode /// @param _patchOnly Whether only the patch part of the protocol version semver has changed function _setL2DefaultAccountBytecodeHash(bytes32 _l2DefaultAccountBytecodeHash, bool _patchOnly) private { if (_l2DefaultAccountBytecodeHash == bytes32(0)) { return; } require(!_patchOnly, "Patch only upgrade can not set new default account"); L2ContractHelper.validateBytecodeHash(_l2DefaultAccountBytecodeHash); // Save previous value into the stack to put it into the event later bytes32 previousDefaultAccountBytecodeHash = s.l2DefaultAccountBytecodeHash; // Change the default account bytecode hash s.l2DefaultAccountBytecodeHash = _l2DefaultAccountBytecodeHash; emit NewL2DefaultAccountBytecodeHash(previousDefaultAccountBytecodeHash, _l2DefaultAccountBytecodeHash); } /// @notice Change bootloader bytecode hash, that is used on L2 /// @param _l2BootloaderBytecodeHash The hash of bootloader L2 bytecode /// @param _patchOnly Whether only the patch part of the protocol version semver has changed function _setL2BootloaderBytecodeHash(bytes32 _l2BootloaderBytecodeHash, bool _patchOnly) private { if (_l2BootloaderBytecodeHash == bytes32(0)) { return; } require(!_patchOnly, "Patch only upgrade can not set new bootloader"); L2ContractHelper.validateBytecodeHash(_l2BootloaderBytecodeHash); // Save previous value into the stack to put it into the event later bytes32 previousBootloaderBytecodeHash = s.l2BootloaderBytecodeHash; // Change the bootloader bytecode hash s.l2BootloaderBytecodeHash = _l2BootloaderBytecodeHash; emit NewL2BootloaderBytecodeHash(previousBootloaderBytecodeHash, _l2BootloaderBytecodeHash); } /// @notice Change the address of the verifier smart contract /// @param _newVerifier Verifier smart contract address function _setVerifier(IVerifier _newVerifier) private { // An upgrade to the verifier must be done carefully to ensure there aren't batches in the committed state // during the transition. If verifier is upgraded, it will immediately be used to prove all committed batches. // Batches committed expecting the old verifier will fail. Ensure all committed batches are finalized before the // verifier is upgraded. if (_newVerifier == IVerifier(address(0))) { return; } IVerifier oldVerifier = s.verifier; s.verifier = _newVerifier; emit NewVerifier(address(oldVerifier), address(_newVerifier)); } /// @notice Change the verifier parameters /// @param _newVerifierParams New parameters for the verifier function _setVerifierParams(VerifierParams calldata _newVerifierParams) private { // An upgrade to the verifier params must be done carefully to ensure there aren't batches in the committed state // during the transition. If verifier is upgraded, it will immediately be used to prove all committed batches. // Batches committed expecting the old verifier params will fail. Ensure all committed batches are finalized before the // verifier is upgraded. if ( _newVerifierParams.recursionNodeLevelVkHash == bytes32(0) && _newVerifierParams.recursionLeafLevelVkHash == bytes32(0) && _newVerifierParams.recursionCircuitsSetVksHash == bytes32(0) ) { return; } VerifierParams memory oldVerifierParams = s.__DEPRECATED_verifierParams; s.__DEPRECATED_verifierParams = _newVerifierParams; emit NewVerifierParams(oldVerifierParams, _newVerifierParams); } /// @notice Updates the verifier and the verifier params /// @param _newVerifier The address of the new verifier. If 0, the verifier will not be updated. /// @param _verifierParams The new verifier params. If all of the fields are 0, the params will not be updated. function _upgradeVerifier(address _newVerifier, VerifierParams calldata _verifierParams) internal { _setVerifier(IVerifier(_newVerifier)); _setVerifierParams(_verifierParams); } /// @notice Updates the bootloader hash and the hash of the default account /// @param _bootloaderHash The hash of the new bootloader bytecode. If zero, it will not be updated. /// @param _defaultAccountHash The hash of the new default account bytecode. If zero, it will not be updated. /// @param _patchOnly Whether only the patch part of the protocol version semver has changed. function _setBaseSystemContracts(bytes32 _bootloaderHash, bytes32 _defaultAccountHash, bool _patchOnly) internal { _setL2BootloaderBytecodeHash(_bootloaderHash, _patchOnly); _setL2DefaultAccountBytecodeHash(_defaultAccountHash, _patchOnly); } /// @notice Sets the hash of the L2 system contract upgrade transaction for the next batch to be committed /// @dev If the transaction is noop (i.e. its type is 0) it does nothing and returns 0. /// @param _l2ProtocolUpgradeTx The L2 system contract upgrade transaction. /// @param _factoryDeps The factory dependencies that are used by the transaction. /// @param _newMinorProtocolVersion The new minor protocol version. It must be used as the `nonce` field /// of the `_l2ProtocolUpgradeTx`. /// @param _patchOnly Whether only the patch part of the protocol version semver has changed. /// @return System contracts upgrade transaction hash. Zero if no upgrade transaction is set. function _setL2SystemContractUpgrade( L2CanonicalTransaction calldata _l2ProtocolUpgradeTx, bytes[] calldata _factoryDeps, uint32 _newMinorProtocolVersion, bool _patchOnly ) internal returns (bytes32) { // If the type is 0, it is considered as noop and so will not be required to be executed. if (_l2ProtocolUpgradeTx.txType == 0) { return bytes32(0); } require(!_patchOnly, "Patch only upgrade can not set upgrade transaction"); require(_l2ProtocolUpgradeTx.txType == SYSTEM_UPGRADE_L2_TX_TYPE, "L2 system upgrade tx type is wrong"); bytes memory encodedTransaction = abi.encode(_l2ProtocolUpgradeTx); TransactionValidator.validateL1ToL2Transaction( _l2ProtocolUpgradeTx, encodedTransaction, s.priorityTxMaxGasLimit, s.feeParams.priorityTxMaxPubdata ); TransactionValidator.validateUpgradeTransaction(_l2ProtocolUpgradeTx); // We want the hashes of l2 system upgrade transactions to be unique. // This is why we require that the `nonce` field is unique to each upgrade. require( _l2ProtocolUpgradeTx.nonce == _newMinorProtocolVersion, "The new protocol version should be included in the L2 system upgrade tx" ); _verifyFactoryDeps(_factoryDeps, _l2ProtocolUpgradeTx.factoryDeps); bytes32 l2ProtocolUpgradeTxHash = keccak256(encodedTransaction); s.l2SystemContractsUpgradeTxHash = l2ProtocolUpgradeTxHash; return l2ProtocolUpgradeTxHash; } /// @notice Verifies that the factory deps correspond to the proper hashes /// @param _factoryDeps The list of factory deps /// @param _expectedHashes The list of expected bytecode hashes function _verifyFactoryDeps(bytes[] calldata _factoryDeps, uint256[] calldata _expectedHashes) private pure { require(_factoryDeps.length == _expectedHashes.length, "Wrong number of factory deps"); require(_factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "Factory deps can be at most 32"); for (uint256 i = 0; i < _factoryDeps.length; ++i) { require( L2ContractHelper.hashL2Bytecode(_factoryDeps[i]) == bytes32(_expectedHashes[i]), "Wrong factory dep hash" ); } } /// @notice Changes the protocol version /// @param _newProtocolVersion The new protocol version function _setNewProtocolVersion( uint256 _newProtocolVersion ) internal virtual returns (uint32 newMinorVersion, bool patchOnly) { uint256 previousProtocolVersion = s.protocolVersion; require( _newProtocolVersion > previousProtocolVersion, "New protocol version is not greater than the current one" ); // slither-disable-next-line unused-return (uint32 previousMajorVersion, uint32 previousMinorVersion, ) = SemVer.unpackSemVer( SafeCast.toUint96(previousProtocolVersion) ); require(previousMajorVersion == 0, "Implementation requires that the major version is 0 at all times"); uint32 newMajorVersion; // slither-disable-next-line unused-return (newMajorVersion, newMinorVersion, ) = SemVer.unpackSemVer(SafeCast.toUint96(_newProtocolVersion)); require(newMajorVersion == 0, "Major must always be 0"); // Since `_newProtocolVersion > previousProtocolVersion`, and both old and new major version is 0, // the difference between minor versions is >= 0. uint256 minorDelta = newMinorVersion - previousMinorVersion; if (minorDelta == 0) { patchOnly = true; } // While this is implicitly enforced by other checks above, we still double check just in case require(minorDelta <= MAX_ALLOWED_MINOR_VERSION_DELTA, "Too big protocol version difference"); // If the minor version changes also, we need to ensure that the previous upgrade has been finalized. // In case the minor version does not change, we permit to keep the old upgrade transaction in the system, but it // must be ensured in the other parts of the upgrade that the is not overridden. if (!patchOnly) { // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. // Note it is important to keep this check, as otherwise hyperchains might skip upgrades by overwriting require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); require( s.l2SystemContractsUpgradeBatchNumber == 0, "The batch number of the previous upgrade has not been cleaned" ); } s.protocolVersion = _newProtocolVersion; emit NewProtocolVersion(previousProtocolVersion, _newProtocolVersion); } /// @notice Placeholder function for custom logic for upgrading L1 contract. /// Typically this function will never be used. /// @param _customCallDataForUpgrade Custom data for an upgrade, which may be interpreted differently for each /// upgrade. function _upgradeL1Contract(bytes calldata _customCallDataForUpgrade) internal virtual {} /// @notice placeholder function for custom logic for post-upgrade logic. /// Typically this function will never be used. /// @param _customCallDataForUpgrade Custom data for an upgrade, which may be interpreted differently for each /// upgrade. function _postUpgrade(bytes calldata _customCallDataForUpgrade) internal virtual {} }
{ "optimizer": { "enabled": true, "runs": 9999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"previousBytecodeHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newBytecodeHash","type":"bytes32"}],"name":"NewL2BootloaderBytecodeHash","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"previousBytecodeHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newBytecodeHash","type":"bytes32"}],"name":"NewL2DefaultAccountBytecodeHash","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"previousProtocolVersion","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newProtocolVersion","type":"uint256"}],"name":"NewProtocolVersion","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldVerifier","type":"address"},{"indexed":true,"internalType":"address","name":"newVerifier","type":"address"}],"name":"NewVerifier","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bytes32","name":"recursionNodeLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionLeafLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionCircuitsSetVksHash","type":"bytes32"}],"indexed":false,"internalType":"struct VerifierParams","name":"oldVerifierParams","type":"tuple"},{"components":[{"internalType":"bytes32","name":"recursionNodeLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionLeafLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionCircuitsSetVksHash","type":"bytes32"}],"indexed":false,"internalType":"struct VerifierParams","name":"newVerifierParams","type":"tuple"}],"name":"NewVerifierParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newProtocolVersion","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"l2UpgradeTxHash","type":"bytes32"},{"components":[{"components":[{"internalType":"uint256","name":"txType","type":"uint256"},{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"gasPerPubdataByteLimit","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"uint256","name":"paymaster","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256[4]","name":"reserved","type":"uint256[4]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"factoryDeps","type":"uint256[]"},{"internalType":"bytes","name":"paymasterInput","type":"bytes"},{"internalType":"bytes","name":"reservedDynamic","type":"bytes"}],"internalType":"struct L2CanonicalTransaction","name":"l2ProtocolUpgradeTx","type":"tuple"},{"internalType":"bytes[]","name":"factoryDeps","type":"bytes[]"},{"internalType":"bytes32","name":"bootloaderHash","type":"bytes32"},{"internalType":"bytes32","name":"defaultAccountHash","type":"bytes32"},{"internalType":"address","name":"verifier","type":"address"},{"components":[{"internalType":"bytes32","name":"recursionNodeLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionLeafLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionCircuitsSetVksHash","type":"bytes32"}],"internalType":"struct VerifierParams","name":"verifierParams","type":"tuple"},{"internalType":"bytes","name":"l1ContractsUpgradeCalldata","type":"bytes"},{"internalType":"bytes","name":"postUpgradeCalldata","type":"bytes"},{"internalType":"uint256","name":"upgradeTimestamp","type":"uint256"},{"internalType":"uint256","name":"newProtocolVersion","type":"uint256"}],"indexed":false,"internalType":"struct ProposedUpgrade","name":"upgrade","type":"tuple"}],"name":"UpgradeComplete","type":"event"},{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"txType","type":"uint256"},{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"gasPerPubdataByteLimit","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"uint256","name":"paymaster","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256[4]","name":"reserved","type":"uint256[4]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"factoryDeps","type":"uint256[]"},{"internalType":"bytes","name":"paymasterInput","type":"bytes"},{"internalType":"bytes","name":"reservedDynamic","type":"bytes"}],"internalType":"struct L2CanonicalTransaction","name":"l2ProtocolUpgradeTx","type":"tuple"},{"internalType":"bytes[]","name":"factoryDeps","type":"bytes[]"},{"internalType":"bytes32","name":"bootloaderHash","type":"bytes32"},{"internalType":"bytes32","name":"defaultAccountHash","type":"bytes32"},{"internalType":"address","name":"verifier","type":"address"},{"components":[{"internalType":"bytes32","name":"recursionNodeLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionLeafLevelVkHash","type":"bytes32"},{"internalType":"bytes32","name":"recursionCircuitsSetVksHash","type":"bytes32"}],"internalType":"struct VerifierParams","name":"verifierParams","type":"tuple"},{"internalType":"bytes","name":"l1ContractsUpgradeCalldata","type":"bytes"},{"internalType":"bytes","name":"postUpgradeCalldata","type":"bytes"},{"internalType":"uint256","name":"upgradeTimestamp","type":"uint256"},{"internalType":"uint256","name":"newProtocolVersion","type":"uint256"}],"internalType":"struct ProposedUpgrade","name":"_proposedUpgrade","type":"tuple"}],"name":"upgrade","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561000f575f80fd5b506125078061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c806308284e571461002d575b5f80fd5b61004061003b3660046119b9565b610052565b60405190815260200160405180910390f35b5f61005c82610084565b507f33774e659306e47509050e97cb651e731180a42d458212294d30751925c551a292915050565b5f8161014001354210156100f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f55706772616465206973206e6f7420726561647920796574000000000000000060448201526064015b60405180910390fd5b5f806101098461016001356101cb565b909250905061012361011f6101008601866119f1565b5050565b61013f61013660a0860160808701611a81565b8560a0016105ba565b61015284604001358560600135836105cc565b61017361015f8580611a9a565b61016c6020870187611ad6565b85856105e5565b925061018661011f6101208601866119f1565b828461016001357f56405fee20a4cf3c21d1b23cbbedc0f54921b0347dc19a7641c80645f6916798866040516101bc9190611e8a565b60405180910390a35050919050565b6021545f908190808411610261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4e65772070726f746f636f6c2076657273696f6e206973206e6f74206772656160448201527f746572207468616e207468652063757272656e74206f6e65000000000000000060648201526084016100f0565b5f8061028e61026f8461086b565b63ffffffff604082901c169167ffffffffffffffff602083901c169190565b50915091508163ffffffff165f1461032a57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f496d706c656d656e746174696f6e20726571756972657320746861742074686560448201527f206d616a6f722076657273696f6e206973203020617420616c6c2074696d657360648201526084016100f0565b5f61033761026f8861086b565b509650905063ffffffff8116156103aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d616a6f72206d75737420616c7761797320626520300000000000000000000060448201526064016100f0565b5f6103b58388611ffd565b63ffffffff169050805f036103c957600195505b606481111561045a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f546f6f206269672070726f746f636f6c2076657273696f6e206469666665726560448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084016100f0565b8561057f57602254156104ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f50726576696f7573207570677261646520686173206e6f74206265656e20666960448201527f6e616c697a65640000000000000000000000000000000000000000000000000060648201526084016100f0565b6023541561057f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f546865206261746368206e756d626572206f66207468652070726576696f757360448201527f207570677261646520686173206e6f74206265656e20636c65616e656400000060648201526084016100f0565b6021889055604051889086907f4235104f56661fe2e9d2f2a460b42766581bc45ce366c6a30a9f86c8a2b371a7905f90a35050505050915091565b6105c38261090c565b61011f816109a0565b6105d68382610a39565b6105e08282610b12565b505050565b5f853581036105f557505f610862565b8115610683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f5061746368206f6e6c7920757067726164652063616e206e6f7420736574207560448201527f706772616465207472616e73616374696f6e000000000000000000000000000060648201526084016100f0565b853560fe14610714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c322073797374656d207570677261646520747820747970652069732077726f60448201527f6e6700000000000000000000000000000000000000000000000000000000000060648201526084016100f0565b5f866040516020016107269190612021565b60405160208183030381529060405290506107698761074490612240565b601a546026548491906d0100000000000000000000000000900463ffffffff16610beb565b61077a61077588612240565b610d66565b8363ffffffff168761010001351461083a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f546865206e65772070726f746f636f6c2076657273696f6e2073686f756c642060448201527f626520696e636c7564656420696e20746865204c322073797374656d2075706760648201527f7261646520747800000000000000000000000000000000000000000000000000608482015260a4016100f0565b610852868661084d6102008b018b611ad6565b61132d565b8051602090910120602281905590505b95945050505050565b5f6bffffffffffffffffffffffff821115610908576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016100f0565b5090565b73ffffffffffffffffffffffffffffffffffffffff811661092a5750565b600a805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2ff4895c300d6993c27f2bb507b4b59d29464dc640af727383451365631ba8b2905f90a35050565b80351580156109b157506020810135155b80156109bf57506040810135155b156109c75750565b604080516060810182526014805482526015805460208085019190915260168054858701528635909355850135905583830135905590517f4c055dbc5f14dcb6e081c9421d9657d950dcd6372f6db0a714b9135171cbc15d90610a2d9083908590612398565b60405180910390a15050565b81610a42575050565b8015610ad0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5061746368206f6e6c7920757067726164652063616e206e6f7420736574206e60448201527f657720626f6f746c6f616465720000000000000000000000000000000000000060648201526084016100f0565b610ad9826114f5565b6017805490839055604051839082907f271b33af94e3f065ecd8659833e6b1daf851f063700c36ddefefab35d4ce4746905f90a3505050565b81610b1b575050565b8015610ba9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f5061746368206f6e6c7920757067726164652063616e206e6f7420736574206e60448201527f65772064656661756c74206163636f756e74000000000000000000000000000060648201526084016100f0565b610bb2826114f5565b6018805490839055604051839082907f36df93a47cc02081d9d8208022ab736fdf98fac566e5fc6f5762bf7666e521f3905f90a3505050565b5f610bfb85606001518551611614565b905082811115610c67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756900000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b81856080015182610c7891906123fe565b1115610ce0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756b00000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b80610cf78551876101a00151518860800151611694565b1115610d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757000000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b5050505050565b602081015161ffff1015610dd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756100000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b604081015173ffffffffffffffffffffffffffffffffffffffff1015610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756200000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60e081015115610ec4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756300000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b61012081015115610f31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756400000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60a081015115610f9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757100000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60c081015115611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757800000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101408101515115611077576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756500000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101408101516020015173ffffffffffffffffffffffffffffffffffffffff10156110fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756600000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b610140810151604001511561116f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756700000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b61014081015160600151156111e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756f00000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b610180810151511561124e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756800000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101c081015151156112bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f756c31000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101e0810151511561132a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756d00000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b50565b828114611396576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f57726f6e67206e756d626572206f6620666163746f727920646570730000000060448201526064016100f0565b6020831115611401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f466163746f727920646570732063616e206265206174206d6f7374203332000060448201526064016100f0565b5f5b83811015610d5f5782828281811061141d5761141d612411565b905060200201355f1b61148686868481811061143b5761143b612411565b905060200281019061144d91906119f1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061172992505050565b146114ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f57726f6e6720666163746f72792064657020686173680000000000000000000060448201526064016100f0565b600101611403565b5f81901a60018114801561153057507fff00000000000000000000000000000000000000000000000000000000000000600183901a60f81b16155b611596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f7a6600000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60026115a18361192e565b6115ab919061243e565b60011461011f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757900000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b5f8061161f83611954565b90508084101561168b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6d7900000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b90920392915050565b5f62028cf56116b06116a861067887612451565b61022061196f565b6116ba9082612468565b90506116c86109a985612451565b6116d29082612468565b90506116e1816202a5ac6119a4565b90505f6116ef846058612451565b9050836116fd604087612451565b6117079190612451565b6117119082612468565b905061171d8183612468565b925050505b9392505050565b5f60208251611738919061243e565b1561179f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f707100000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b5f602083516117ae91906123fe565b905062010000811061181c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f707000000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b61182760028261243e565b600114611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f707300000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6002836040516118a0919061247b565b602060405180830381855afa1580156118bb573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906118de91906124a7565b60e09190911b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff91909116177f01000000000000000000000000000000000000000000000000000000000000001792915050565b5f8160031a82600261194491901a610100612451565b61194e9190612468565b92915050565b6127105f61196383600a612451565b905061172282826119a4565b5f821561199c57816119826001856124be565b61198c91906123fe565b611997906001612468565b611722565b5f9392505050565b5f8183116119b25781611722565b5090919050565b5f602082840312156119c9575f80fd5b813567ffffffffffffffff8111156119df575f80fd5b82016101808185031215611722575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611a24575f80fd5b83018035915067ffffffffffffffff821115611a3e575f80fd5b602001915036819003821315611a52575f80fd5b9250929050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a7c575f80fd5b919050565b5f60208284031215611a91575f80fd5b61172282611a59565b5f82357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda1833603018112611acc575f80fd5b9190910192915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b09575f80fd5b83018035915067ffffffffffffffff821115611b23575f80fd5b6020019150600581901b3603821315611a52575f80fd5b5f82357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda1833603018112611b6c575f80fd5b90910192915050565b60808183375050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611bb1575f80fd5b830160208101925035905067ffffffffffffffff811115611bd0575f80fd5b803603821315611a52575f80fd5b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611c58575f80fd5b830160208101925035905067ffffffffffffffff811115611c77575f80fd5b8060051b3603821315611a52575f80fd5b8183525f7f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611cb8575f80fd5b8260051b80836020870137939093016020019392505050565b5f610260823584526020830135602085015260408301356040850152606083013560608501526080830135608085015260a083013560a085015260c083013560c085015260e083013560e0850152610100808401358186015250610120808401358186015250610140611d48818601828601611b75565b506101c0611d5881850185611b7e565b8383880152611d6a8488018284611bde565b93505050506101e0611d7e81850185611b7e565b86840383880152611d90848284611bde565b9350505050610200611da481850185611c25565b86840383880152611db6848284611c88565b9350505050610220611dca81850185611b7e565b86840383880152611ddc848284611bde565b9350505050610240611df081850185611b7e565b86840383880152611e02848284611bde565b979650505050505050565b5f838385526020808601955060208560051b830101845f5b87811015611e7d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0858403018952611e5e8288611b7e565b611e69858284611bde565b9a86019a9450505090830190600101611e25565b5090979650505050505050565b602081525f611e998384611b3a565b610180806020850152611eb06101a0850183611cd1565b9150611ebf6020860186611c25565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080878603016040880152611ef5858385611e0d565b94506040880135606088015260608801356080880152611f1760808901611a59565b73ffffffffffffffffffffffffffffffffffffffff811660a08901529250611f5960c0880160a08a018035825260208082013590830152604090810135910152565b611f67610100890189611b7e565b93509150610120818887030181890152611f82868585611bde565b9550611f90818a018a611b7e565b9450925050610140818887030181890152611fac868585611bde565b90890135610160898101919091529098013593909601929092525093949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b63ffffffff82811682821603908082111561201a5761201a611fd0565b5092915050565b602081525f6117226020830184611cd1565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610200810167ffffffffffffffff8111828210171561208457612084612033565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156120d1576120d1612033565b604052919050565b5f82601f8301126120e8575f80fd5b6040516080810181811067ffffffffffffffff8211171561210b5761210b612033565b60405280608084018581111561211f575f80fd5b845b81811015612139578035835260209283019201612121565b509195945050505050565b5f82601f830112612153575f80fd5b813567ffffffffffffffff81111561216d5761216d612033565b61219e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161208a565b8181528460208386010111156121b2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126121dd575f80fd5b8135602067ffffffffffffffff8211156121f9576121f9612033565b8160051b61220882820161208a565b9283528481018201928281019087851115612221575f80fd5b83870192505b84831015611e0257823582529183019190830190612227565b5f6102608236031215612251575f80fd5b612259612060565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013581830152506101208084013581830152506101406122ca368286016120d9565b908201526101c08381013567ffffffffffffffff808211156122ea575f80fd5b6122f636838801612144565b6101608501526101e091508186013581811115612311575f80fd5b61231d36828901612144565b6101808601525061020086013581811115612336575f80fd5b612342368289016121ce565b6101a0860152506102208601358181111561235b575f80fd5b61236736828901612144565b8486015250610240860135925080831115612380575f80fd5b5061238d36838701612144565b908301525092915050565b8251815260208084015181830152604080850151818401528335606084015290830135608083015282013560a082015260c08101611722565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261240c5761240c6123d1565b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8261244c5761244c6123d1565b500690565b808202811582820484141761194e5761194e611fd0565b8082018082111561194e5761194e611fd0565b5f82515f5b8181101561249a5760208186018101518583015201612480565b505f920191825250919050565b5f602082840312156124b7575f80fd5b5051919050565b8181038181111561194e5761194e611fd056fea264697066735822122075d5aa800fd91682850cb533d5e685d165696f659df73fce08ce67d5b1bd44ed64736f6c63430008180033
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610029575f3560e01c806308284e571461002d575b5f80fd5b61004061003b3660046119b9565b610052565b60405190815260200160405180910390f35b5f61005c82610084565b507f33774e659306e47509050e97cb651e731180a42d458212294d30751925c551a292915050565b5f8161014001354210156100f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f55706772616465206973206e6f7420726561647920796574000000000000000060448201526064015b60405180910390fd5b5f806101098461016001356101cb565b909250905061012361011f6101008601866119f1565b5050565b61013f61013660a0860160808701611a81565b8560a0016105ba565b61015284604001358560600135836105cc565b61017361015f8580611a9a565b61016c6020870187611ad6565b85856105e5565b925061018661011f6101208601866119f1565b828461016001357f56405fee20a4cf3c21d1b23cbbedc0f54921b0347dc19a7641c80645f6916798866040516101bc9190611e8a565b60405180910390a35050919050565b6021545f908190808411610261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4e65772070726f746f636f6c2076657273696f6e206973206e6f74206772656160448201527f746572207468616e207468652063757272656e74206f6e65000000000000000060648201526084016100f0565b5f8061028e61026f8461086b565b63ffffffff604082901c169167ffffffffffffffff602083901c169190565b50915091508163ffffffff165f1461032a57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f496d706c656d656e746174696f6e20726571756972657320746861742074686560448201527f206d616a6f722076657273696f6e206973203020617420616c6c2074696d657360648201526084016100f0565b5f61033761026f8861086b565b509650905063ffffffff8116156103aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d616a6f72206d75737420616c7761797320626520300000000000000000000060448201526064016100f0565b5f6103b58388611ffd565b63ffffffff169050805f036103c957600195505b606481111561045a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f546f6f206269672070726f746f636f6c2076657273696f6e206469666665726560448201527f6e6365000000000000000000000000000000000000000000000000000000000060648201526084016100f0565b8561057f57602254156104ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f50726576696f7573207570677261646520686173206e6f74206265656e20666960448201527f6e616c697a65640000000000000000000000000000000000000000000000000060648201526084016100f0565b6023541561057f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f546865206261746368206e756d626572206f66207468652070726576696f757360448201527f207570677261646520686173206e6f74206265656e20636c65616e656400000060648201526084016100f0565b6021889055604051889086907f4235104f56661fe2e9d2f2a460b42766581bc45ce366c6a30a9f86c8a2b371a7905f90a35050505050915091565b6105c38261090c565b61011f816109a0565b6105d68382610a39565b6105e08282610b12565b505050565b5f853581036105f557505f610862565b8115610683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f5061746368206f6e6c7920757067726164652063616e206e6f7420736574207560448201527f706772616465207472616e73616374696f6e000000000000000000000000000060648201526084016100f0565b853560fe14610714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c322073797374656d207570677261646520747820747970652069732077726f60448201527f6e6700000000000000000000000000000000000000000000000000000000000060648201526084016100f0565b5f866040516020016107269190612021565b60405160208183030381529060405290506107698761074490612240565b601a546026548491906d0100000000000000000000000000900463ffffffff16610beb565b61077a61077588612240565b610d66565b8363ffffffff168761010001351461083a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f546865206e65772070726f746f636f6c2076657273696f6e2073686f756c642060448201527f626520696e636c7564656420696e20746865204c322073797374656d2075706760648201527f7261646520747800000000000000000000000000000000000000000000000000608482015260a4016100f0565b610852868661084d6102008b018b611ad6565b61132d565b8051602090910120602281905590505b95945050505050565b5f6bffffffffffffffffffffffff821115610908576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016100f0565b5090565b73ffffffffffffffffffffffffffffffffffffffff811661092a5750565b600a805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2ff4895c300d6993c27f2bb507b4b59d29464dc640af727383451365631ba8b2905f90a35050565b80351580156109b157506020810135155b80156109bf57506040810135155b156109c75750565b604080516060810182526014805482526015805460208085019190915260168054858701528635909355850135905583830135905590517f4c055dbc5f14dcb6e081c9421d9657d950dcd6372f6db0a714b9135171cbc15d90610a2d9083908590612398565b60405180910390a15050565b81610a42575050565b8015610ad0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5061746368206f6e6c7920757067726164652063616e206e6f7420736574206e60448201527f657720626f6f746c6f616465720000000000000000000000000000000000000060648201526084016100f0565b610ad9826114f5565b6017805490839055604051839082907f271b33af94e3f065ecd8659833e6b1daf851f063700c36ddefefab35d4ce4746905f90a3505050565b81610b1b575050565b8015610ba9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f5061746368206f6e6c7920757067726164652063616e206e6f7420736574206e60448201527f65772064656661756c74206163636f756e74000000000000000000000000000060648201526084016100f0565b610bb2826114f5565b6018805490839055604051839082907f36df93a47cc02081d9d8208022ab736fdf98fac566e5fc6f5762bf7666e521f3905f90a3505050565b5f610bfb85606001518551611614565b905082811115610c67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756900000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b81856080015182610c7891906123fe565b1115610ce0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756b00000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b80610cf78551876101a00151518860800151611694565b1115610d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757000000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b5050505050565b602081015161ffff1015610dd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756100000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b604081015173ffffffffffffffffffffffffffffffffffffffff1015610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756200000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60e081015115610ec4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756300000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b61012081015115610f31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756400000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60a081015115610f9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757100000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60c081015115611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757800000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101408101515115611077576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756500000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101408101516020015173ffffffffffffffffffffffffffffffffffffffff10156110fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756600000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b610140810151604001511561116f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756700000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b61014081015160600151156111e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756f00000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b610180810151511561124e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756800000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101c081015151156112bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f756c31000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6101e0810151511561132a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f756d00000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b50565b828114611396576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f57726f6e67206e756d626572206f6620666163746f727920646570730000000060448201526064016100f0565b6020831115611401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f466163746f727920646570732063616e206265206174206d6f7374203332000060448201526064016100f0565b5f5b83811015610d5f5782828281811061141d5761141d612411565b905060200201355f1b61148686868481811061143b5761143b612411565b905060200281019061144d91906119f1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061172992505050565b146114ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f57726f6e6720666163746f72792064657020686173680000000000000000000060448201526064016100f0565b600101611403565b5f81901a60018114801561153057507fff00000000000000000000000000000000000000000000000000000000000000600183901a60f81b16155b611596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f7a6600000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b60026115a18361192e565b6115ab919061243e565b60011461011f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f757900000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b5f8061161f83611954565b90508084101561168b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f6d7900000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b90920392915050565b5f62028cf56116b06116a861067887612451565b61022061196f565b6116ba9082612468565b90506116c86109a985612451565b6116d29082612468565b90506116e1816202a5ac6119a4565b90505f6116ef846058612451565b9050836116fd604087612451565b6117079190612451565b6117119082612468565b905061171d8183612468565b925050505b9392505050565b5f60208251611738919061243e565b1561179f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f707100000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b5f602083516117ae91906123fe565b905062010000811061181c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f707000000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b61182760028261243e565b600114611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f707300000000000000000000000000000000000000000000000000000000000060448201526064016100f0565b6002836040516118a0919061247b565b602060405180830381855afa1580156118bb573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906118de91906124a7565b60e09190911b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff91909116177f01000000000000000000000000000000000000000000000000000000000000001792915050565b5f8160031a82600261194491901a610100612451565b61194e9190612468565b92915050565b6127105f61196383600a612451565b905061172282826119a4565b5f821561199c57816119826001856124be565b61198c91906123fe565b611997906001612468565b611722565b5f9392505050565b5f8183116119b25781611722565b5090919050565b5f602082840312156119c9575f80fd5b813567ffffffffffffffff8111156119df575f80fd5b82016101808185031215611722575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611a24575f80fd5b83018035915067ffffffffffffffff821115611a3e575f80fd5b602001915036819003821315611a52575f80fd5b9250929050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a7c575f80fd5b919050565b5f60208284031215611a91575f80fd5b61172282611a59565b5f82357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda1833603018112611acc575f80fd5b9190910192915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b09575f80fd5b83018035915067ffffffffffffffff821115611b23575f80fd5b6020019150600581901b3603821315611a52575f80fd5b5f82357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda1833603018112611b6c575f80fd5b90910192915050565b60808183375050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611bb1575f80fd5b830160208101925035905067ffffffffffffffff811115611bd0575f80fd5b803603821315611a52575f80fd5b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611c58575f80fd5b830160208101925035905067ffffffffffffffff811115611c77575f80fd5b8060051b3603821315611a52575f80fd5b8183525f7f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611cb8575f80fd5b8260051b80836020870137939093016020019392505050565b5f610260823584526020830135602085015260408301356040850152606083013560608501526080830135608085015260a083013560a085015260c083013560c085015260e083013560e0850152610100808401358186015250610120808401358186015250610140611d48818601828601611b75565b506101c0611d5881850185611b7e565b8383880152611d6a8488018284611bde565b93505050506101e0611d7e81850185611b7e565b86840383880152611d90848284611bde565b9350505050610200611da481850185611c25565b86840383880152611db6848284611c88565b9350505050610220611dca81850185611b7e565b86840383880152611ddc848284611bde565b9350505050610240611df081850185611b7e565b86840383880152611e02848284611bde565b979650505050505050565b5f838385526020808601955060208560051b830101845f5b87811015611e7d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0858403018952611e5e8288611b7e565b611e69858284611bde565b9a86019a9450505090830190600101611e25565b5090979650505050505050565b602081525f611e998384611b3a565b610180806020850152611eb06101a0850183611cd1565b9150611ebf6020860186611c25565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080878603016040880152611ef5858385611e0d565b94506040880135606088015260608801356080880152611f1760808901611a59565b73ffffffffffffffffffffffffffffffffffffffff811660a08901529250611f5960c0880160a08a018035825260208082013590830152604090810135910152565b611f67610100890189611b7e565b93509150610120818887030181890152611f82868585611bde565b9550611f90818a018a611b7e565b9450925050610140818887030181890152611fac868585611bde565b90890135610160898101919091529098013593909601929092525093949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b63ffffffff82811682821603908082111561201a5761201a611fd0565b5092915050565b602081525f6117226020830184611cd1565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610200810167ffffffffffffffff8111828210171561208457612084612033565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156120d1576120d1612033565b604052919050565b5f82601f8301126120e8575f80fd5b6040516080810181811067ffffffffffffffff8211171561210b5761210b612033565b60405280608084018581111561211f575f80fd5b845b81811015612139578035835260209283019201612121565b509195945050505050565b5f82601f830112612153575f80fd5b813567ffffffffffffffff81111561216d5761216d612033565b61219e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161208a565b8181528460208386010111156121b2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f82601f8301126121dd575f80fd5b8135602067ffffffffffffffff8211156121f9576121f9612033565b8160051b61220882820161208a565b9283528481018201928281019087851115612221575f80fd5b83870192505b84831015611e0257823582529183019190830190612227565b5f6102608236031215612251575f80fd5b612259612060565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013581830152506101208084013581830152506101406122ca368286016120d9565b908201526101c08381013567ffffffffffffffff808211156122ea575f80fd5b6122f636838801612144565b6101608501526101e091508186013581811115612311575f80fd5b61231d36828901612144565b6101808601525061020086013581811115612336575f80fd5b612342368289016121ce565b6101a0860152506102208601358181111561235b575f80fd5b61236736828901612144565b8486015250610240860135925080831115612380575f80fd5b5061238d36838701612144565b908301525092915050565b8251815260208084015181830152604080850151818401528335606084015290830135608083015282013560a082015260c08101611722565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261240c5761240c6123d1565b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8261244c5761244c6123d1565b500690565b808202811582820484141761194e5761194e611fd0565b8082018082111561194e5761194e611fd0565b5f82515f5b8181101561249a5760208186018101518583015201612480565b505f920191825250919050565b5f602082840312156124b7575f80fd5b5051919050565b8181038181111561194e5761194e611fd056fea264697066735822122075d5aa800fd91682850cb533d5e685d165696f659df73fce08ce67d5b1bd44ed64736f6c63430008180033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.