RWAL

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "@openzeppelin/contracts/interfaces/IERC5313.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC5313.sol)

pragma solidity >=0.4.16;

/**
 * @dev Interface for the Light Contract Ownership Standard.
 *
 * A standardized minimal interface required to identify an account that controls a contract
 */
interface IERC5313 {
    /**
     * @dev Gets the address of the owner.
     */
    function owner() external view returns (address);
}
"
    },
    "contracts/RWALToken.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {IGetCCIPAdmin} from "mock/src/v0.8/ccip/interfaces/IGetCCIPAdmin.sol";
import {IBurnMintERC20Upgradeable} from "mock/src/v0.8/shared/token/ERC20/upgradeable/IBurnMintERC20Upgradeable.sol";

import {AccessControlDefaultAdminRulesUpgradeable} from "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/access/extensions/AccessControlDefaultAdminRulesUpgradeable.sol";
import {Initializable} from "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/proxy/utils/Initializable.sol";
import {UUPSUpgradeable} from "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/proxy/utils/UUPSUpgradeable.sol";
import {ERC20Upgradeable} from "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/token/ERC20/ERC20Upgradeable.sol";
import {PausableUpgradeable} from "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/utils/PausableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/utils/ReentrancyGuardUpgradeable.sol";
import {IAccessControl} from "mock/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/access/IAccessControl.sol";
import {IERC20} from "mock/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC20.sol";
import {IERC165} from "mock/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol";
import {SafeERC20} from "mock/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/utils/SafeERC20.sol";

/// @title RWAL - Lendr Governance & Utility Token
/// @notice 1 billion fixed supply governance token with Chainlink CCT bridging
/// @dev Implements ERC20Votes for governance, CCT for cross-chain bridging
contract RWAL is
    Initializable,
    UUPSUpgradeable,
    ERC20Upgradeable,
    IBurnMintERC20Upgradeable,
    IGetCCIPAdmin,
    IERC165,
    PausableUpgradeable,
    ReentrancyGuardUpgradeable,
    AccessControlDefaultAdminRulesUpgradeable
{

    using SafeERC20 for IERC20;

    // ================================================================
    // │                           CONSTANTS                          │
    // ================================================================

    /// @dev Maximum supply of RWAL tokens (1 billion tokens with 18 decimals)
    uint256 public constant MAX_SUPPLY = 1_000_000_000e18;

    // ================================================================
    // │                            ROLES                             │
    // ================================================================
    bool public launchPhaseActive;
    mapping(address => bool) public launchPhaseWhitelist;
    bytes32 public constant LAUNCH_MANAGER_ROLE =
        keccak256("LAUNCH_MANAGER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
    bytes32 public constant BRIDGE_ROLE = keccak256("BRIDGE_ROLE");
    bytes32 public constant EMERGENCY_ROLE = keccak256("EMERGENCY_ROLE");
    bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");

    // ================================================================
    // │                           ERRORS                             │
    // ================================================================

    error RWAL__MaxSupplyExceeded(uint256 supplyAfterMint);
    error RWAL__InvalidRecipient(address recipient);
    error RWAL__ZeroAmount();
    error RWAL__ZeroAddress();
    error RWAL__InvalidUpgrade();
    error RWAL__LaunchPhaseInactive();
    error RWAL__NotWhitelisted();
    error RWAL__AlreadyDeactivated();
    error RWAL__ArrayLengthMismatch();
    error RWAL__InvalidDecimals();

    // ================================================================
    // │                           EVENTS                             │
    // ================================================================

    event LaunchPhaseActivated();
    event LaunchPhaseDeactivated();
    event CCIPAdminTransferred(
        address indexed previousAdmin,
        address indexed newAdmin
    );
    event EmergencyWithdraw(
        address indexed token,
        address indexed to,
        uint256 amount
    );
    event UpgradeAuthorized(
        address indexed newImplementation,
        address indexed authorizer
    );
    event LaunchPhaseWhitelistUpdated(
        address indexed account,
        bool whitelisted
    );

    // ================================================================
    // │                        STATE VARIABLES                       │
    // ================================================================

    /// @dev The number of decimals for the token
    uint8 internal i_decimals;

    /// @dev The CCIP Admin address
    address internal s_ccipAdmin;

    // Storage gap for future upgrades
    uint256[49] private __gap;

    // ================================================================
    // │                         CONSTRUCTOR                          │
    // ================================================================

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        // Disable initializers to prevent implementation contract initialization
        _disableInitializers();
    }

    // ================================================================
    // │                        INITIALIZATION                        │
    // ================================================================

    /// @dev Initialize the contract (for proxy deployment)
    function initialize(
        string memory name,
        string memory symbol,
        address admin,
        uint256 preMint,
        uint8 decimals_,
        bool _launchPhaseActive
    ) public initializer {
        if (admin == address(0)) revert RWAL__ZeroAddress();
        if (preMint > MAX_SUPPLY) revert RWAL__MaxSupplyExceeded(preMint);
        if (decimals_ != 18) revert RWAL__InvalidDecimals(); 

        // FIXED: Call initializers in the correct linearized order
        __ERC20_init(name, symbol);
        __Pausable_init();
        __ReentrancyGuard_init();
        __AccessControlDefaultAdminRules_init(0, admin);
        __UUPSUpgradeable_init();


        s_ccipAdmin = admin;
        i_decimals = decimals_;
        // Grant initial roles
        _grantRole(MINTER_ROLE, admin);
        _grantRole(BURNER_ROLE, admin);
        _grantRole(UPGRADER_ROLE, admin);
        _grantRole(BRIDGE_ROLE, admin);
        _grantRole(ADMIN_ROLE, admin);
        _grantRole(EMERGENCY_ROLE, admin);

        // LAUNCH PHASE INIT
        launchPhaseActive = _launchPhaseActive;
        _grantRole(LAUNCH_MANAGER_ROLE, admin);
        if (_launchPhaseActive) {
            launchPhaseWhitelist[admin] = true;
            emit LaunchPhaseWhitelistUpdated(admin, true);
            emit LaunchPhaseActivated();
        }

        // Pre-mint initial supply if specified
        if (preMint > 0) {
            _mint(admin, preMint);
        }
    }

    // ================================================================
    // │                         MODIFIERS                            │
    // ================================================================

    modifier nonZeroAmount(uint256 amount) {
        if (amount == 0) revert RWAL__ZeroAmount();
        _;
    }

    // ================================================================
    // |                    LAUNCH-PHASE MANAGEMENT                   |
    // ================================================================

    function setLaunchPhaseWhitelist(
        address account,
        bool whitelisted
    ) external onlyRole(LAUNCH_MANAGER_ROLE) {
        if (!launchPhaseActive) revert RWAL__LaunchPhaseInactive();
        if (account == address(0)) revert RWAL__ZeroAddress();
        launchPhaseWhitelist[account] = whitelisted;
        emit LaunchPhaseWhitelistUpdated(account, whitelisted);
    }

    /// @notice Batch add or remove addresses to the launch-phase whitelist
         function batchSetLaunchPhaseWhitelist(
         address[] calldata accounts,
         bool[] calldata whitelisted
     ) external onlyRole(LAUNCH_MANAGER_ROLE) {
         if (!launchPhaseActive) revert RWAL__LaunchPhaseInactive();
         uint256 len = accounts.length;
         if (len != whitelisted.length) revert RWAL__ArrayLengthMismatch(); 
         if (len == 0) revert RWAL__ZeroAmount();
         
         for (uint256 i; i < len; ) {
             address account = accounts[i];
             if (account == address(0)) revert RWAL__ZeroAddress();
             launchPhaseWhitelist[account] = whitelisted[i];
             emit LaunchPhaseWhitelistUpdated(account, whitelisted[i]);
             unchecked { ++i; }
         }
     }


    function deactivateLaunchPhase() external onlyRole(LAUNCH_MANAGER_ROLE) {
        if (!launchPhaseActive) revert RWAL__AlreadyDeactivated();
        launchPhaseActive = false;
        emit LaunchPhaseDeactivated();
    }

    // ================================================================
    // │                         ERC20 CORE                           │
    // ================================================================

    /// @inheritdoc IERC165
    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        virtual
        override(AccessControlDefaultAdminRulesUpgradeable, IERC165)
        returns (bool)
    {
        return
            interfaceId == type(IERC20).interfaceId ||
            interfaceId == type(IBurnMintERC20Upgradeable).interfaceId ||
            interfaceId == type(IERC165).interfaceId ||
            interfaceId == type(IAccessControl).interfaceId ||
            interfaceId == type(IGetCCIPAdmin).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /// @dev Returns the number of decimals used in its user representation
    function decimals() public view virtual override returns (uint8) {
        return i_decimals;
    }

    /// @dev Returns the max supply of the token
    function maxSupply() public pure virtual returns (uint256) {
        return MAX_SUPPLY;
    }

    // ================================================================
    // │                      BURNING & MINTING                       │
    // ================================================================

    /// @inheritdoc IBurnMintERC20Upgradeable
    /// @dev Burns tokens from the caller's account (for CCT bridging)
    function burn(
        uint256 amount
    ) public virtual onlyRole(BURNER_ROLE) nonZeroAmount(amount) {
        _burn(msg.sender, amount);
    }

    /// @inheritdoc IBurnMintERC20Upgradeable
    /// @dev Burns tokens from specified account (for CCT bridging)
    function burn(
        address account,
        uint256 amount
    ) public virtual onlyRole(BURNER_ROLE) nonZeroAmount(amount) {
        if (account == address(0)) revert RWAL__ZeroAddress();

        // Check if caller has allowance (unless it's the account owner)
        if (account != msg.sender) {
            _spendAllowance(account, msg.sender, amount);
            _burn(account, amount);
            _approve(account, msg.sender, 0); // LEN-5: clear unlimited approvals
        } else {
            _burn(account, amount);
        }
    }

    /// @inheritdoc IBurnMintERC20Upgradeable
    /// @dev Burns tokens from specified account with allowance check
    function burnFrom(
        address account,
        uint256 amount
    ) public virtual onlyRole(BURNER_ROLE) nonZeroAmount(amount) {
        if (account == address(0)) revert RWAL__ZeroAddress();

        _spendAllowance(account, msg.sender, amount);
        _burn(account, amount);
        _approve(account, msg.sender, 0); // LEN-5: clear unlimited approvals
    }

    /// @inheritdoc IBurnMintERC20Upgradeable
    /// @dev Mints new tokens to specified account (for CCT bridging)
    function mint(
        address account,
        uint256 amount
    ) external onlyRole(MINTER_ROLE) nonZeroAmount(amount) {
        if (account == address(0) || account == address(this)) {
            revert RWAL__InvalidRecipient(account);
        }
        if (totalSupply() + amount > MAX_SUPPLY) {
            revert RWAL__MaxSupplyExceeded(totalSupply() + amount);
        }

        _mint(account, amount);
    }

    // ================================================================
    // │                     EMERGENCY CONTROLS                       │
    // ================================================================

    /// @notice Pauses all token transfers
    function pause() external onlyRole(EMERGENCY_ROLE) {
        _pause();
    }

    /// @notice Unpauses all token transfers
    function unpause() external onlyRole(EMERGENCY_ROLE) {
        _unpause();
    }

    /// @notice Emergency withdrawal of any ERC20 token (except RWAL itself)
    /// @dev SECURITY: This function is controlled by multi-signature wallet
    /// @dev Multi-sig inherently prevents reentrancy through approval process
    /// @param token The token address to withdraw
    /// @param to The recipient address
    /// @param amount The amount to withdraw
    function emergencyWithdraw(
        address token,
        address to,
        uint256 amount
    ) external onlyRole(EMERGENCY_ROLE) nonZeroAmount(amount) nonReentrant { // LEN-2
        if (to == address(0)) revert RWAL__ZeroAddress();
        if (token == address(this)) revert RWAL__InvalidRecipient(token);

        IERC20(token).safeTransfer(to, amount); // LEN-2
        emit EmergencyWithdraw(token, to, amount);
    }

    // ================================================================
    // │                         ROLE MANAGEMENT                      │
    // ================================================================

    /// @notice Grants both mint and burn roles to an address
    function grantMintAndBurnRoles(
        address burnAndMinter
    ) external onlyRole(ADMIN_ROLE) {
        if (burnAndMinter == address(0)) revert RWAL__ZeroAddress();
        grantRole(MINTER_ROLE, burnAndMinter);
        grantRole(BURNER_ROLE, burnAndMinter);
    }

    /// @notice Returns the current CCIP Admin
    function getCCIPAdmin() external view returns (address) {
        return s_ccipAdmin;
    }

    /// @notice Transfers the CCIP Admin role to a new address
    function setCCIPAdmin(address newAdmin) external onlyRole(ADMIN_ROLE) {
        if (newAdmin == address(0)) revert RWAL__ZeroAddress();
        address currentAdmin = s_ccipAdmin;
        s_ccipAdmin = newAdmin;
        emit CCIPAdminTransferred(currentAdmin, newAdmin);
    }

    // ================================================================
    // │                        UUPS UPGRADE                          │
    // ================================================================

    /// @dev Authorize upgrade (only UPGRADER_ROLE can upgrade)
    function _authorizeUpgrade(
        address newImplementation
    ) internal override onlyRole(UPGRADER_ROLE) {
        if (newImplementation == address(0)) revert RWAL__ZeroAddress();
        if (newImplementation == address(this)) revert RWAL__InvalidUpgrade();

        emit UpgradeAuthorized(newImplementation, msg.sender);
    }

    // ================================================================
    // |            TRANSFER RESTRICTIONS OVERRIDE                    |
    // ================================================================

    /// @dev Override _update to handle pause and whitelist restrictions
    function _update(
        address from,
        address to,
        uint256 value
    ) internal virtual override {
        // Enforce Pausable — OZ doesn't do this in ERC20Upgradeable
        _requireNotPaused();

        // Prevent transfers to the token contract itself
        if (to == address(this)) revert RWAL__InvalidRecipient(to);

        // First apply launch phase restrictions (before calling super)
        if (from != address(0) && to != address(0) && launchPhaseActive) {
            if (!launchPhaseWhitelist[from] || !launchPhaseWhitelist[to]) {
                revert RWAL__NotWhitelisted();
            }
        }

        // Call parent _update (handles pause via whenNotPaused modifier)
        super._update(from, to, value);
    }
}
"
    },
    "mock/src/v0.8/ccip/interfaces/IGetCCIPAdmin.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IGetCCIPAdmin {
  /// @notice Returns the admin of the token.
  /// @dev This method is named to never conflict with existing methods.
  function getCCIPAdmin() external view returns (address);
}
"
    },
    "mock/src/v0.8/shared/token/ERC20/upgradeable/IBurnMintERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC20} from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol";

interface IBurnMintERC20Upgradeable is IERC20 {
  /// @notice Mints new tokens for a given address.
  /// @param account The address to mint the new tokens to.
  /// @param amount The number of tokens to be minted.
  /// @dev this function increases the total supply.
  function mint(address account, uint256 amount) external;

  /// @notice Burns tokens from the sender.
  /// @param amount The number of tokens to be burned.
  /// @dev this function decreases the total supply.
  function burn(uint256 amount) external;

  /// @notice Burns tokens from a given address..
  /// @param account The address to burn tokens from.
  /// @param amount The number of tokens to be burned.
  /// @dev this function decreases the total supply.
  function burn(address account, uint256 amount) external;

  /// @notice Burns tokens from a given address..
  /// @param account The address to burn tokens from.
  /// @param amount The number of tokens to be burned.
  /// @dev this function decreases the total supply.
  function burnFrom(address account, uint256 amount) external;
}
"
    },
    "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/access/AccessControlUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)

pragma solidity ^0.8.20;

import {IAccessControl} from "../../../../openzeppelin-solidity/v5.0.2/contracts/access/IAccessControl.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```solidity
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```solidity
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
 * to enforce additional security measures for this role.
 */
abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {
  struct RoleData {
    mapping(address account => bool) hasRole;
    bytes32 adminRole;
  }

  bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

  /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl
  struct AccessControlStorage {
    mapping(bytes32 role => RoleData) _roles;
  }

  // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControl")) - 1)) & ~bytes32(uint256(0xff))
  bytes32 private constant AccessControlStorageLocation =
    0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;

  function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {
    assembly {
      $.slot := AccessControlStorageLocation
    }
  }

  /**
   * @dev Modifier that checks that an account has a specific role. Reverts
   * with an {AccessControlUnauthorizedAccount} error including the required role.
   */
  modifier onlyRole(
    bytes32 role
  ) {
    _checkRole(role);
    _;
  }

  function __AccessControl_init() internal onlyInitializing {}

  function __AccessControl_init_unchained() internal onlyInitializing {}
  /**
   * @dev See {IERC165-supportsInterface}.
   */

  function supportsInterface(
    bytes4 interfaceId
  ) public view virtual override returns (bool) {
    return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
  }

  /**
   * @dev Returns `true` if `account` has been granted `role`.
   */
  function hasRole(bytes32 role, address account) public view virtual returns (bool) {
    AccessControlStorage storage $ = _getAccessControlStorage();
    return $._roles[role].hasRole[account];
  }

  /**
   * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
   * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
   */
  function _checkRole(
    bytes32 role
  ) internal view virtual {
    _checkRole(role, _msgSender());
  }

  /**
   * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
   * is missing `role`.
   */
  function _checkRole(bytes32 role, address account) internal view virtual {
    if (!hasRole(role, account)) {
      revert AccessControlUnauthorizedAccount(account, role);
    }
  }

  /**
   * @dev Returns the admin role that controls `role`. See {grantRole} and
   * {revokeRole}.
   *
   * To change a role's admin, use {_setRoleAdmin}.
   */
  function getRoleAdmin(
    bytes32 role
  ) public view virtual returns (bytes32) {
    AccessControlStorage storage $ = _getAccessControlStorage();
    return $._roles[role].adminRole;
  }

  /**
   * @dev Grants `role` to `account`.
   *
   * If `account` had not been already granted `role`, emits a {RoleGranted}
   * event.
   *
   * Requirements:
   *
   * - the caller must have ``role``'s admin role.
   *
   * May emit a {RoleGranted} event.
   */
  function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
    _grantRole(role, account);
  }

  /**
   * @dev Revokes `role` from `account`.
   *
   * If `account` had been granted `role`, emits a {RoleRevoked} event.
   *
   * Requirements:
   *
   * - the caller must have ``role``'s admin role.
   *
   * May emit a {RoleRevoked} event.
   */
  function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
    _revokeRole(role, account);
  }

  /**
   * @dev Revokes `role` from the calling account.
   *
   * Roles are often managed via {grantRole} and {revokeRole}: this function's
   * purpose is to provide a mechanism for accounts to lose their privileges
   * if they are compromised (such as when a trusted device is misplaced).
   *
   * If the calling account had been revoked `role`, emits a {RoleRevoked}
   * event.
   *
   * Requirements:
   *
   * - the caller must be `callerConfirmation`.
   *
   * May emit a {RoleRevoked} event.
   */
  function renounceRole(bytes32 role, address callerConfirmation) public virtual {
    if (callerConfirmation != _msgSender()) {
      revert AccessControlBadConfirmation();
    }

    _revokeRole(role, callerConfirmation);
  }

  /**
   * @dev Sets `adminRole` as ``role``'s admin role.
   *
   * Emits a {RoleAdminChanged} event.
   */
  function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
    AccessControlStorage storage $ = _getAccessControlStorage();
    bytes32 previousAdminRole = getRoleAdmin(role);
    $._roles[role].adminRole = adminRole;
    emit RoleAdminChanged(role, previousAdminRole, adminRole);
  }

  /**
   * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
   *
   * Internal function without access restriction.
   *
   * May emit a {RoleGranted} event.
   */
  function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
    AccessControlStorage storage $ = _getAccessControlStorage();
    if (!hasRole(role, account)) {
      $._roles[role].hasRole[account] = true;
      emit RoleGranted(role, account, _msgSender());
      return true;
    } else {
      return false;
    }
  }

  /**
   * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
   *
   * Internal function without access restriction.
   *
   * May emit a {RoleRevoked} event.
   */
  function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
    AccessControlStorage storage $ = _getAccessControlStorage();
    if (hasRole(role, account)) {
      $._roles[role].hasRole[account] = false;
      emit RoleRevoked(role, account, _msgSender());
      return true;
    } else {
      return false;
    }
  }
}
"
    },
    "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/access/extensions/AccessControlDefaultAdminRulesUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlDefaultAdminRules.sol)

pragma solidity ^0.8.20;

import {IAccessControl} from "../../../../../openzeppelin-solidity/v5.0.2/contracts/access/IAccessControl.sol";
import {IAccessControlDefaultAdminRules} from
  "../../../../../openzeppelin-solidity/v5.0.2/contracts/access/extensions/IAccessControlDefaultAdminRules.sol";

import {Math} from "../../../../../openzeppelin-solidity/v5.0.2/contracts/utils/math/Math.sol";
import {SafeCast} from "../../../../../openzeppelin-solidity/v5.0.2/contracts/utils/math/SafeCast.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
import {AccessControlUpgradeable} from "../AccessControlUpgradeable.sol";
import {IERC5313} from "@openzeppelin/contracts/interfaces/IERC5313.sol";

/**
 * @dev Extension of {AccessControl} that allows specifying special rules to manage
 * the `DEFAULT_ADMIN_ROLE` holder, which is a sensitive role with special permissions
 * over other roles that may potentially have privileged rights in the system.
 *
 * If a specific role doesn't have an admin role assigned, the holder of the
 * `DEFAULT_ADMIN_ROLE` will have the ability to grant it and revoke it.
 *
 * This contract implements the following risk mitigations on top of {AccessControl}:
 *
 * * Only one account holds the `DEFAULT_ADMIN_ROLE` since deployment until it's potentially renounced.
 * * Enforces a 2-step process to transfer the `DEFAULT_ADMIN_ROLE` to another account.
 * * Enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted.
 * * The delay can be changed by scheduling, see {changeDefaultAdminDelay}.
 * * It is not possible to use another role to manage the `DEFAULT_ADMIN_ROLE`.
 *
 * Example usage:
 *
 * ```solidity
 * contract MyToken is AccessControlDefaultAdminRules {
 *   constructor() AccessControlDefaultAdminRules(
 *     3 days,
 *     msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder
 *    ) {}
 * }
 * ```
 */
abstract contract AccessControlDefaultAdminRulesUpgradeable is
  Initializable,
  IAccessControlDefaultAdminRules,
  IERC5313,
  AccessControlUpgradeable
{
  /// @custom:storage-location erc7201:openzeppelin.storage.AccessControlDefaultAdminRules
  struct AccessControlDefaultAdminRulesStorage {
    // pending admin pair read/written together frequently
    address _pendingDefaultAdmin;
    uint48 _pendingDefaultAdminSchedule; // 0 == unset
    uint48 _currentDelay;
    address _currentDefaultAdmin;
    // pending delay pair read/written together frequently
    uint48 _pendingDelay;
    uint48 _pendingDelaySchedule; // 0 == unset
  }

  // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControlDefaultAdminRules")) - 1)) & ~bytes32(uint256(0xff))
  bytes32 private constant AccessControlDefaultAdminRulesStorageLocation =
    0xeef3dac4538c82c8ace4063ab0acd2d15cdb5883aa1dff7c2673abb3d8698400;

  function _getAccessControlDefaultAdminRulesStorage()
    private
    pure
    returns (AccessControlDefaultAdminRulesStorage storage $)
  {
    assembly {
      $.slot := AccessControlDefaultAdminRulesStorageLocation
    }
  }

  /**
   * @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address.
   */
  function __AccessControlDefaultAdminRules_init(
    uint48 initialDelay,
    address initialDefaultAdmin
  ) internal onlyInitializing {
    __AccessControlDefaultAdminRules_init_unchained(initialDelay, initialDefaultAdmin);
  }

  function __AccessControlDefaultAdminRules_init_unchained(
    uint48 initialDelay,
    address initialDefaultAdmin
  ) internal onlyInitializing {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    if (initialDefaultAdmin == address(0)) {
      revert AccessControlInvalidDefaultAdmin(address(0));
    }
    $._currentDelay = initialDelay;
    _grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin);
  }

  /**
   * @dev See {IERC165-supportsInterface}.
   */
  function supportsInterface(
    bytes4 interfaceId
  ) public view virtual override returns (bool) {
    return interfaceId == type(IAccessControlDefaultAdminRules).interfaceId || super.supportsInterface(interfaceId);
  }

  /**
   * @dev See {IERC5313-owner}.
   */
  function owner() public view virtual returns (address) {
    return defaultAdmin();
  }

  ///
  /// Override AccessControl role management
  ///

  /**
   * @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`.
   */
  function grantRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) {
    if (role == DEFAULT_ADMIN_ROLE) {
      revert AccessControlEnforcedDefaultAdminRules();
    }
    super.grantRole(role, account);
  }

  /**
   * @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`.
   */
  function revokeRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) {
    if (role == DEFAULT_ADMIN_ROLE) {
      revert AccessControlEnforcedDefaultAdminRules();
    }
    super.revokeRole(role, account);
  }

  /**
   * @dev See {AccessControl-renounceRole}.
   *
   * For the `DEFAULT_ADMIN_ROLE`, it only allows renouncing in two steps by first calling
   * {beginDefaultAdminTransfer} to the `address(0)`, so it's required that the {pendingDefaultAdmin} schedule
   * has also passed when calling this function.
   *
   * After its execution, it will not be possible to call `onlyRole(DEFAULT_ADMIN_ROLE)` functions.
   *
   * NOTE: Renouncing `DEFAULT_ADMIN_ROLE` will leave the contract without a {defaultAdmin},
   * thereby disabling any functionality that is only available for it, and the possibility of reassigning a
   * non-administrated role.
   */
  function renounceRole(
    bytes32 role,
    address account
  ) public virtual override(AccessControlUpgradeable, IAccessControl) {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {
      (address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin();
      if (newDefaultAdmin != address(0) || !_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {
        revert AccessControlEnforcedDefaultAdminDelay(schedule);
      }
      delete $._pendingDefaultAdminSchedule;
    }
    super.renounceRole(role, account);
  }

  /**
   * @dev See {AccessControl-_grantRole}.
   *
   * For `DEFAULT_ADMIN_ROLE`, it only allows granting if there isn't already a {defaultAdmin} or if the
   * role has been previously renounced.
   *
   * NOTE: Exposing this function through another mechanism may make the `DEFAULT_ADMIN_ROLE`
   * assignable again. Make sure to guarantee this is the expected behavior in your implementation.
   */
  function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    if (role == DEFAULT_ADMIN_ROLE) {
      if (defaultAdmin() != address(0)) {
        revert AccessControlEnforcedDefaultAdminRules();
      }
      $._currentDefaultAdmin = account;
    }
    return super._grantRole(role, account);
  }

  /**
   * @dev See {AccessControl-_revokeRole}.
   */
  function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {
      delete $._currentDefaultAdmin;
    }
    return super._revokeRole(role, account);
  }

  /**
   * @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`.
   */
  function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override {
    if (role == DEFAULT_ADMIN_ROLE) {
      revert AccessControlEnforcedDefaultAdminRules();
    }
    super._setRoleAdmin(role, adminRole);
  }

  ///
  /// AccessControlDefaultAdminRules accessors
  ///

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function defaultAdmin() public view virtual returns (address) {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    return $._currentDefaultAdmin;
  }

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule) {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    return ($._pendingDefaultAdmin, $._pendingDefaultAdminSchedule);
  }

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function defaultAdminDelay() public view virtual returns (uint48) {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    uint48 schedule = $._pendingDelaySchedule;
    return (_isScheduleSet(schedule) && _hasSchedulePassed(schedule)) ? $._pendingDelay : $._currentDelay;
  }

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule) {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    schedule = $._pendingDelaySchedule;
    return (_isScheduleSet(schedule) && !_hasSchedulePassed(schedule)) ? ($._pendingDelay, schedule) : (0, 0);
  }

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function defaultAdminDelayIncreaseWait() public view virtual returns (uint48) {
    return 5 days;
  }

  ///
  /// AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin
  ///

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function beginDefaultAdminTransfer(
    address newAdmin
  ) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
    _beginDefaultAdminTransfer(newAdmin);
  }

  /**
   * @dev See {beginDefaultAdminTransfer}.
   *
   * Internal function without access restriction.
   */
  function _beginDefaultAdminTransfer(
    address newAdmin
  ) internal virtual {
    uint48 newSchedule = SafeCast.toUint48(block.timestamp) + defaultAdminDelay();
    _setPendingDefaultAdmin(newAdmin, newSchedule);
    emit DefaultAdminTransferScheduled(newAdmin, newSchedule);
  }

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
    _cancelDefaultAdminTransfer();
  }

  /**
   * @dev See {cancelDefaultAdminTransfer}.
   *
   * Internal function without access restriction.
   */
  function _cancelDefaultAdminTransfer() internal virtual {
    _setPendingDefaultAdmin(address(0), 0);
  }

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function acceptDefaultAdminTransfer() public virtual {
    (address newDefaultAdmin,) = pendingDefaultAdmin();
    if (_msgSender() != newDefaultAdmin) {
      // Enforce newDefaultAdmin explicit acceptance.
      revert AccessControlInvalidDefaultAdmin(_msgSender());
    }
    _acceptDefaultAdminTransfer();
  }

  /**
   * @dev See {acceptDefaultAdminTransfer}.
   *
   * Internal function without access restriction.
   */
  function _acceptDefaultAdminTransfer() internal virtual {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    (address newAdmin, uint48 schedule) = pendingDefaultAdmin();
    if (!_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {
      revert AccessControlEnforcedDefaultAdminDelay(schedule);
    }
    _revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin());
    _grantRole(DEFAULT_ADMIN_ROLE, newAdmin);
    delete $._pendingDefaultAdmin;
    delete $._pendingDefaultAdminSchedule;
  }

  ///
  /// AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay
  ///

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function changeDefaultAdminDelay(
    uint48 newDelay
  ) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
    _changeDefaultAdminDelay(newDelay);
  }

  /**
   * @dev See {changeDefaultAdminDelay}.
   *
   * Internal function without access restriction.
   */
  function _changeDefaultAdminDelay(
    uint48 newDelay
  ) internal virtual {
    uint48 newSchedule = SafeCast.toUint48(block.timestamp) + _delayChangeWait(newDelay);
    _setPendingDelay(newDelay, newSchedule);
    emit DefaultAdminDelayChangeScheduled(newDelay, newSchedule);
  }

  /**
   * @inheritdoc IAccessControlDefaultAdminRules
   */
  function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
    _rollbackDefaultAdminDelay();
  }

  /**
   * @dev See {rollbackDefaultAdminDelay}.
   *
   * Internal function without access restriction.
   */
  function _rollbackDefaultAdminDelay() internal virtual {
    _setPendingDelay(0, 0);
  }

  /**
   * @dev Returns the amount of seconds to wait after the `newDelay` will
   * become the new {defaultAdminDelay}.
   *
   * The value returned guarantees that if the delay is reduced, it will go into effect
   * after a wait that honors the previously set delay.
   *
   * See {defaultAdminDelayIncreaseWait}.
   */
  function _delayChangeWait(
    uint48 newDelay
  ) internal view virtual returns (uint48) {
    uint48 currentDelay = defaultAdminDelay();

    // When increasing the delay, we schedule the delay change to occur after a period of "new delay" has passed, up
    // to a maximum given by defaultAdminDelayIncreaseWait, by default 5 days. For example, if increasing from 1 day
    // to 3 days, the new delay will come into effect after 3 days. If increasing from 1 day to 10 days, the new
    // delay will come into effect after 5 days. The 5 day wait period is intended to be able to fix an error like
    // using milliseconds instead of seconds.
    //
    // When decreasing the delay, we wait the difference between "current delay" and "new delay". This guarantees
    // that an admin transfer cannot be made faster than "current delay" at the time the delay change is scheduled.
    // For example, if decreasing from 10 days to 3 days, the new delay will come into effect after 7 days.
    return newDelay > currentDelay
      ? uint48(Math.min(newDelay, defaultAdminDelayIncreaseWait())) // no need to safecast, both inputs are uint48
      : currentDelay - newDelay;
  }

  ///
  /// Private setters
  ///

  /**
   * @dev Setter of the tuple for pending admin and its schedule.
   *
   * May emit a DefaultAdminTransferCanceled event.
   */
  function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    (, uint48 oldSchedule) = pendingDefaultAdmin();

    $._pendingDefaultAdmin = newAdmin;
    $._pendingDefaultAdminSchedule = newSchedule;

    // An `oldSchedule` from `pendingDefaultAdmin()` is only set if it hasn't been accepted.
    if (_isScheduleSet(oldSchedule)) {
      // Emit for implicit cancellations when another default admin was scheduled.
      emit DefaultAdminTransferCanceled();
    }
  }

  /**
   * @dev Setter of the tuple for pending delay and its schedule.
   *
   * May emit a DefaultAdminDelayChangeCanceled event.
   */
  function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private {
    AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();
    uint48 oldSchedule = $._pendingDelaySchedule;

    if (_isScheduleSet(oldSchedule)) {
      if (_hasSchedulePassed(oldSchedule)) {
        // Materialize a virtual delay
        $._currentDelay = $._pendingDelay;
      } else {
        // Emit for implicit cancellations when another delay was scheduled.
        emit DefaultAdminDelayChangeCanceled();
      }
    }

    $._pendingDelay = newDelay;
    $._pendingDelaySchedule = newSchedule;
  }

  ///
  /// Private helpers
  ///

  /**
   * @dev Defines if an `schedule` is considered set. For consistency purposes.
   */
  function _isScheduleSet(
    uint48 schedule
  ) private pure returns (bool) {
    return schedule != 0;
  }

  /**
   * @dev Defines if an `schedule` is considered passed. For consistency purposes.
   */
  function _hasSchedulePassed(
    uint48 schedule
  ) private view returns (bool) {
    return schedule < block.timestamp;
  }
}
"
    },
    "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/proxy/utils/Initializable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
  /**
   * @dev Storage of the initializable contract.
   *
   * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
   * when using with upgradeable contracts.
   *
   * @custom:storage-location erc7201:openzeppelin.storage.Initializable
   */
  struct InitializableStorage {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    uint64 _initialized;
    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool _initializing;
  }

  // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
  bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

  /**
   * @dev The contract is already initialized.
   */
  error InvalidInitialization();

  /**
   * @dev The contract is not initializing.
   */
  error NotInitializing();

  /**
   * @dev Triggered when the contract has been initialized or reinitialized.
   */
  event Initialized(uint64 version);

  /**
   * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
   * `onlyInitializing` functions can be used to initialize parent contracts.
   *
   * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
   * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
   * production.
   *
   * Emits an {Initialized} event.
   */
  modifier initializer() {
    // solhint-disable-next-line var-name-mixedcase
    InitializableStorage storage $ = _getInitializableStorage();

    // Cache values to avoid duplicated sloads
    bool isTopLevelCall = !$._initializing;
    uint64 initialized = $._initialized;

    // Allowed calls:
    // - initialSetup: the contract is not in the initializing state and no previous version was
    //                 initialized
    // - construction: the contract is initialized at version 1 (no reininitialization) and the
    //                 current contract is just being deployed
    bool initialSetup = initialized == 0 && isTopLevelCall;
    bool construction = initialized == 1 && address(this).code.length == 0;

    if (!initialSetup && !construction) {
      revert InvalidInitialization();
    }
    $._initialized = 1;
    if (isTopLevelCall) {
      $._initializing = true;
    }
    _;
    if (isTopLevelCall) {
      $._initializing = false;
      emit Initialized(1);
    }
  }

  /**
   * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
   * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
   * used to initialize parent contracts.
   *
   * A reinitializer may be used after the original initialization step. This is essential to configure modules that
   * are added through upgrades and that require initialization.
   *
   * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
   * cannot be nested. If one is invoked in the context of another, execution will revert.
   *
   * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
   * a contract, executing them in the right order is up to the developer or operator.
   *
   * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
   *
   * Emits an {Initialized} event.
   */
  modifier reinitializer(
    uint64 version
  ) {
    // solhint-disable-next-line var-name-mixedcase
    InitializableStorage storage $ = _getInitializableStorage();

    if ($._initializing || $._initialized >= version) {
      revert InvalidInitialization();
    }
    $._initialized = version;
    $._initializing = true;
    _;
    $._initializing = false;
    emit Initialized(version);
  }

  /**
   * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
   * {initializer} and {reinitializer} modifiers, directly or indirectly.
   */
  modifier onlyInitializing() {
    _checkInitializing();
    _;
  }

  /**
   * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
   */
  function _checkInitializing() internal view virtual {
    if (!_isInitializing()) {
      revert NotInitializing();
    }
  }

  /**
   * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
   * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
   * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
   * through proxies.
   *
   * Emits an {Initialized} event the first time it is successfully executed.
   */
  function _disableInitializers() internal virtual {
    // solhint-disable-next-line var-name-mixedcase
    InitializableStorage storage $ = _getInitializableStorage();

    if ($._initializing) {
      revert InvalidInitialization();
    }
    if ($._initialized != type(uint64).max) {
      $._initialized = type(uint64).max;
      emit Initialized(type(uint64).max);
    }
  }

  /**
   * @dev Returns the highest version that has been initialized. See {reinitializer}.
   */
  function _getInitializedVersion() internal view returns (uint64) {
    return _getInitializableStorage()._initialized;
  }

  /**
   * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
   */
  function _isInitializing() internal view returns (bool) {
    return _getInitializableStorage()._initializing;
  }

  /**
   * @dev Returns a pointer to the storage namespace.
   */
  // solhint-disable-next-line var-name-mixedcase
  function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
    assembly {
      $.slot := INITIALIZABLE_STORAGE
    }
  }
}
"
    },
    "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/proxy/utils/UUPSUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)

pragma solidity ^0.8.20;

import {IERC1822Proxiable} from "../../../../../openzeppelin-solidity/v5.0.2/contracts/interfaces/draft-IERC1822.sol";
import {ERC1967Utils} from "../../../../../openzeppelin-solidity/v5.0.2/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {Initializable} from "./Initializable.sol";

/**
 * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
 * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
 *
 * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
 * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
 * `UUPSUpgradeable` with a custom implementation of upgrades.
 *
 * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
 */
abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
  /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
  address private immutable __self = address(this);

  /**
   * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
   * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
   * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
   * If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
   * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
   * during an upgrade.
   */
  string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";

  /**
   * @dev The call is from an unauthorized context.
   */
  error UUPSUnauthorizedCallContext();

  /**
   * @dev The storage `slot` is unsupported as a UUID.
   */
  error UUPSUnsupportedProxiableUUID(bytes32 slot);

  /**
   * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
   * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
   * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
   * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
   * fail.
   */
  modifier onlyProxy() {
    _checkProxy();
    _;
  }

  /**
   * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
   * callable on the implementing contract but not through proxies.
   */
  modifier notDelegated() {
    _checkNotDelegated();
    _;
  }

  function __UUPSUpgradeable_init() internal onlyInitializing {}

  function __UUPSUpgradeable_init_unchained() internal onlyInitializing {}
  /**
   * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
   * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
   *
   * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
   * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
   * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
   */

  function proxiableUUID() external view virtual notDelegated returns (bytes32) {
    return ERC1967Utils.IMPLEMENTATION_SLOT;
  }

  /**
   * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
   * encoded in `data`.
   *
   * Calls {_authorizeUpgrade}.
   *
   * Emits an {Upgraded} event.
   *
   * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
   */
  function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
    _authorizeUpgrade(newImplementation);
    _upgradeToAndCallUUPS(newImplementation, data);
  }

  /**
   * @dev Reverts if the execution is not performed via delegatecall or the execution
   * context is not of a proxy with an ERC1967-compliant implementation pointing to self.
   * See {_onlyProxy}.
   */
  function _checkProxy() internal view virtual {
    if (
      address(this) == __self // Must be called through delegatecall
        || ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
    ) {
      revert UUPSUnauthorizedCallContext();
    }
  }

  /**
   * @dev Reverts if the execution is performed via delegatecall.
   * See {notDelegated}.
   */
  function _checkNotDelegated() internal view virtual {
    if (address(this) != __self) {
      // Must not be called through delegatecall
      revert UUPSUnauthorizedCallContext();
    }
  }

  /**
   * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
   * {upgradeToAndCall}.
   *
   * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
   *
   * ```solidity
   * function _authorizeUpgrade(address) internal onlyOwner {}
   * ```
   */
  function _authorizeUpgrade(
    address newImplementation
  ) internal virtual;

  /**
   * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
   *
   * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
   * is expected to be the implementation slot in ERC1967.
   *
   * Emits an {IERC1967-Upgraded} event.
   */
  function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
    try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
      if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
        revert UUPSUnsupportedProxiableUUID(slot);
      }
      ERC1967Utils.upgradeToAndCall(newImplementation, data);
    } catch {
      // The implementation is not UUPS
      revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
    }
  }
}
"
    },
    "mock/src/v0.8/vendor/openzeppelin-solidity-upgradeable/v5.0.2/contracts/token/ERC20/ERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20Errors} from "../../../../../openzeppelin-solidity/v5.0.2/contracts/interfaces/draft-IERC6093.sol";
import {IERC20} from "../../../../../openzeppelin-solidity/v5.0.2/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from
  "../../../../../openzeppelin-solidity/v5.0.2/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 */
abstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {
  /// @custom:storage-location erc7201:openzeppelin.storage.ERC20
  struct ERC20Storage {
    mapping(address account => uint256) _balances;
    mapping(address account => mapping(address spender => uint256)) _allowances;
    uint256 _totalSupply;
    string _name;
    string _symbol;
  }

  // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))
  bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;

  function _getERC20Storage() private pure returns (ERC20Storage storage $) {
    assembly {
      $.slot := ERC20StorageLocation
    }
  }

  /**
   * @dev Sets the values for {name} and {symbol}.
   *
   * All two of these values are immutable: they can only be set once during
   * construction.
   */
  function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
    __ERC20_init_unchained(name_, symbol_);
  }

  function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
    ERC20Storage storage $ = _getERC20Storage();
    $._name = name_;
    $._symbol = symbol_;
  }

  /**
   * @dev Returns the name of the token.
   */
  function name() public view virtual returns (string memory) {
    ERC20Storage storage $ = _getERC20Storage();
    return $._name;
  }

  /**
   * @dev Returns the symbol of the token, usually a shorter version of the
   * name.
   */
  function symbol() public view virtual returns (string memory) {
    ERC20Storage storage $ = _getERC20Storage();
    return $._symbol;
  }

  /**
   * @dev Returns the number of decimals used to get its user representation.
   * For example, if `decimals` equals `2`, a balance of `505` tokens should
   * be displayed to a user as `5.05` (`505 / 10 ** 2`).
   *
   * Tokens usually opt for a value of 18, imitating the relationship between
   * Ether and Wei. This is the default value returned by this function, unless
   * it's overridden.
   *
   * NOTE: This information is only used for _display_ purposes: it in
   * no way affects any of the arithmetic of the contract, including
   * {IERC20-balanceOf} and {IERC20-transfer}.
   */
  function decimals() public view virtual returns (uint8) {
    return 18;
  }

  /**
   * @dev See {IERC20-totalSupply}.
   */
  function totalSupply() public view virtual returns (uint256) {
    ERC20Storage storage $ = _getERC20Storage();
    return $._totalSupply;
  }

  /**
   * @dev See {IERC20-balanceOf}.
   */
  function balanceOf(
    address account
  ) public view virtual returns (uint256) {
    ERC20Storage storage $ = _getERC20Storage();
    return $._balances[account];
  }

  /**
   * @dev See {IERC20-transfer}.
   *
   * Requirements:
   *
   * - `to` cannot be the zero address.
   * - the caller must have a balance of at least `value`.
   */
  function transfer(address to, uint256 value) public virtual returns (bool) {
    address owner = _msgSender();
    _transfer(owner, to, value);
    return true;
  }

  /**
   * @dev See {IERC20-allowance}.
   */
  function allowance(address owne

Tags:
ERC20, ERC165, Multisig, Mintable, Burnable, Pausable, Voting, Upgradeable, Multi-Signature, Factory, Oracle|addr:0x856f48bc9cd053a5637b680f738a534653c475c3|verified:true|block:23425457|tx:0xe97f0a39a99dba879a57b2b55b6cecd503775fcbc81a1fc9136e628778524e2b|first_check:1758723497

Submitted on: 2025-09-24 16:18:22

Comments

Log in to comment.

No comments yet.