{"file_path":"solidity/contracts/FlowStakingPool.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.16;\n\nimport \"@ankr.com/contracts/earn/extension/MixedLiquidTokenStakingPool.sol\";\nimport \"./config/FlowStakingConfig.sol\";\n\ncontract FlowStakingPool is MixedLiquidTokenStakingPool {\n    event FlowBridgeAddressChanged(address prevValue, address newValue);\n    event FlowBridgeFunded(address bridge, uint256 amount);\n\n    /// @dev Cadence-owned account address. Used to bridge staked FLOW to Cadence side\n    address internal flowBridgeAddress;\n\n    /// @param earnConfig contains major addresses for Ankr LiquidTokenStaking: consensus, governance, treasury...\n    function initialize(\n        IEarnConfig earnConfig,\n        uint256 distributeGasLimit,\n        address _flowBridgeAddress\n    ) external initializer {\n        require(\n            _flowBridgeAddress != address(0),\n            \"Cannot set Flow bridge address to zero\"\n        );\n        __Ownable_init();\n        __QueuePool_init(distributeGasLimit);\n        __LiquidTokenStakingPool_init(earnConfig);\n        __ReferralPool_init();\n        __ImmediatePool_init();\n        __ManualClaimPool_init();\n        __MixedPool_init();\n        flowBridgeAddress = _flowBridgeAddress;\n        emit FlowBridgeAddressChanged(address(0), _flowBridgeAddress);\n    }\n\n    /**\n     * Staking methods\n     */\n\n    /// @dev After staking, we need to send funds to the flow bridge\n    function _afterStake(\n        address /* account */,\n        uint256 amount,\n        uint256 /* shares */\n    ) internal virtual override {\n        bool bridgeTransfer = _unsafeTransfer(flowBridgeAddress, amount, false);\n        require(\n            bridgeTransfer,\n            \"FlowStakingPool: failed to send staked FLOW to bridge address\"\n        );\n\n        emit FlowBridgeFunded(flowBridgeAddress, amount);\n    }\n\n    /**\n     * Unstaking methods\n     */\n\n    /// @dev Everyone can execute, but usually a backend service do it\n    /// @notice Pending unstake requests kept in smart-contract state with receive addresses\n    /// @dev GasLimit param should be set higher than 100_000 wei for execution queue in _distributePendingRewards\n    function distributePendingRewards() external payable nonReentrant {\n        _distributePendingRewards();\n    }\n\n    /**\n     * FlowEVMPool specific methods\n     */\n    // TODO: determine necesity of checking newValue COA ownership\n    function setFlowBridgeAddress(address newValue) external onlyOwner {\n        require(\n            newValue != address(0),\n            \"Cannot set Flow bridge address to zero\"\n        );\n        address prevValue = flowBridgeAddress;\n        flowBridgeAddress = newValue;\n        emit FlowBridgeAddressChanged(prevValue, newValue);\n    }\n\n    function getFlowBridgeAddress() external view returns (address) {\n        return flowBridgeAddress;\n    }\n\n    /// @notice Recovers native FLOW held by this contract that is not owed to any\n    /// pending unstake request or manual claim - e.g. FLOW sent here directly\n    /// (bypassing stakeBonds/stakeCerts) by mistake. Always routed to\n    /// flowBridgeAddress, the same destination staked funds are forwarded to.\n    /// @dev Bounded by getFreeBalance() - getTotalPendingUnstakes(), so funds\n    /// reserved for other users' unstakes/manual claims can never be moved.\n    function recoverStrayFunds(\n        uint256 amount\n    ) external onlyOwner nonReentrant {\n        uint256 pendingUnstakes = getTotalPendingUnstakes();\n        uint256 freeBalance = getFreeBalance();\n        require(\n            freeBalance > pendingUnstakes,\n            \"FlowStakingPool: no recoverable surplus\"\n        );\n        uint256 surplus = freeBalance - pendingUnstakes;\n        require(\n            amount <= surplus,\n            \"FlowStakingPool: amount exceeds recoverable surplus\"\n        );\n\n        bool success = _unsafeTransfer(flowBridgeAddress, amount, false);\n        require(success, \"FlowStakingPool: transfer failed\");\n\n        emit FlowBridgeFunded(flowBridgeAddress, amount);\n    }\n}\n","deployed_bytecode":"0x6080604052600436106101f25760003560e01c80638c0bfdee1161010d578063cb1f951b116100a0578063e44148ec1161006f578063e44148ec146105af578063e93c4f15146105cf578063e97b4d16146105e4578063ec05e6741461061a578063f2fde38b1461062257600080fd5b8063cb1f951b1461051f578063cea7cd8614610567578063d05b01ae1461057a578063d0652e421461059a57600080fd5b8063ac76d450116100dc578063ac76d450146104b7578063c1ebda7f146104bf578063c350a1b5146104df578063c56c838c146104ff57600080fd5b80638c0bfdee146104315780638da5cb5b146104465780638f4662d114610464578063aa6ca8081461048457600080fd5b806346faa33c11610185578063715018a611610154578063715018a6146103c957806381782dff146103de57806381c180b7146103fe5780638b10caeb1461041e57600080fd5b806346faa33c146103565780635234bd5f1461038c57806356a3b5fa146103ac5780636d186d7b146103c157600080fd5b8063107ba721116101c1578063107ba721146102ce578063126d5df61461030157806321ce57cf14610316578063233e99031461033657600080fd5b806301ff923c14610233578063034c445414610269578063042fc3a61461028c5780630d904ce2146102ae57600080fd5b3661022e5760405134815233907f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258749060200160405180910390a2005b600080fd5b34801561023f57600080fd5b5061025361024e366004612a96565b610642565b6040516102609190612aee565b60405180910390f35b34801561027557600080fd5b5061027e610760565b604051908152602001610260565b34801561029857600080fd5b506102ac6102a7366004612b01565b610783565b005b3480156102ba57600080fd5b506102ac6102c9366004612b01565b610879565b3480156102da57600080fd5b50610190546001600160a01b03165b6040516001600160a01b039091168152602001610260565b34801561030d57600080fd5b5060fc5461027e565b34801561032257600080fd5b506102ac610331366004612b01565b6108c5565b34801561034257600080fd5b506102ac610351366004612b01565b610a6f565b34801561036257600080fd5b5061027e610371366004612a96565b6001600160a01b0316600090815260fe602052604090205490565b34801561039857600080fd5b506102ac6103a7366004612b1a565b610c2a565b3480156103b857600080fd5b5061027e610cde565b6102ac610d03565b3480156103d557600080fd5b506102ac610d1f565b3480156103ea57600080fd5b506102ac6103f9366004612b1a565b610d31565b34801561040a57600080fd5b506102ac610419366004612b01565b610d43565b6102ac61042c366004612b01565b610e16565b34801561043d57600080fd5b5060c85461027e565b34801561045257600080fd5b506033546001600160a01b03166102e9565b34801561047057600080fd5b506102ac61047f366004612a96565b610e5d565b34801561049057600080fd5b50609754609854604080516001600160a01b03938416815292909116602083015201610260565b6102ac610ee6565b3480156104cb57600080fd5b506102ac6104da366004612b01565b610ef8565b3480156104eb57600080fd5b506102ac6104fa366004612b46565b6110b9565b34801561050b57600080fd5b506102ac61051a366004612a96565b611280565b34801561052b57600080fd5b5061055761053a366004612a96565b6001600160a01b0316600090815260c96020526040902054151590565b6040519015158152602001610260565b6102ac610575366004612b01565b611381565b34801561058657600080fd5b506102ac610595366004612a96565b611393565b3480156105a657600080fd5b5060fa5461027e565b3480156105bb57600080fd5b506102ac6105ca366004612a96565b611494565b3480156105db57600080fd5b5061027e6116f8565b3480156105f057600080fd5b5061027e6105ff366004612a96565b6001600160a01b0316600090815260c9602052604090205490565b6102ac61171c565b34801561062e57600080fd5b506102ac61063d366004612a96565b6117c2565b60fb5460fd54606091600091829161065991612b9e565b67ffffffffffffffff81111561067157610671612bb7565b60405190808252806020026020018201604052801561069a578160200160208202803683370190505b5060fb549091505b60fd5481101561073c57846001600160a01b031660fd82815481106106c9576106c9612bcd565b6000918252602090912001546001600160a01b03160361072a5760ff81815481106106f6576106f6612bcd565b906000526020600020015482848151811061071357610713612bcd565b602090810291909101015261072783612be3565b92505b8061073481612be3565b9150506106a2565b50600082825161074c9190612b9e565b90508015610758578282525b509392505050565b609a5460009061077e9067ffffffffffffffff16633b9aca00612bfc565b905090565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190612c1b565b6001600160a01b0316336001600160a01b0316146108335760405162461bcd60e51b815260040161082a90612c38565b60405180910390fd5b60fa80549082905560408051828152602081018490527f3bb2da990d30b0bc98e39d632b60814d66b3bae55947927dec7a75719de577de91015b60405180910390a15050565b33600090815260c96020526040902054156108a65760405162461bcd60e51b815260040161082a90612c87565b6108ae611838565b6108b83382611891565b6108c26001606555565b50565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015610918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093c9190612c1b565b6001600160a01b0316336001600160a01b03161461096c5760405162461bcd60e51b815260040161082a90612c38565b61097a633b9aca0082612cfa565b156109975760405162461bcd60e51b815260040161082a90612d0e565b60006109a1610760565b90506109b1633b9aca0083612d6b565b609a805467ffffffffffffffff191667ffffffffffffffff92909216918217905582906109e290633b9aca00612d7f565b67ffffffffffffffff1614610a395760405162461bcd60e51b815260206004820181905260248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206f766572666c6f77604482015260640161082a565b60408051828152602081018490527f976e4c5a2502181884199a44267e9ba339f2d071066e4f0ae97600ce4975935c910161086d565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae69190612c1b565b6001600160a01b0316336001600160a01b031614610b165760405162461bcd60e51b815260040161082a90612c38565b610b24633b9aca0082612cfa565b15610b415760405162461bcd60e51b815260040161082a90612d0e565b6000610b4b610cde565b9050610b5b633b9aca0083612d6b565b6099805467ffffffffffffffff60a01b1916600160a01b67ffffffffffffffff938416810291909117918290558492610b9d929190910416633b9aca00612d7f565b67ffffffffffffffff1614610bf45760405162461bcd60e51b815260206004820181905260248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206f766572666c6f77604482015260640161082a565b60408051828152602081018490527fdc4a0b2dc1fa27da98de2ac6f8fa373b4be405e1bf69fc3976597b6d56b79abc910161086d565b610c32611838565b609960009054906101000a90046001600160a01b03166001600160a01b0316639fe553c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca99190612daf565b15610cc65760405162461bcd60e51b815260040161082a90612dd1565b610cd08282611a87565b610cda6001606555565b5050565b60995460009061077e90600160a01b900467ffffffffffffffff16633b9aca00612bfc565b610d0b611838565b610d13611cdb565b610d1d6001606555565b565b610d27612094565b610d1d60006120ee565b610d39611838565b610cd08282611891565b610d4b611838565b33600090815260c9602052604090205415610d785760405162461bcd60e51b815260040161082a90612c87565b609960009054906101000a90046001600160a01b03166001600160a01b0316639fe553c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610def9190612daf565b15610e0c5760405162461bcd60e51b815260040161082a90612dd1565b6108b83382611a87565b610e1e611838565b610e283334612140565b60405181907f3c16de186f1ef5ecb8049424d69d8038355dfdd932e194e95067b0dadd05259890600090a26108c26001606555565b610e65612094565b6001600160a01b038116610e8b5760405162461bcd60e51b815260040161082a90612e1f565b61019080546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f222b3805ad11387cfa3d8ff25b5c1a386d56f568f07c217088b91e17996882ca910161086d565b610eee611838565b610d1333346121cd565b610f00612094565b610f08611838565b6000610f1360fc5490565b90506000610f1f6116f8565b9050818111610f805760405162461bcd60e51b815260206004820152602760248201527f466c6f775374616b696e67506f6f6c3a206e6f207265636f76657261626c6520604482015266737572706c757360c81b606482015260840161082a565b6000610f8c8383612b9e565b905080841115610ffa5760405162461bcd60e51b815260206004820152603360248201527f466c6f775374616b696e67506f6f6c3a20616d6f756e742065786365656473206044820152727265636f76657261626c6520737572706c757360681b606482015260840161082a565b61019054600090611015906001600160a01b031686836122bb565b9050806110645760405162461bcd60e51b815260206004820181905260248201527f466c6f775374616b696e67506f6f6c3a207472616e73666572206661696c6564604482015260640161082a565b61019054604080516001600160a01b039092168252602082018790527f11ff5db12742675bcf3ccb786e43022f6e18f2a9e7600e406ee808724bf20880910160405180910390a1505050506108c26001606555565b600054610100900460ff16158080156110d95750600054600160ff909116105b806110f35750303b1580156110f3575060005460ff166001145b6111565760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161082a565b6000805460ff191660011790558015611179576000805461ff0019166101001790555b6001600160a01b03821661119f5760405162461bcd60e51b815260040161082a90612e1f565b6111a7612338565b6111b083612367565b6111b9846123d0565b6111c1612419565b6111c9612419565b6111d1612419565b6111d9612419565b61019080546001600160a01b0319166001600160a01b038416908117909155604080516000815260208101929092527f222b3805ad11387cfa3d8ff25b5c1a386d56f568f07c217088b91e17996882ca910160405180910390a1801561127a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b50505050565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f79190612c1b565b6001600160a01b0316336001600160a01b0316146113275760405162461bcd60e51b815260040161082a90612c38565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fbfd6f15b713a9c39626b80329f359df34f5b64863e24acd3869092794a1ee8f2910161086d565b611389611838565b610e2833346121cd565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140a9190612c1b565b6001600160a01b0316336001600160a01b03161461143a5760405162461bcd60e51b815260040161082a90612c38565b609880546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f63d8371ad7e38cfb2f86b20688da999f9750c68f15d078ac59c9a64c410b4432910161086d565b61149c611838565b6001600160a01b0381166114fe5760405162461bcd60e51b8152602060048201526024808201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a207a65726f206164646044820152637265737360e01b606482015260840161082a565b6001600160a01b038116600090815260c96020526040902054806115805760405162461bcd60e51b815260206004820152603360248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206e6f74206d61726b604482015272656420666f72206d616e75616c20636c61696d60681b606482015260840161082a565b60c8544710156115ec5760405162461bcd60e51b815260206004820152603160248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20696e73756666696360448201527069656e7420706f6f6c2062616c616e636560781b606482015260840161082a565b8060c860008282546115fe9190612b9e565b90915550506001600160a01b038216600090815260c9602052604081208190556116298383836122bb565b9050806116a85760405162461bcd60e51b815260206004820152604160248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206661696c6564207460448201527f6f2073656e64207265776172647320746f2072656365697665724164647265736064820152607360f81b608482015260a40161082a565b60408051338152602081018490526001600160a01b038516917f9310ccfcb8de723f578a9e4282ea9f521f05ae40dc08f3068dfad528a65ee3c7910160405180910390a250506108c26001606555565b600061170360c85490565b47106117165760c85461077e9047612b9e565b50600090565b611724611838565b609960009054906101000a90046001600160a01b03166001600160a01b0316639fe553c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179b9190612daf565b156117b85760405162461bcd60e51b815260040161082a90612dd1565b610d133334612140565b6117ca612094565b6001600160a01b03811661182f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161082a565b6108c2816120ee565b60026065540361188a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161082a565b6002606555565b609854604051636c58d43d60e01b81526004810183905233916000916001600160a01b0390911690636c58d43d90602401602060405180830381865afa1580156118df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119039190612e65565b905061190d610760565b81101561192c5760405162461bcd60e51b815260040161082a90612e7e565b6098546040516370a0823160e01b81526001600160a01b038481166004830152859216906370a0823190602401602060405180830381865afa158015611976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199a9190612e65565b10156119b85760405162461bcd60e51b815260040161082a90612edb565b6119c3828583612440565b609854604051632770a7eb60e21b81526001600160a01b0384811660048301526024820186905290911690639dc29fac90604401600060405180830381600087803b158015611a1157600080fd5b505af1158015611a25573d6000803e3d6000fd5b50505050611a348285836124cc565b60408051828152602081018590526000916001600160a01b0380881692908616917fad145f1b26afda04058ac140badd5b2ae9369e46bf2e2a519fcdb40b65289c4a91015b60405180910390a450505050565b609754604051635361637360e01b81526004810183905233916000916001600160a01b0390911690635361637390602401602060405180830381865afa158015611ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af99190612e65565b9050611b03610760565b831015611b225760405162461bcd60e51b815260040161082a90612e7e565b6097546040516370a0823160e01b81526001600160a01b038481166004830152859216906370a0823190602401602060405180830381865afa158015611b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b909190612e65565b1015611bae5760405162461bcd60e51b815260040161082a90612edb565b611bb9828585612440565b609854609754604051632770a7eb60e21b81526001600160a01b03918216600482015260248101849052911690639dc29fac90604401600060405180830381600087803b158015611c0957600080fd5b505af1158015611c1d573d6000803e3d6000fd5b5050609754604051632770a7eb60e21b81526001600160a01b038681166004830152602482018690529091169250639dc29fac9150604401600060405180830381600087803b158015611c6f57600080fd5b505af1158015611c83573d6000803e3d6000fd5b50505050611c928285856124cc565b60408051848152602081018390526001916001600160a01b0380881692908616917fad145f1b26afda04058ac140badd5b2ae9369e46bf2e2a519fcdb40b65289c4a9101611a79565b600060fa5411611d535760405162461bcd60e51b815260206004820152603760248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20444953545249425560448201527f54455f4741535f4c494d4954206973206e6f7420736574000000000000000000606482015260840161082a565b6000611d5d6116f8565b60fb5460fd54919250600091611d739190612b9e565b67ffffffffffffffff811115611d8b57611d8b612bb7565b604051908082528060200260200182016040528015611db4578160200160208202803683370190505b5060fb5460fd54919250600091611dcb9190612b9e565b67ffffffffffffffff811115611de357611de3612bb7565b604051908082528060200260200182016040528015611e0c578160200160208202803683370190505b5060fb549091506000905b60fd5481108015611e285750600085115b8015611e35575060fa545a115b1561202f57600060fd8281548110611e4f57611e4f612bcd565b600091825260208220015460ff80546001600160a01b0390921693509084908110611e7c57611e7c612bcd565b60009182526020909120015490506001600160a01b0382161580611e9e575080155b15611eb557611eac83612be3565b92505050611e17565b80871015611ec457505061202f565b6001600160a01b038216600090815260fe602052604081208054839290611eec908490612b9e565b925050819055508060fc6000828254611f059190612b9e565b90915550611f1590508188612b9e565b965060fd8381548110611f2a57611f2a612bcd565b600091825260209091200180546001600160a01b031916905560ff805484908110611f5757611f57612bcd565b6000918252602082200155611f6b83612be3565b9250611f8e826001600160a01b0316600090815260c96020526040902054151590565b15611fa457611f9d82826124ef565b5050611e17565b6000611fb2838360016122bb565b905080611fcb57611fc383836124ef565b505050611e17565b82878681518110611fde57611fde612bcd565b60200260200101906001600160a01b031690816001600160a01b0316815250508186868151811061201157612011612bcd565b602090810291909101015261202585612be3565b9450505050611e17565b60fb8190558351600090612044908490612b9e565b90508015612053578285528284525b7fe69d325558610ba73c441901deb46d7f251108348dc5dc9447e8866774c12edc8585604051612084929190612f39565b60405180910390a1505050505050565b6033546001600160a01b03163314610d1d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161082a565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b609754604051635361637360e01b8152600481018390526000916001600160a01b031690635361637390602401602060405180830381865afa15801561218a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ae9190612e65565b90506121bd8383836001612575565b6121c88383836126b8565b505050565b609854604051635361637360e01b8152600481018390526000916001600160a01b031690635361637390602401602060405180830381865afa158015612217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223b9190612e65565b905061224a8383836000612575565b609754604051631a1ac52760e21b81526001600160a01b038581166004830152602482018490529091169063686b149c90604401600060405180830381600087803b15801561229857600080fd5b505af11580156122ac573d6000803e3d6000fd5b505050506121c88383836126b8565b6000838183156122db576000806000808886612710f19250612331915050565b6040516001600160a01b038316908690600081818185875af1925050503d8060008114612324576040519150601f19603f3d011682016040523d82523d6000602084013e612329565b606091505b509093505050505b9392505050565b600054610100900460ff1661235f5760405162461bcd60e51b815260040161082a90612f99565b610d1d61278c565b600054610100900460ff1661238e5760405162461bcd60e51b815260040161082a90612f99565b60fa8190556040805160008152602081018390527f3bb2da990d30b0bc98e39d632b60814d66b3bae55947927dec7a75719de577de910160405180910390a150565b600054610100900460ff166123f75760405162461bcd60e51b815260040161082a90612f99565b609980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16610d1d5760405162461bcd60e51b815260040161082a90612f99565b6001600160a01b038216600090815260c96020526040902054156121c85760405162461bcd60e51b815260206004820152603b60248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20726563656976657260448201527f206973206d61726b656420666f72206d616e75616c20636c61696d0000000000606482015260840161082a565b806124d56116f8565b106124e4576121c882826127bc565b6121c8838383612904565b8060c860008282546125019190612fe4565b90915550506001600160a01b038216600090815260c960205260408120805483929061252e908490612fe4565b90915550506040518181526001600160a01b038316907fd3a9686144ad9a6d4bfdad99cc4083c7de8e5a5a155fb9c2325a492d5bc83ba59060200160405180910390a25050565b61257d610cde565b83101561259c5760405162461bcd60e51b815260040161082a90612e7e565b6098546097546040516340c10f1960e01b81526001600160a01b039182166004820152602481018590529116906340c10f1990604401600060405180830381600087803b1580156125ec57600080fd5b505af1158015612600573d6000803e3d6000fd5b50506097546040516340c10f1960e01b81526001600160a01b0388811660048301526024820187905290911692506340c10f199150604401600060405180830381600087803b15801561265257600080fd5b505af1158015612666573d6000803e3d6000fd5b5050604080518681526020810186905284151593506001600160a01b03881692507f3df45cb339f96ae4bdb793efcb6e22100dd0dc4fd739a4ee2033fe67ea35af96910160405180910390a350505050565b610190546000906126d3906001600160a01b031684836122bb565b9050806127485760405162461bcd60e51b815260206004820152603d60248201527f466c6f775374616b696e67506f6f6c3a206661696c656420746f2073656e642060448201527f7374616b656420464c4f5720746f206272696467652061646472657373000000606482015260840161082a565b61019054604080516001600160a01b039092168252602082018590527f11ff5db12742675bcf3ccb786e43022f6e18f2a9e7600e406ee808724bf208809101611271565b600054610100900460ff166127b35760405162461bcd60e51b815260040161082a90612f99565b610d1d336120ee565b806127c56116f8565b10156128395760405162461bcd60e51b815260206004820152603860248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2062616c616e63652060448201527f6c657373207468616e207265776172647320616d6f756e740000000000000000606482015260840161082a565b6000612847838360006122bb565b9050806128bc5760405162461bcd60e51b815260206004820152603960248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206661696c6564207460448201527f6f2073656e64207265776172647320746f20636c61696d657200000000000000606482015260840161082a565b826001600160a01b03167f5910001d6ca4285091c4077cf57bcd244645b77d84a6658b65d31a34f2c9f2d4836040516128f791815260200190565b60405180910390a2505050565b801580159061291b57506001600160a01b03821615155b6129795760405162461bcd60e51b815260206004820152602960248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a207a65726f20696e7060448201526875742076616c75657360b81b606482015260840161082a565b8060fc600082825461298b9190612fe4565b909155505060fd805460018082019092557f9346ac6dd7de6b96975fec380d4d994c4c12e6a8897544f22915316cc6cca2800180546001600160a01b0319166001600160a01b03851690811790915560ff805492830190557fe08ec2af2cfc251225e1968fd6ca21e4044f129bffa95bac3503be8bdb30a367909101829055600090815260fe602052604081208054839290612a28908490612fe4565b92505081905550816001600160a01b0316836001600160a01b03167f8bd920adc14654a74328c96f8873d60e6836c1e81079be3a620ec760602dcd8c83604051612a7491815260200190565b60405180910390a3505050565b6001600160a01b03811681146108c257600080fd5b600060208284031215612aa857600080fd5b813561233181612a81565b600081518084526020808501945080840160005b83811015612ae357815187529582019590820190600101612ac7565b509495945050505050565b6020815260006123316020830184612ab3565b600060208284031215612b1357600080fd5b5035919050565b60008060408385031215612b2d57600080fd5b8235612b3881612a81565b946020939093013593505050565b600080600060608486031215612b5b57600080fd5b8335612b6681612a81565b9250602084013591506040840135612b7d81612a81565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b81810381811115612bb157612bb1612b88565b92915050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201612bf557612bf5612b88565b5060010190565b6000816000190483118215151615612c1657612c16612b88565b500290565b600060208284031215612c2d57600080fd5b815161233181612a81565b6020808252602f908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206f6e6c7920676f7660408201526e195c9b985b98d948185b1b1bddd959608a1b606082015260800190565b60208082526039908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2073656e646572206960408201527f73206d61726b656420666f72206d616e75616c20636c61696d00000000000000606082015260800190565b634e487b7160e01b600052601260045260246000fd5b600082612d0957612d09612ce4565b500690565b6020808252603a908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2076616c756520736860408201527f6f756c64206265206d756c7469706c696564206f662067776569000000000000606082015260800190565b600082612d7a57612d7a612ce4565b500490565b600067ffffffffffffffff80831681851681830481118215151615612da657612da6612b88565b02949350505050565b600060208284031215612dc157600080fd5b8151801515811461233157600080fd5b6020808252602e908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20626f6e642073746160408201526d1ada5b99c81a5cc81c185d5cd95960921b606082015260800190565b60208082526026908201527f43616e6e6f742073657420466c6f7720627269646765206164647265737320746040820152656f207a65726f60d01b606082015260800190565b600060208284031215612e7757600080fd5b5051919050565b6020808252603d908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2076616c7565206d7560408201527f73742062652067726561746572207468616e206d696e20616d6f756e74000000606082015260800190565b602080825260409082018190527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2063616e6e6f742075908201527f6e7374616b65206d6f7265207468616e2068617665206f6e2061646472657373606082015260800190565b604080825283519082018190526000906020906060840190828701845b82811015612f7b5781516001600160a01b031684529284019290840190600101612f56565b50505083810382850152612f8f8186612ab3565b9695505050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b80820180821115612bb157612bb1612b8856fea2646970667358221220189cda6fcf77f2946547d3bcd07c218051e7520a82b8cd28041ca4a2bf56ae9664736f6c63430008100033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"libraries":{},"metadata":{"useLiteralContent":true},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}}},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.16+commit.07a7930e","is_verified_via_verifier_alliance":false,"verified_at":"2026-07-25T03:33:28.804629Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x608060405234801561001057600080fd5b5061302d806100206000396000f3fe6080604052600436106101f25760003560e01c80638c0bfdee1161010d578063cb1f951b116100a0578063e44148ec1161006f578063e44148ec146105af578063e93c4f15146105cf578063e97b4d16146105e4578063ec05e6741461061a578063f2fde38b1461062257600080fd5b8063cb1f951b1461051f578063cea7cd8614610567578063d05b01ae1461057a578063d0652e421461059a57600080fd5b8063ac76d450116100dc578063ac76d450146104b7578063c1ebda7f146104bf578063c350a1b5146104df578063c56c838c146104ff57600080fd5b80638c0bfdee146104315780638da5cb5b146104465780638f4662d114610464578063aa6ca8081461048457600080fd5b806346faa33c11610185578063715018a611610154578063715018a6146103c957806381782dff146103de57806381c180b7146103fe5780638b10caeb1461041e57600080fd5b806346faa33c146103565780635234bd5f1461038c57806356a3b5fa146103ac5780636d186d7b146103c157600080fd5b8063107ba721116101c1578063107ba721146102ce578063126d5df61461030157806321ce57cf14610316578063233e99031461033657600080fd5b806301ff923c14610233578063034c445414610269578063042fc3a61461028c5780630d904ce2146102ae57600080fd5b3661022e5760405134815233907f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258749060200160405180910390a2005b600080fd5b34801561023f57600080fd5b5061025361024e366004612a96565b610642565b6040516102609190612aee565b60405180910390f35b34801561027557600080fd5b5061027e610760565b604051908152602001610260565b34801561029857600080fd5b506102ac6102a7366004612b01565b610783565b005b3480156102ba57600080fd5b506102ac6102c9366004612b01565b610879565b3480156102da57600080fd5b50610190546001600160a01b03165b6040516001600160a01b039091168152602001610260565b34801561030d57600080fd5b5060fc5461027e565b34801561032257600080fd5b506102ac610331366004612b01565b6108c5565b34801561034257600080fd5b506102ac610351366004612b01565b610a6f565b34801561036257600080fd5b5061027e610371366004612a96565b6001600160a01b0316600090815260fe602052604090205490565b34801561039857600080fd5b506102ac6103a7366004612b1a565b610c2a565b3480156103b857600080fd5b5061027e610cde565b6102ac610d03565b3480156103d557600080fd5b506102ac610d1f565b3480156103ea57600080fd5b506102ac6103f9366004612b1a565b610d31565b34801561040a57600080fd5b506102ac610419366004612b01565b610d43565b6102ac61042c366004612b01565b610e16565b34801561043d57600080fd5b5060c85461027e565b34801561045257600080fd5b506033546001600160a01b03166102e9565b34801561047057600080fd5b506102ac61047f366004612a96565b610e5d565b34801561049057600080fd5b50609754609854604080516001600160a01b03938416815292909116602083015201610260565b6102ac610ee6565b3480156104cb57600080fd5b506102ac6104da366004612b01565b610ef8565b3480156104eb57600080fd5b506102ac6104fa366004612b46565b6110b9565b34801561050b57600080fd5b506102ac61051a366004612a96565b611280565b34801561052b57600080fd5b5061055761053a366004612a96565b6001600160a01b0316600090815260c96020526040902054151590565b6040519015158152602001610260565b6102ac610575366004612b01565b611381565b34801561058657600080fd5b506102ac610595366004612a96565b611393565b3480156105a657600080fd5b5060fa5461027e565b3480156105bb57600080fd5b506102ac6105ca366004612a96565b611494565b3480156105db57600080fd5b5061027e6116f8565b3480156105f057600080fd5b5061027e6105ff366004612a96565b6001600160a01b0316600090815260c9602052604090205490565b6102ac61171c565b34801561062e57600080fd5b506102ac61063d366004612a96565b6117c2565b60fb5460fd54606091600091829161065991612b9e565b67ffffffffffffffff81111561067157610671612bb7565b60405190808252806020026020018201604052801561069a578160200160208202803683370190505b5060fb549091505b60fd5481101561073c57846001600160a01b031660fd82815481106106c9576106c9612bcd565b6000918252602090912001546001600160a01b03160361072a5760ff81815481106106f6576106f6612bcd565b906000526020600020015482848151811061071357610713612bcd565b602090810291909101015261072783612be3565b92505b8061073481612be3565b9150506106a2565b50600082825161074c9190612b9e565b90508015610758578282525b509392505050565b609a5460009061077e9067ffffffffffffffff16633b9aca00612bfc565b905090565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190612c1b565b6001600160a01b0316336001600160a01b0316146108335760405162461bcd60e51b815260040161082a90612c38565b60405180910390fd5b60fa80549082905560408051828152602081018490527f3bb2da990d30b0bc98e39d632b60814d66b3bae55947927dec7a75719de577de91015b60405180910390a15050565b33600090815260c96020526040902054156108a65760405162461bcd60e51b815260040161082a90612c87565b6108ae611838565b6108b83382611891565b6108c26001606555565b50565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015610918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093c9190612c1b565b6001600160a01b0316336001600160a01b03161461096c5760405162461bcd60e51b815260040161082a90612c38565b61097a633b9aca0082612cfa565b156109975760405162461bcd60e51b815260040161082a90612d0e565b60006109a1610760565b90506109b1633b9aca0083612d6b565b609a805467ffffffffffffffff191667ffffffffffffffff92909216918217905582906109e290633b9aca00612d7f565b67ffffffffffffffff1614610a395760405162461bcd60e51b815260206004820181905260248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206f766572666c6f77604482015260640161082a565b60408051828152602081018490527f976e4c5a2502181884199a44267e9ba339f2d071066e4f0ae97600ce4975935c910161086d565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae69190612c1b565b6001600160a01b0316336001600160a01b031614610b165760405162461bcd60e51b815260040161082a90612c38565b610b24633b9aca0082612cfa565b15610b415760405162461bcd60e51b815260040161082a90612d0e565b6000610b4b610cde565b9050610b5b633b9aca0083612d6b565b6099805467ffffffffffffffff60a01b1916600160a01b67ffffffffffffffff938416810291909117918290558492610b9d929190910416633b9aca00612d7f565b67ffffffffffffffff1614610bf45760405162461bcd60e51b815260206004820181905260248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206f766572666c6f77604482015260640161082a565b60408051828152602081018490527fdc4a0b2dc1fa27da98de2ac6f8fa373b4be405e1bf69fc3976597b6d56b79abc910161086d565b610c32611838565b609960009054906101000a90046001600160a01b03166001600160a01b0316639fe553c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca99190612daf565b15610cc65760405162461bcd60e51b815260040161082a90612dd1565b610cd08282611a87565b610cda6001606555565b5050565b60995460009061077e90600160a01b900467ffffffffffffffff16633b9aca00612bfc565b610d0b611838565b610d13611cdb565b610d1d6001606555565b565b610d27612094565b610d1d60006120ee565b610d39611838565b610cd08282611891565b610d4b611838565b33600090815260c9602052604090205415610d785760405162461bcd60e51b815260040161082a90612c87565b609960009054906101000a90046001600160a01b03166001600160a01b0316639fe553c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610def9190612daf565b15610e0c5760405162461bcd60e51b815260040161082a90612dd1565b6108b83382611a87565b610e1e611838565b610e283334612140565b60405181907f3c16de186f1ef5ecb8049424d69d8038355dfdd932e194e95067b0dadd05259890600090a26108c26001606555565b610e65612094565b6001600160a01b038116610e8b5760405162461bcd60e51b815260040161082a90612e1f565b61019080546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f222b3805ad11387cfa3d8ff25b5c1a386d56f568f07c217088b91e17996882ca910161086d565b610eee611838565b610d1333346121cd565b610f00612094565b610f08611838565b6000610f1360fc5490565b90506000610f1f6116f8565b9050818111610f805760405162461bcd60e51b815260206004820152602760248201527f466c6f775374616b696e67506f6f6c3a206e6f207265636f76657261626c6520604482015266737572706c757360c81b606482015260840161082a565b6000610f8c8383612b9e565b905080841115610ffa5760405162461bcd60e51b815260206004820152603360248201527f466c6f775374616b696e67506f6f6c3a20616d6f756e742065786365656473206044820152727265636f76657261626c6520737572706c757360681b606482015260840161082a565b61019054600090611015906001600160a01b031686836122bb565b9050806110645760405162461bcd60e51b815260206004820181905260248201527f466c6f775374616b696e67506f6f6c3a207472616e73666572206661696c6564604482015260640161082a565b61019054604080516001600160a01b039092168252602082018790527f11ff5db12742675bcf3ccb786e43022f6e18f2a9e7600e406ee808724bf20880910160405180910390a1505050506108c26001606555565b600054610100900460ff16158080156110d95750600054600160ff909116105b806110f35750303b1580156110f3575060005460ff166001145b6111565760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161082a565b6000805460ff191660011790558015611179576000805461ff0019166101001790555b6001600160a01b03821661119f5760405162461bcd60e51b815260040161082a90612e1f565b6111a7612338565b6111b083612367565b6111b9846123d0565b6111c1612419565b6111c9612419565b6111d1612419565b6111d9612419565b61019080546001600160a01b0319166001600160a01b038416908117909155604080516000815260208101929092527f222b3805ad11387cfa3d8ff25b5c1a386d56f568f07c217088b91e17996882ca910160405180910390a1801561127a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b50505050565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f79190612c1b565b6001600160a01b0316336001600160a01b0316146113275760405162461bcd60e51b815260040161082a90612c38565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fbfd6f15b713a9c39626b80329f359df34f5b64863e24acd3869092794a1ee8f2910161086d565b611389611838565b610e2833346121cd565b609960009054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140a9190612c1b565b6001600160a01b0316336001600160a01b03161461143a5760405162461bcd60e51b815260040161082a90612c38565b609880546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f63d8371ad7e38cfb2f86b20688da999f9750c68f15d078ac59c9a64c410b4432910161086d565b61149c611838565b6001600160a01b0381166114fe5760405162461bcd60e51b8152602060048201526024808201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a207a65726f206164646044820152637265737360e01b606482015260840161082a565b6001600160a01b038116600090815260c96020526040902054806115805760405162461bcd60e51b815260206004820152603360248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206e6f74206d61726b604482015272656420666f72206d616e75616c20636c61696d60681b606482015260840161082a565b60c8544710156115ec5760405162461bcd60e51b815260206004820152603160248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20696e73756666696360448201527069656e7420706f6f6c2062616c616e636560781b606482015260840161082a565b8060c860008282546115fe9190612b9e565b90915550506001600160a01b038216600090815260c9602052604081208190556116298383836122bb565b9050806116a85760405162461bcd60e51b815260206004820152604160248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206661696c6564207460448201527f6f2073656e64207265776172647320746f2072656365697665724164647265736064820152607360f81b608482015260a40161082a565b60408051338152602081018490526001600160a01b038516917f9310ccfcb8de723f578a9e4282ea9f521f05ae40dc08f3068dfad528a65ee3c7910160405180910390a250506108c26001606555565b600061170360c85490565b47106117165760c85461077e9047612b9e565b50600090565b611724611838565b609960009054906101000a90046001600160a01b03166001600160a01b0316639fe553c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179b9190612daf565b156117b85760405162461bcd60e51b815260040161082a90612dd1565b610d133334612140565b6117ca612094565b6001600160a01b03811661182f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161082a565b6108c2816120ee565b60026065540361188a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161082a565b6002606555565b609854604051636c58d43d60e01b81526004810183905233916000916001600160a01b0390911690636c58d43d90602401602060405180830381865afa1580156118df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119039190612e65565b905061190d610760565b81101561192c5760405162461bcd60e51b815260040161082a90612e7e565b6098546040516370a0823160e01b81526001600160a01b038481166004830152859216906370a0823190602401602060405180830381865afa158015611976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199a9190612e65565b10156119b85760405162461bcd60e51b815260040161082a90612edb565b6119c3828583612440565b609854604051632770a7eb60e21b81526001600160a01b0384811660048301526024820186905290911690639dc29fac90604401600060405180830381600087803b158015611a1157600080fd5b505af1158015611a25573d6000803e3d6000fd5b50505050611a348285836124cc565b60408051828152602081018590526000916001600160a01b0380881692908616917fad145f1b26afda04058ac140badd5b2ae9369e46bf2e2a519fcdb40b65289c4a91015b60405180910390a450505050565b609754604051635361637360e01b81526004810183905233916000916001600160a01b0390911690635361637390602401602060405180830381865afa158015611ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af99190612e65565b9050611b03610760565b831015611b225760405162461bcd60e51b815260040161082a90612e7e565b6097546040516370a0823160e01b81526001600160a01b038481166004830152859216906370a0823190602401602060405180830381865afa158015611b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b909190612e65565b1015611bae5760405162461bcd60e51b815260040161082a90612edb565b611bb9828585612440565b609854609754604051632770a7eb60e21b81526001600160a01b03918216600482015260248101849052911690639dc29fac90604401600060405180830381600087803b158015611c0957600080fd5b505af1158015611c1d573d6000803e3d6000fd5b5050609754604051632770a7eb60e21b81526001600160a01b038681166004830152602482018690529091169250639dc29fac9150604401600060405180830381600087803b158015611c6f57600080fd5b505af1158015611c83573d6000803e3d6000fd5b50505050611c928285856124cc565b60408051848152602081018390526001916001600160a01b0380881692908616917fad145f1b26afda04058ac140badd5b2ae9369e46bf2e2a519fcdb40b65289c4a9101611a79565b600060fa5411611d535760405162461bcd60e51b815260206004820152603760248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20444953545249425560448201527f54455f4741535f4c494d4954206973206e6f7420736574000000000000000000606482015260840161082a565b6000611d5d6116f8565b60fb5460fd54919250600091611d739190612b9e565b67ffffffffffffffff811115611d8b57611d8b612bb7565b604051908082528060200260200182016040528015611db4578160200160208202803683370190505b5060fb5460fd54919250600091611dcb9190612b9e565b67ffffffffffffffff811115611de357611de3612bb7565b604051908082528060200260200182016040528015611e0c578160200160208202803683370190505b5060fb549091506000905b60fd5481108015611e285750600085115b8015611e35575060fa545a115b1561202f57600060fd8281548110611e4f57611e4f612bcd565b600091825260208220015460ff80546001600160a01b0390921693509084908110611e7c57611e7c612bcd565b60009182526020909120015490506001600160a01b0382161580611e9e575080155b15611eb557611eac83612be3565b92505050611e17565b80871015611ec457505061202f565b6001600160a01b038216600090815260fe602052604081208054839290611eec908490612b9e565b925050819055508060fc6000828254611f059190612b9e565b90915550611f1590508188612b9e565b965060fd8381548110611f2a57611f2a612bcd565b600091825260209091200180546001600160a01b031916905560ff805484908110611f5757611f57612bcd565b6000918252602082200155611f6b83612be3565b9250611f8e826001600160a01b0316600090815260c96020526040902054151590565b15611fa457611f9d82826124ef565b5050611e17565b6000611fb2838360016122bb565b905080611fcb57611fc383836124ef565b505050611e17565b82878681518110611fde57611fde612bcd565b60200260200101906001600160a01b031690816001600160a01b0316815250508186868151811061201157612011612bcd565b602090810291909101015261202585612be3565b9450505050611e17565b60fb8190558351600090612044908490612b9e565b90508015612053578285528284525b7fe69d325558610ba73c441901deb46d7f251108348dc5dc9447e8866774c12edc8585604051612084929190612f39565b60405180910390a1505050505050565b6033546001600160a01b03163314610d1d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161082a565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b609754604051635361637360e01b8152600481018390526000916001600160a01b031690635361637390602401602060405180830381865afa15801561218a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ae9190612e65565b90506121bd8383836001612575565b6121c88383836126b8565b505050565b609854604051635361637360e01b8152600481018390526000916001600160a01b031690635361637390602401602060405180830381865afa158015612217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223b9190612e65565b905061224a8383836000612575565b609754604051631a1ac52760e21b81526001600160a01b038581166004830152602482018490529091169063686b149c90604401600060405180830381600087803b15801561229857600080fd5b505af11580156122ac573d6000803e3d6000fd5b505050506121c88383836126b8565b6000838183156122db576000806000808886612710f19250612331915050565b6040516001600160a01b038316908690600081818185875af1925050503d8060008114612324576040519150601f19603f3d011682016040523d82523d6000602084013e612329565b606091505b509093505050505b9392505050565b600054610100900460ff1661235f5760405162461bcd60e51b815260040161082a90612f99565b610d1d61278c565b600054610100900460ff1661238e5760405162461bcd60e51b815260040161082a90612f99565b60fa8190556040805160008152602081018390527f3bb2da990d30b0bc98e39d632b60814d66b3bae55947927dec7a75719de577de910160405180910390a150565b600054610100900460ff166123f75760405162461bcd60e51b815260040161082a90612f99565b609980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16610d1d5760405162461bcd60e51b815260040161082a90612f99565b6001600160a01b038216600090815260c96020526040902054156121c85760405162461bcd60e51b815260206004820152603b60248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20726563656976657260448201527f206973206d61726b656420666f72206d616e75616c20636c61696d0000000000606482015260840161082a565b806124d56116f8565b106124e4576121c882826127bc565b6121c8838383612904565b8060c860008282546125019190612fe4565b90915550506001600160a01b038216600090815260c960205260408120805483929061252e908490612fe4565b90915550506040518181526001600160a01b038316907fd3a9686144ad9a6d4bfdad99cc4083c7de8e5a5a155fb9c2325a492d5bc83ba59060200160405180910390a25050565b61257d610cde565b83101561259c5760405162461bcd60e51b815260040161082a90612e7e565b6098546097546040516340c10f1960e01b81526001600160a01b039182166004820152602481018590529116906340c10f1990604401600060405180830381600087803b1580156125ec57600080fd5b505af1158015612600573d6000803e3d6000fd5b50506097546040516340c10f1960e01b81526001600160a01b0388811660048301526024820187905290911692506340c10f199150604401600060405180830381600087803b15801561265257600080fd5b505af1158015612666573d6000803e3d6000fd5b5050604080518681526020810186905284151593506001600160a01b03881692507f3df45cb339f96ae4bdb793efcb6e22100dd0dc4fd739a4ee2033fe67ea35af96910160405180910390a350505050565b610190546000906126d3906001600160a01b031684836122bb565b9050806127485760405162461bcd60e51b815260206004820152603d60248201527f466c6f775374616b696e67506f6f6c3a206661696c656420746f2073656e642060448201527f7374616b656420464c4f5720746f206272696467652061646472657373000000606482015260840161082a565b61019054604080516001600160a01b039092168252602082018590527f11ff5db12742675bcf3ccb786e43022f6e18f2a9e7600e406ee808724bf208809101611271565b600054610100900460ff166127b35760405162461bcd60e51b815260040161082a90612f99565b610d1d336120ee565b806127c56116f8565b10156128395760405162461bcd60e51b815260206004820152603860248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2062616c616e63652060448201527f6c657373207468616e207265776172647320616d6f756e740000000000000000606482015260840161082a565b6000612847838360006122bb565b9050806128bc5760405162461bcd60e51b815260206004820152603960248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206661696c6564207460448201527f6f2073656e64207265776172647320746f20636c61696d657200000000000000606482015260840161082a565b826001600160a01b03167f5910001d6ca4285091c4077cf57bcd244645b77d84a6658b65d31a34f2c9f2d4836040516128f791815260200190565b60405180910390a2505050565b801580159061291b57506001600160a01b03821615155b6129795760405162461bcd60e51b815260206004820152602960248201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a207a65726f20696e7060448201526875742076616c75657360b81b606482015260840161082a565b8060fc600082825461298b9190612fe4565b909155505060fd805460018082019092557f9346ac6dd7de6b96975fec380d4d994c4c12e6a8897544f22915316cc6cca2800180546001600160a01b0319166001600160a01b03851690811790915560ff805492830190557fe08ec2af2cfc251225e1968fd6ca21e4044f129bffa95bac3503be8bdb30a367909101829055600090815260fe602052604081208054839290612a28908490612fe4565b92505081905550816001600160a01b0316836001600160a01b03167f8bd920adc14654a74328c96f8873d60e6836c1e81079be3a620ec760602dcd8c83604051612a7491815260200190565b60405180910390a3505050565b6001600160a01b03811681146108c257600080fd5b600060208284031215612aa857600080fd5b813561233181612a81565b600081518084526020808501945080840160005b83811015612ae357815187529582019590820190600101612ac7565b509495945050505050565b6020815260006123316020830184612ab3565b600060208284031215612b1357600080fd5b5035919050565b60008060408385031215612b2d57600080fd5b8235612b3881612a81565b946020939093013593505050565b600080600060608486031215612b5b57600080fd5b8335612b6681612a81565b9250602084013591506040840135612b7d81612a81565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b81810381811115612bb157612bb1612b88565b92915050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201612bf557612bf5612b88565b5060010190565b6000816000190483118215151615612c1657612c16612b88565b500290565b600060208284031215612c2d57600080fd5b815161233181612a81565b6020808252602f908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a206f6e6c7920676f7660408201526e195c9b985b98d948185b1b1bddd959608a1b606082015260800190565b60208082526039908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2073656e646572206960408201527f73206d61726b656420666f72206d616e75616c20636c61696d00000000000000606082015260800190565b634e487b7160e01b600052601260045260246000fd5b600082612d0957612d09612ce4565b500690565b6020808252603a908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2076616c756520736860408201527f6f756c64206265206d756c7469706c696564206f662067776569000000000000606082015260800190565b600082612d7a57612d7a612ce4565b500490565b600067ffffffffffffffff80831681851681830481118215151615612da657612da6612b88565b02949350505050565b600060208284031215612dc157600080fd5b8151801515811461233157600080fd5b6020808252602e908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a20626f6e642073746160408201526d1ada5b99c81a5cc81c185d5cd95960921b606082015260800190565b60208082526026908201527f43616e6e6f742073657420466c6f7720627269646765206164647265737320746040820152656f207a65726f60d01b606082015260800190565b600060208284031215612e7757600080fd5b5051919050565b6020808252603d908201527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2076616c7565206d7560408201527f73742062652067726561746572207468616e206d696e20616d6f756e74000000606082015260800190565b602080825260409082018190527f4c6971756964546f6b656e5374616b696e67506f6f6c3a2063616e6e6f742075908201527f6e7374616b65206d6f7265207468616e2068617665206f6e2061646472657373606082015260800190565b604080825283519082018190526000906020906060840190828701845b82811015612f7b5781516001600160a01b031684529284019290840190600101612f56565b50505083810382850152612f8f8186612ab3565b9695505050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b80820180821115612bb157612bb1612b8856fea2646970667358221220189cda6fcf77f2946547d3bcd07c218051e7520a82b8cd28041ca4a2bf56ae9664736f6c63430008100033","name":"FlowStakingPool","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"default","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"@ankr.com/contracts/earn/EarnConfig.sol","source_code":"// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/IEarnConfig.sol\";\n\ncontract EarnConfig is Initializable, IEarnConfig {\n\n    event ConsensusAddressChanged(address prevValue, address newValue);\n    event GovernanceAddressChanged(address prevValue, address newValue);\n    event TreasuryAddressChanged(address prevValue, address newValue);\n    event SwapFeeRatioChanged(uint16 prevValue, uint16 newValue);\n    event BondStakingPaused(uint256 block);\n    event BondStakingUnpaused(uint256 block);\n\n    struct Slot0 {\n        address consensusAddress;\n        address governanceAddress;\n        address treasuryAddress;\n        uint16 swapFeeRatio;\n        bool bondStakingPaused;\n    }\n\n    Slot0 internal _slot0;\n\n    function initialize(\n        address consensusAddress,\n        address governanceAddress,\n        address treasuryAddress,\n        uint16 swapFeeRatio,\n        bool bondStakingPaused\n    ) external initializer {\n        _slot0.consensusAddress = consensusAddress;\n        emit ConsensusAddressChanged(address(0x00), consensusAddress);\n        _slot0.governanceAddress = governanceAddress;\n        emit GovernanceAddressChanged(address(0x00), governanceAddress);\n        _slot0.treasuryAddress = treasuryAddress;\n        emit TreasuryAddressChanged(address(0x00), treasuryAddress);\n        _slot0.swapFeeRatio = swapFeeRatio;\n        emit SwapFeeRatioChanged(0, swapFeeRatio);\n        _slot0.bondStakingPaused = bondStakingPaused;\n        if (bondStakingPaused) {\n            emit BondStakingPaused(block.number);\n        } else {\n            emit BondStakingUnpaused(block.number);\n        }\n    }\n\n    modifier onlyGovernance() virtual {\n        require(msg.sender == address(_slot0.governanceAddress), \"EarnConfig: only governance\");\n        _;\n    }\n\n    function getConsensusAddress() external view override returns (address) {\n        return _slot0.consensusAddress;\n    }\n\n    function setConsensusAddress(address newValue) external override onlyGovernance {\n        address prevValue = _slot0.consensusAddress;\n        _slot0.consensusAddress = newValue;\n        emit ConsensusAddressChanged(prevValue, newValue);\n    }\n\n    function getGovernanceAddress() external view override returns (address) {\n        return _slot0.governanceAddress;\n    }\n\n    function setGovernanceAddress(address newValue) external override onlyGovernance {\n        address prevValue = _slot0.governanceAddress;\n        _slot0.governanceAddress = newValue;\n        emit GovernanceAddressChanged(prevValue, newValue);\n    }\n\n    function getTreasuryAddress() external view override returns (address) {\n        return _slot0.treasuryAddress;\n    }\n\n    function setTreasuryAddress(address newValue) external override onlyGovernance {\n        address prevValue = _slot0.treasuryAddress;\n        _slot0.treasuryAddress = newValue;\n        emit TreasuryAddressChanged(prevValue, newValue);\n    }\n\n    function getSwapFeeRatio() external view override returns (uint16) {\n        return _slot0.swapFeeRatio;\n    }\n\n    function setSwapFeeRatio(uint16 newValue) external override onlyGovernance {\n        uint16 prevValue = _slot0.swapFeeRatio;\n        _slot0.swapFeeRatio = newValue;\n        emit SwapFeeRatioChanged(prevValue, newValue);\n    }\n\n    function pauseBondStaking() external override onlyGovernance {\n        _slot0.bondStakingPaused = true;\n        emit BondStakingPaused(block.number);\n    }\n\n    function unpauseBondStaking() external override onlyGovernance {\n        _slot0.bondStakingPaused = false;\n        emit BondStakingUnpaused(block.number);\n    }\n\n    function isBondStakingPaused() external view override returns (bool) {\n        return _slot0.bondStakingPaused;\n    }\n}"},{"file_path":"@ankr.com/contracts/earn/LiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\n\nimport \"../interfaces/ICertificateToken.sol\";\nimport \"../interfaces/IBearingToken.sol\";\nimport \"../interfaces/IEarnConfig.sol\";\nimport \"../interfaces/ILiquidTokenStakingPool.sol\";\n\nabstract contract LiquidTokenStakingPool is\n    ILiquidTokenStakingPool,\n    OwnableUpgradeable,\n    ReentrancyGuardUpgradeable\n{\n    /**\n     * @dev external contracts\n     */\n    IBearingToken internal _bearingToken;\n    ICertificateToken internal _certificateToken;\n    IEarnConfig internal _earnConfig;\n\n    /**\n     * @dev compact size, should be multiplied by 1 gwei\n     */\n    uint64 private minimumStake;\n\n    uint64 private _minimumUnstake;\n\n    // reserve some gap for the future upgrades\n    uint256[50 - 5] private __reserved;\n\n    modifier onlyGovernance() virtual {\n        require(\n            msg.sender == _earnConfig.getGovernanceAddress(),\n            \"LiquidTokenStakingPool: only governance allowed\"\n        );\n        _;\n    }\n\n    modifier onlyConsensus() virtual {\n        require(\n            msg.sender == _earnConfig.getConsensusAddress(),\n            \"LiquidTokenStakingPool: only consensus allowed\"\n        );\n        _;\n    }\n\n    modifier bondStakingUnpaused() virtual {\n        require(\n            !_earnConfig.isBondStakingPaused(),\n            \"LiquidTokenStakingPool: bond staking is paused\"\n        );\n        _;\n    }\n\n    function __LiquidTokenStakingPool_init(\n        IEarnConfig earnConfig\n    ) internal onlyInitializing {\n        _earnConfig = earnConfig;\n    }\n\n    receive() external payable virtual {\n        emit Received(msg.sender, msg.value);\n    }\n\n    function setBearingToken(\n        address newValue\n    ) external override onlyGovernance {\n        address prevValue = address(_bearingToken);\n        _bearingToken = IBearingToken(newValue);\n        emit BearingTokenChanged(prevValue, newValue);\n    }\n\n    function setCertificateToken(\n        address newValue\n    ) external override onlyGovernance {\n        address prevValue = address(_certificateToken);\n        _certificateToken = ICertificateToken(newValue);\n        emit CertificateTokenChanged(prevValue, newValue);\n    }\n\n    function setMinimumStake(\n        uint256 newValue\n    ) external virtual override onlyGovernance {\n        require(\n            newValue % 1 gwei == 0,\n            \"LiquidTokenStakingPool: value should be multiplied of gwei\"\n        );\n        uint256 prevValue = getMinStake();\n        minimumStake = uint64(newValue / 1 gwei);\n        require(\n            minimumStake * 1 gwei == newValue,\n            \"LiquidTokenStakingPool: overflow\"\n        );\n        emit MinimumStakeChanged(prevValue, newValue);\n    }\n\n    function setMinimumUnstake(\n        uint256 newValue\n    ) external virtual override onlyGovernance {\n        require(\n            newValue % 1 gwei == 0,\n            \"LiquidTokenStakingPool: value should be multiplied of gwei\"\n        );\n        uint256 prevValue = getMinUnstake();\n        _minimumUnstake = uint64(newValue / 1 gwei);\n        require(\n            _minimumUnstake * 1 gwei == newValue,\n            \"LiquidTokenStakingPool: overflow\"\n        );\n        emit MinimumUnstakeChanged(prevValue, newValue);\n    }\n\n    function getMinStake() public view virtual override returns (uint256) {\n        return uint256(minimumStake) * 1 gwei;\n    }\n\n    function getMinUnstake() public view virtual override returns (uint256) {\n        return uint256(_minimumUnstake) * 1 gwei;\n    }\n\n    function stakeBonds()\n        external\n        payable\n        override\n        nonReentrant\n        bondStakingUnpaused\n    {\n        _stakeBonds(msg.sender, msg.value);\n    }\n\n    function stakeCerts() external payable override nonReentrant {\n        _stakeCerts(msg.sender, msg.value);\n    }\n\n    function _stakeCerts(address staker, uint256 amount) internal {\n        uint256 shares = _certificateToken.bondsToShares(amount);\n        _stake(staker, amount, shares, false);\n        _bearingToken.unlockSharesFor(staker, shares);\n        _afterStake(staker, amount, shares);\n    }\n\n    function _stakeBonds(address staker, uint256 amount) internal {\n        uint256 shares = _bearingToken.bondsToShares(amount);\n        _stake(staker, amount, shares, true);\n        _afterStake(staker, amount, shares);\n    }\n\n    function _stake(\n        address staker,\n        uint256 amount,\n        uint256 shares,\n        bool isRebasing\n    ) internal {\n        _beforeStake(staker, amount, shares);\n        require(\n            amount >= getMinStake(),\n            \"LiquidTokenStakingPool: value must be greater than min amount\"\n        );\n        _certificateToken.mint(address(_bearingToken), shares);\n        _bearingToken.mint(staker, shares);\n        emit Staked(staker, amount, shares, isRebasing);\n    }\n\n    function _beforeStake(\n        address account,\n        uint256 amount,\n        uint256 shares\n    ) internal virtual {}\n\n    function _afterStake(\n        address account,\n        uint256 amount,\n        uint256 shares\n    ) internal virtual {}\n\n    /**\n     * @notice burns amount of bearing from msg.sender\n     * @notice returns native or ERC20 token immediately or via queue\n     * @param receiverAddress address for receiving unstaked funds\n     * @param amount amount of bearing token to unstake\n     */\n    function _unstakeBondsFor(\n        address receiverAddress,\n        uint256 amount\n    ) internal {\n        address ownerAddress = msg.sender;\n        uint256 shares = _bearingToken.bondsToShares(amount);\n        require(\n            amount >= getMinUnstake(),\n            \"LiquidTokenStakingPool: value must be greater than min amount\"\n        );\n        require(\n            _bearingToken.balanceOf(ownerAddress) >= amount,\n            \"LiquidTokenStakingPool: cannot unstake more than have on address\"\n        );\n        _beforeUnstake(ownerAddress, receiverAddress, amount);\n        _certificateToken.burn(address(_bearingToken), shares);\n        _bearingToken.burn(ownerAddress, shares);\n        _afterUnstake(ownerAddress, receiverAddress, amount);\n        emit Unstaked(ownerAddress, receiverAddress, amount, shares, true);\n    }\n\n    /**\n     * @notice Burns amount of certificate from msg.sender\n     * @notice Returns native token immediately or via queue\n     * @param receiverAddress address for receiving unstaked funds\n     * @param shares amount of certificate token to unstake\n     */\n    function _unstakeCertsFor(\n        address receiverAddress,\n        uint256 shares\n    ) internal {\n        address ownerAddress = msg.sender;\n        uint256 amount = _certificateToken.sharesToBonds(shares);\n        require(\n            amount >= getMinUnstake(),\n            \"LiquidTokenStakingPool: value must be greater than min amount\"\n        );\n        require(\n            _certificateToken.balanceOf(ownerAddress) >= shares,\n            \"LiquidTokenStakingPool: cannot unstake more than have on address\"\n        );\n        _beforeUnstake(ownerAddress, receiverAddress, amount);\n        _certificateToken.burn(ownerAddress, shares);\n        _afterUnstake(ownerAddress, receiverAddress, amount);\n        emit Unstaked(ownerAddress, receiverAddress, amount, shares, false);\n    }\n\n    /**\n     * @dev Might be checked whether the amount matches some restrictions\n     * @dev Might be checked the account for manual witdrawal requests\n     */\n    function _beforeUnstake(\n        address ownerAddress,\n        address receiverAddress,\n        uint256 amount\n    ) internal virtual {}\n\n    /**\n     * @dev Might be set for pending (queue)\n     * @dev Might be distributed immediately\n     */\n    function _afterUnstake(\n        address ownerAddress,\n        address receiverAddress,\n        uint256 amount\n    ) internal virtual {}\n\n    /**\n     * @dev Unsafe transfer with gas limit if necessary\n     * @notice The solution was received from bnb bounty program\n     */\n    function _unsafeTransfer(\n        address receiverAddress,\n        uint256 amount,\n        bool limit\n    ) internal virtual returns (bool) {\n        address payable wallet = payable(receiverAddress);\n        bool success;\n        if (limit) {\n            assembly {\n                success := call(10000, wallet, amount, 0, 0, 0, 0)\n            }\n            return success;\n        }\n        (success, ) = wallet.call{value: amount}(\"\");\n        return success;\n    }\n\n    function getFreeBalance() public view virtual returns (uint256) {\n        return address(this).balance;\n    }\n\n    /**\n     * @return Bearing token address\n     * @return Certificate token address\n     */\n    function getTokens() external view virtual returns (address, address) {\n        return (address(_bearingToken), address(_certificateToken));\n    }\n}\n"},{"file_path":"@ankr.com/contracts/earn/extension/ImmediateLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.16;\n\nimport \"../LiquidTokenStakingPool.sol\";\n\ncontract ImmediateLiquidTokenStakingPool is LiquidTokenStakingPool {\n    /**\n     * Events\n     */\n    event ImmediatelyDistributed(\n        address indexed receiverAddress,\n        uint256 amount\n    );\n\n    // reserve some gap for the future upgrades\n    uint256[50] private __reserved;\n\n    function __ImmediatePool_init() internal onlyInitializing {}\n\n    /**\n     * @notice Safe distribution\n     * @dev Checks the result of _unsafeTransfer()\n     */\n    function _distributeRewards(address receiverAddress, uint256 amount)\n        internal\n    {\n        require(\n            getFreeBalance() >= amount,\n            \"LiquidTokenStakingPool: balance less than rewards amount\"\n        );\n        bool result = _unsafeTransfer(receiverAddress, amount, false);\n        require(\n            result,\n            \"LiquidTokenStakingPool: failed to send rewards to claimer\"\n        );\n        emit ImmediatelyDistributed(receiverAddress, amount);\n    }\n}\n"},{"file_path":"@ankr.com/contracts/earn/extension/ManualClaimLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.16;\n\nimport \"../LiquidTokenStakingPool.sol\";\nimport \"../../interfaces/IManualClaimLiquidTokenStakingPool.sol\";\n\ncontract ManualClaimLiquidTokenStakingPool is\n    LiquidTokenStakingPool,\n    IManualClaimLiquidTokenStakingPool\n{\n    uint256 internal _stashedForManualClaims;\n    mapping(address => uint256) internal _manualClaims; // address => amount\n\n    // reserve some gap for the future upgrades\n    uint256[50 - 2] private __reserved;\n\n    modifier notMarkerForManualClaim() virtual {\n        require(\n            _manualClaims[msg.sender] == 0,\n            \"LiquidTokenStakingPool: sender is marked for manual claim\"\n        );\n        _;\n    }\n\n    function __ManualClaimPool_init() internal onlyInitializing {}\n\n    /**\n     * @dev Checks whether receiverAddress is marked for manual claim\n     * @dev Might be overridden\n     */\n    function _beforeUnstake(\n        address /* ownerAddress */,\n        address receiverAddress,\n        uint256 /* amount */\n    ) internal virtual override(LiquidTokenStakingPool) {\n        require(\n            !isMarkedForManualClaim(receiverAddress),\n            \"LiquidTokenStakingPool: receiver is marked for manual claim\"\n        );\n    }\n\n    function unstakeBonds(\n        uint256 amount\n    )\n        external\n        virtual\n        nonReentrant\n        notMarkerForManualClaim\n        bondStakingUnpaused\n    {\n        _unstakeBondsFor(msg.sender, amount);\n    }\n\n    function unstakeBondsFor(\n        address receiverAddress,\n        uint256 amount\n    ) external virtual nonReentrant bondStakingUnpaused {\n        _unstakeBondsFor(receiverAddress, amount);\n    }\n\n    function unstakeCerts(\n        uint256 shares\n    ) external virtual notMarkerForManualClaim nonReentrant {\n        _unstakeCertsFor(msg.sender, shares);\n    }\n\n    function unstakeCertsFor(\n        address receiverAddress,\n        uint256 shares\n    ) external virtual nonReentrant {\n        _unstakeCertsFor(receiverAddress, shares);\n    }\n\n    function claimManually(address receiverAddress) external nonReentrant {\n        require(\n            receiverAddress != address(0),\n            \"LiquidTokenStakingPool: zero address\"\n        );\n        uint256 amount = _manualClaims[receiverAddress];\n        require(\n            amount > 0,\n            \"LiquidTokenStakingPool: not marked for manual claim\"\n        );\n        require(\n            address(this).balance >= getStashedForManualClaims(),\n            \"LiquidTokenStakingPool: insufficient pool balance\"\n        );\n        _stashedForManualClaims -= amount;\n        _manualClaims[receiverAddress] = 0;\n        // _markedForManualClaim[id] = address(0);\n        bool result = _unsafeTransfer(receiverAddress, amount, false);\n        require(\n            result,\n            \"LiquidTokenStakingPool: failed to send rewards to receiverAddress\"\n        );\n        emit RewardsClaimed(receiverAddress, msg.sender, amount);\n    }\n\n    function _setForManualClaim(address claimer, uint256 amount) internal {\n        _stashedForManualClaims += amount;\n        _manualClaims[claimer] += amount;\n\n        emit ManualClaimExpected(claimer, amount);\n    }\n\n    function isMarkedForManualClaim(\n        address claimer\n    ) public view returns (bool) {\n        return _manualClaims[claimer] != uint256(0);\n    }\n\n    function getForManualClaimOf(\n        address claimer\n    ) public view returns (uint256) {\n        return _manualClaims[claimer];\n    }\n\n    function getStashedForManualClaims() public view returns (uint256) {\n        return _stashedForManualClaims;\n    }\n\n    /// @dev Might be overridden\n    function getFreeBalance() public view virtual override returns (uint256) {\n        return\n            address(this).balance < getStashedForManualClaims()\n                ? 0\n                : address(this).balance - getStashedForManualClaims();\n    }\n}\n"},{"file_path":"@ankr.com/contracts/earn/extension/MixedLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.16;\n\nimport \"../LiquidTokenStakingPool.sol\";\nimport \"./ManualClaimLiquidTokenStakingPool.sol\";\nimport \"./QueueLiquidTokenStakingPool.sol\";\nimport \"./ImmediateLiquidTokenStakingPool.sol\";\nimport \"./ReferralLiquidTokenStakingPool.sol\";\n\ncontract MixedLiquidTokenStakingPool is\n    QueueLiquidTokenStakingPool,\n    ImmediateLiquidTokenStakingPool,\n    ReferralLiquidTokenStakingPool\n{\n    // reserve some gap for the future upgrades\n    uint256[50] private __reserved;\n\n    function __MixedPool_init() internal onlyInitializing {}\n\n    /**\n     * @dev Checks the receiverAddress for existing manual requests\n     * @dev Might be overridden\n     */\n    function _beforeUnstake(\n        address /* ownerAddress */,\n        address receiverAddress,\n        uint256 /* amount */\n    )\n        internal\n        virtual\n        override(LiquidTokenStakingPool, ManualClaimLiquidTokenStakingPool)\n    {\n        require(\n            !isMarkedForManualClaim(receiverAddress),\n            \"LiquidTokenStakingPool: receiver is marked for manual claim\"\n        );\n    }\n\n    /**\n     * @dev Checks the pool balance and then sends the amount immediately\n     * @dev If the pool balance is less than the amount puts into the queue\n     * @dev Might be overridden\n     */\n    function _afterUnstake(\n        address ownerAddress,\n        address receiverAddress,\n        uint256 amount\n    ) internal virtual override {\n        // unstake immediately\n        if (getFreeBalance() >= amount) {\n            _distributeRewards(receiverAddress, amount);\n            return;\n        }\n        // pending unstake\n        _addIntoQueue(ownerAddress, receiverAddress, amount);\n    }\n\n    /**\n     * @dev Might be overridden\n     */\n    function getFreeBalance()\n        public\n        view\n        virtual\n        override(ManualClaimLiquidTokenStakingPool, LiquidTokenStakingPool)\n        returns (uint256)\n    {\n        return\n            address(this).balance < getStashedForManualClaims()\n                ? 0\n                : address(this).balance - getStashedForManualClaims();\n    }\n}\n"},{"file_path":"@ankr.com/contracts/earn/extension/QueueLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.14;\n\nimport \"./ManualClaimLiquidTokenStakingPool.sol\";\nimport \"../../interfaces/IQueueLiquidTokenStakingPool.sol\";\n\ncontract QueueLiquidTokenStakingPool is\n    ManualClaimLiquidTokenStakingPool,\n    IQueueLiquidTokenStakingPool\n{\n    uint256 internal _DISTRIBUTE_GAS_LIMIT;\n\n    uint256 internal _pendingGap;\n\n    uint256 internal _pendingTotalUnstakes;\n    address[] internal _pendingClaimers;\n    mapping(address => uint256) internal _pendingClaimerUnstakes;\n\n    uint256[] internal _pendingRequests;\n\n    // reserve some gap for the future upgrades\n    uint256[50 - 6] private __reserved;\n\n    function __QueuePool_init(\n        uint256 distributeGasLimit\n    ) internal onlyInitializing {\n        _DISTRIBUTE_GAS_LIMIT = distributeGasLimit;\n        emit DistributeGasLimitChanged(0, distributeGasLimit);\n    }\n\n    function setDistributeGasLimit(uint256 newValue) external onlyGovernance {\n        uint256 prevValue = _DISTRIBUTE_GAS_LIMIT;\n        _DISTRIBUTE_GAS_LIMIT = newValue;\n\n        emit DistributeGasLimitChanged(prevValue, newValue);\n    }\n\n    function getDistributeGasLimit() public view returns (uint256) {\n        return _DISTRIBUTE_GAS_LIMIT;\n    }\n\n    function _addIntoQueue(\n        address owner,\n        address claimer,\n        uint256 amount\n    ) internal {\n        require(\n            amount != 0 && claimer != address(0),\n            \"LiquidTokenStakingPool: zero input values\"\n        );\n        // each new request is placed at the end of the queue\n        _pendingTotalUnstakes += amount;\n        _pendingClaimers.push(claimer);\n        _pendingRequests.push(amount);\n        _pendingClaimerUnstakes[claimer] += amount;\n        emit PendingUnstake(owner, claimer, amount);\n    }\n\n    function _distributePendingRewards() internal {\n        require(\n            _DISTRIBUTE_GAS_LIMIT > 0,\n            \"LiquidTokenStakingPool: DISTRIBUTE_GAS_LIMIT is not set\"\n        );\n        uint256 poolBalance = getFreeBalance();\n        address[] memory claimers = new address[](\n            _pendingClaimers.length - _pendingGap\n        );\n        uint256[] memory amounts = new uint256[](\n            _pendingClaimers.length - _pendingGap\n        );\n        uint256 j = 0;\n        uint256 i = _pendingGap;\n\n        while (\n            i < _pendingClaimers.length &&\n            poolBalance > 0 &&\n            gasleft() > _DISTRIBUTE_GAS_LIMIT\n        ) {\n            address claimer = _pendingClaimers[i];\n            uint256 toDistribute = _pendingRequests[i];\n            if (claimer == address(0) || toDistribute == 0) {\n                ++i;\n                continue;\n            }\n\n            if (poolBalance < toDistribute) {\n                break;\n            }\n\n            _pendingClaimerUnstakes[claimer] -= toDistribute;\n            _pendingTotalUnstakes -= toDistribute;\n            poolBalance -= toDistribute;\n            delete _pendingClaimers[i];\n            delete _pendingRequests[i];\n            ++i;\n            // if claimer for manual claim then add the request like manual\n            if (isMarkedForManualClaim(claimer)) {\n                _setForManualClaim(claimer, toDistribute);\n                continue;\n            }\n\n            bool success = _unsafeTransfer(claimer, toDistribute, true);\n            if (!success) {\n                _setForManualClaim(claimer, toDistribute);\n                continue;\n            }\n            claimers[j] = claimer;\n            amounts[j] = toDistribute;\n            ++j;\n        }\n        _pendingGap = i;\n        /* decrease arrays */\n        uint256 removeCells = claimers.length - j;\n        if (removeCells > 0) {\n            assembly {\n                mstore(claimers, j)\n            }\n            assembly {\n                mstore(amounts, j)\n            }\n        }\n\n        emit RewardsDistributed(claimers, amounts);\n    }\n\n    function getTotalPendingUnstakes() public view returns (uint256) {\n        return _pendingTotalUnstakes;\n    }\n\n    function getPendingRequestsOf(\n        address claimer\n    ) public view returns (uint256[] memory) {\n        uint256 j;\n        uint256[] memory unstakes = new uint256[](\n            _pendingClaimers.length - _pendingGap\n        );\n        for (uint256 i = _pendingGap; i < _pendingClaimers.length; i++) {\n            if (_pendingClaimers[i] == claimer) {\n                unstakes[j] = _pendingRequests[i];\n                ++j;\n            }\n        }\n        uint256 removeCells = unstakes.length - j;\n        if (removeCells > 0) {\n            assembly {\n                mstore(unstakes, j)\n            }\n        }\n        return unstakes;\n    }\n\n    function getPendingUnstakesOf(\n        address claimer\n    ) public view returns (uint256) {\n        return _pendingClaimerUnstakes[claimer];\n    }\n}\n"},{"file_path":"@ankr.com/contracts/earn/extension/ReferralLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\nimport \"../LiquidTokenStakingPool.sol\";\nimport \"../../interfaces/IReferralLiquidTokenStakingPool.sol\";\n\ncontract ReferralLiquidTokenStakingPool is\n    LiquidTokenStakingPool,\n    IReferralLiquidTokenStakingPool\n{\n    function __ReferralPool_init() internal onlyInitializing {}\n\n    /**\n     * @dev Overrides LiquidTokenStakingPool#stakeBonds with additional param\n     * @param code is a partner code for the Ankr Referral program\n     */\n    function stakeBondsWithCode(bytes32 code)\n        external\n        payable\n        override\n        nonReentrant\n    {\n        _stakeBonds(msg.sender, msg.value);\n        emit ReferralCode(code);\n    }\n\n    /**\n     * @dev Overrides LiquidTokenStakingPool#stakeCerts with additional param\n     * @param code is a partner code for the Ankr Referral program\n     */\n    function stakeCertsWithCode(bytes32 code)\n        external\n        payable\n        override\n        nonReentrant\n    {\n        _stakeCerts(msg.sender, msg.value);\n        emit ReferralCode(code);\n    }\n}\n"},{"file_path":"@ankr.com/contracts/interfaces/IBearingToken.sol","source_code":"// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.7;\n\nimport \"./ICertificateToken.sol\";\n\ninterface IBearingToken is ICertificateToken {\n\n    function lockShares(uint256 shares) external;\n\n    function lockSharesFor(address account, uint256 shares) external;\n\n    function unlockShares(uint256 shares) external;\n\n    function unlockSharesFor(address account, uint256 shares) external;\n\n    function totalSharesSupply() external view returns (uint256);\n}"},{"file_path":"@ankr.com/contracts/interfaces/ICertificateToken.sol","source_code":"// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface ICertificateToken is IERC20Upgradeable {\n\n    function sharesToBonds(uint256 amount) external view returns (uint256);\n\n    function bondsToShares(uint256 amount) external view returns (uint256);\n\n    function ratio() external view returns (uint256);\n\n    function isRebasing() external pure returns (bool);\n\n    function mint(address account, uint256 amount) external;\n\n    function burn(address account, uint256 amount) external;\n}"},{"file_path":"@ankr.com/contracts/interfaces/IEarnConfig.sol","source_code":"// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.7;\n\nimport \"./IGovernable.sol\";\n\ninterface IEarnConfig is IGovernable {\n\n    function getConsensusAddress() external view returns (address);\n\n    function setConsensusAddress(address newValue) external;\n\n    function getGovernanceAddress() external view override returns (address);\n\n    function setGovernanceAddress(address newValue) external;\n\n    function getTreasuryAddress() external view returns (address);\n\n    function setTreasuryAddress(address newValue) external;\n\n    function getSwapFeeRatio() external view returns (uint16);\n\n    function setSwapFeeRatio(uint16 newValue) external;\n\n    function pauseBondStaking() external;\n\n    function unpauseBondStaking() external;\n\n    function isBondStakingPaused() external view returns (bool);\n}"},{"file_path":"@ankr.com/contracts/interfaces/IGovernable.sol","source_code":"// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.7;\n\ninterface IGovernable {\n\n    function getGovernanceAddress() external view returns (address);\n}"},{"file_path":"@ankr.com/contracts/interfaces/ILiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\ninterface ILiquidTokenStakingPool {\n    event BearingTokenChanged(address prevValue, address newValue);\n\n    event CertificateTokenChanged(address prevValue, address newValue);\n\n    event MinimumStakeChanged(uint256 prevValue, uint256 newValue);\n\n    event MinimumUnstakeChanged(uint256 prevValue, uint256 newValue);\n\n    event Staked(\n        address indexed staker,\n        uint256 amount,\n        uint256 shares,\n        bool indexed isRebasing\n    );\n\n    event Unstaked(\n        address indexed ownerAddress,\n        address indexed receiverAddress,\n        uint256 amount,\n        uint256 shares,\n        bool indexed isRebasing\n    );\n\n    event Received(address indexed from, uint256 value);\n\n    function setBearingToken(address newValue) external;\n\n    function setCertificateToken(address newValue) external;\n\n    function setMinimumStake(uint256 newValue) external;\n\n    function setMinimumUnstake(uint256 newValue) external;\n\n    function stakeBonds() external payable;\n\n    function stakeCerts() external payable;\n\n    function getFreeBalance() external view returns (uint256);\n\n    function getMinStake() external view returns (uint256);\n\n    function getMinUnstake() external view returns (uint256);\n}\n"},{"file_path":"@ankr.com/contracts/interfaces/IManualClaimLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\ninterface IManualClaimLiquidTokenStakingPool {\n    /**\n     * Events\n     */\n    event RewardsClaimed(\n        address indexed receiverAddress,\n        address claimer,\n        uint256 amount\n    );\n\n    event ManualClaimExpected(address indexed claimer, uint256 amount);\n}\n"},{"file_path":"@ankr.com/contracts/interfaces/IQueueLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\ninterface IQueueLiquidTokenStakingPool {\n    /**\n     * Events\n     */\n    event PendingUnstake(\n        address indexed ownerAddress,\n        address indexed receiverAddress,\n        uint256 amount\n    );\n\n    event RewardsDistributed(address[] claimers, uint256[] amounts);\n\n    event ManualDistributeExpected(\n        address indexed claimer,\n        uint256 amount,\n        uint256 indexed id\n    );\n\n    event DistributeGasLimitChanged(uint256 prevValue, uint256 newValue);\n}\n"},{"file_path":"@ankr.com/contracts/interfaces/IReferralLiquidTokenStakingPool.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\ninterface IReferralLiquidTokenStakingPool {\n    /**\n     * Events\n     */\n    event ReferralCode(bytes32 indexed code);\n\n    /**\n     * Methods\n     */\n    function stakeBondsWithCode(bytes32 code) external payable;\n\n    function stakeCertsWithCode(bytes32 code) external payable;\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == _ENTERED;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"solidity/contracts/config/FlowStakingConfig.sol","source_code":"// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.16;\n\nimport {EarnConfig} from \"@ankr.com/contracts/earn/EarnConfig.sol\";\n\ncontract FlowStakingConfig is EarnConfig {\n    // /// @dev https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializing_the_implementation_contract\n    // /// @custom:oz-upgrades-unsafe-allow constructor\n    // constructor() {\n    //     _disableInitializers();\n    // }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"BearingTokenChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"CertificateTokenChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"DistributeGasLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"FlowBridgeAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"bridge","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FlowBridgeFunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiverAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ImmediatelyDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ManualClaimExpected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ManualDistributeExpected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinimumStakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinimumUnstakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ownerAddress","type":"address"},{"indexed":true,"internalType":"address","name":"receiverAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PendingUnstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"ReferralCode","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiverAddress","type":"address"},{"indexed":false,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"claimers","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"RewardsDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"bool","name":"isRebasing","type":"bool"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ownerAddress","type":"address"},{"indexed":true,"internalType":"address","name":"receiverAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"bool","name":"isRebasing","type":"bool"}],"name":"Unstaked","type":"event"},{"inputs":[{"internalType":"address","name":"receiverAddress","type":"address"}],"name":"claimManually","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributePendingRewards","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getDistributeGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFlowBridgeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"getForManualClaimOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFreeBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinUnstake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"getPendingRequestsOf","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"getPendingUnstakesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStashedForManualClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokens","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalPendingUnstakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IEarnConfig","name":"earnConfig","type":"address"},{"internalType":"uint256","name":"distributeGasLimit","type":"uint256"},{"internalType":"address","name":"_flowBridgeAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"isMarkedForManualClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverStrayFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setBearingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setCertificateToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setDistributeGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setFlowBridgeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinimumStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinimumUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeBonds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"stakeBondsWithCode","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"stakeCerts","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"stakeCertsWithCode","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstakeBonds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstakeBondsFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"unstakeCerts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"unstakeCertsFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}