// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /** * @title ERC1967Proxy * @notice Minimal ERC-1967 proxy. All calls (except construction) are delegated * to the implementation stored in the EIP-1967 slot. * * Deploy flow for FomoMinerBibiUpgradeable: * 1. Deploy `FomoMinerBibiUpgradeable` (logic / implementation) * 2. Encode `initialize(token, poolClaimer, owner, listPrices)` calldata * 3. Deploy `ERC1967Proxy(implementation, initCalldata)` * 4. Players / front-end always use the **Proxy** address * 5. To ship a new version: deploy new implementation, then call * `upgradeTo(newImpl)` or `upgradeToAndCall(newImpl, data)` on the Proxy * (as `owner`) */ contract ERC1967Proxy { // keccak256("eip1967.proxy.implementation") - 1 bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; error ProxyDelegateFailed(); constructor(address implementation_, bytes memory data_) { require(implementation_ != address(0), "ZERO_IMPL"); require(implementation_.code.length > 0, "NOT_CONTRACT"); assembly { sstore(_IMPLEMENTATION_SLOT, implementation_) } if (data_.length > 0) { (bool ok, bytes memory ret) = implementation_.delegatecall(data_); if (!ok) { if (ret.length == 0) revert ProxyDelegateFailed(); assembly { revert(add(ret, 32), mload(ret)) } } } } fallback() external payable { _delegate(); } receive() external payable { _delegate(); } function _delegate() private { assembly { let impl := sload(_IMPLEMENTATION_SLOT) calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } }