{"file_path":"contracts/strategies/idle/IdleCreditVault.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.10;\n\nimport \"../../interfaces/IIdleCDOStrategy.sol\";\nimport \"../../interfaces/IERC20Detailed.sol\";\n\nimport '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IIdleCDOEpochVariant {\n  function isEpochRunning() external view returns (bool);\n  function epochEndDate() external view returns (uint256);\n  function expectedEpochInterest() external view returns (uint256);\n  function pendingWithdrawFees() external view returns (uint256);\n  function fee() external view returns (uint256);\n  function getContractValue() external view returns (uint256);\n  function defaulted() external view returns (bool);\n}\n\nerror NotAllowed();\n\ncontract IdleCreditVault is\n  Initializable,\n  OwnableUpgradeable,\n  ERC20Upgradeable,\n  ReentrancyGuardUpgradeable,\n  IIdleCDOStrategy\n{\n  using SafeERC20Upgradeable for IERC20Detailed;\n\n  /// @notice underlying token address (pool currency for Clearpool)\n  address public override token;\n  /// @notice decimals of the underlying asset\n  uint256 public override tokenDecimals;\n  /// @notice one underlying token\n  uint256 public override oneToken;\n  /// @notice underlying ERC20 token contract (pool currency for Clearpool)\n  IERC20Detailed public underlyingToken;\n  /// @notice address of the IdleCDO\n  address public idleCDO;\n  /// @notice one year, used to calculate the APR\n  uint256 public constant YEAR = 365 days;\n  /// @notice latest saved apr, already scaled to include the buffer period\n  uint256 public lastApr;\n  /// @notice address of the borrower\n  address public borrower;\n  /// @notice address of the manager\n  address public manager;\n  /// @notice user withdraw requests\n  mapping (address => uint256) public withdrawsRequests;\n  /// @notice user instant withdraw requests\n  mapping (address => uint256) public instantWithdrawsRequests;\n  /// @notice total withdraw requests\n  uint256 public pendingWithdraws;\n  /// @notice pending instant withdraw requests\n  uint256 public pendingInstantWithdraws;\n  /// @notice counter for epoch deposits\n  uint256 public totEpochDeposits;\n  /// @notice flag to allow transfers\n  bool public canTransfer;\n  /// @notice last withdraw request epoch for a user\n  mapping (address => uint256) public lastWithdrawRequest;\n  /// @notice current epoch number\n  uint256 public epochNumber;\n  /// @notice unscaled apr\n  uint256 public unscaledApr;\n  /// @notice constant representing a 100% fee used for accounting\n  uint256 private constant FULL_ALLOC = 100_000;\n  /// @notice total principal for APR=0 requests in the current epoch\n  uint256 public apr0TotalPrincipal;\n  struct Apr0UserData {\n    uint256 principal;\n    uint256 principalEpoch;\n    uint256 settledPrincipal;\n    uint256 settledInterest;\n  }\n  /// @notice APR=0 withdraw data per user\n  mapping (address => Apr0UserData) public apr0Users;\n  /// @notice net APR=0 interest rate per epoch, scaled by 1e18\n  mapping (uint256 => uint256) public apr0RateByEpoch;\n  /// @notice default maximum allowed scaled apr\n  uint256 public constant DEFAULT_MAX_APR = 20e18;\n  /// @notice maximum allowed scaled apr, 0 disables the cap\n  uint256 public maxApr;\n\n  /// @custom:oz-upgrades-unsafe-allow constructor\n  constructor() {\n    token = address(1);\n  }\n\n  /// @notice can be only called once\n  /// @param _underlyingToken address of the underlying token (pool currency)\n  function initialize(\n    address _underlyingToken,\n    address _owner,\n    address _manager,\n    address _borrower,\n    string memory borrowerName,\n    uint256 _apr\n  ) public virtual initializer {\n    OwnableUpgradeable.__Ownable_init();\n    ReentrancyGuardUpgradeable.__ReentrancyGuard_init();\n    require(token == address(0), \"Token is already initialized\");\n\n    //----- // -------//\n    token = _underlyingToken;\n    underlyingToken = IERC20Detailed(token);\n    tokenDecimals = underlyingToken.decimals();\n    oneToken = 10**(tokenDecimals);\n    borrower = _borrower;\n    manager = _manager;\n    maxApr = DEFAULT_MAX_APR;\n    // on the first setup we set the lastApr equal to the unscaledApr\n    lastApr = _apr;\n    unscaledApr = _apr;\n\n    // name will be like: Pareto Credit Vault Borrower\n    // symbol will be like: Borrower\n    ERC20Upgradeable.__ERC20_init(\n      _concat(string(\"Pareto Credit Vault \"), borrowerName),\n      borrowerName\n    );\n    //------//-------//\n\n    transferOwnership(_owner);\n  }\n\n  /// @notice strategy token decimals\n  /// @dev equal to underlying token decimals\n  /// @return number of decimals\n  function decimals() public view override returns (uint8) {\n    return uint8(tokenDecimals);\n  }\n\n  /// @notice strategy token address\n  function strategyToken() external view override returns (address) {\n    return address(this);\n  }\n\n  /// @notice return strategy token price which is always 1\n  /// @return price in underlyings\n  function price() public view virtual override returns (uint256) {\n    return oneToken;\n  }\n\n  /// @notice current fixed apr for the epoch\n  function getApr() external view returns (uint256) {\n    return lastApr;\n  }\n\n  /// @notice set manager address\n  /// @param _manager address of the new manager\n  function setManager(address _manager) external onlyOwner {\n    manager = _manager;\n  }\n\n  /// @notice set borrower address\n  /// @param _borrower address of the new borrower\n  function setBorrower(address _borrower) external onlyOwner {\n    require(_borrower != address(0), \"IS_0\");\n    borrower = _borrower;\n  }\n\n  /// @notice set maximum allowed scaled apr, 0 disables the cap\n  /// @param _maxApr new max apr\n  function setMaxApr(uint256 _maxApr) external onlyOwner {\n    maxApr = _maxApr;\n  }\n\n  /// @notice set both the scaled and unscaled apr\n  /// @dev only cdo and manager can set the apr.\n  /// @param _unscaledApr unscaled apr\n  /// @param _apr scaled apr\n  function setAprs(uint256 _unscaledApr, uint256 _apr) external {\n    unscaledApr = _unscaledApr;\n    // here we also check that msg.sender is allowed\n    setApr(_apr);\n  }\n\n  /// @notice set the fixed apr\n  /// @dev only cdo and manager can set the apr. If manager manually set apr from \n  /// here it will not be scaled to include the buffer period\n  function setApr(uint256 _apr) public {\n    address _cdo = idleCDO;\n\n    // if cdo is not yet set we skip the check (this can happen only during the setup)\n    if (_cdo != address(0)) {\n      if (msg.sender != _cdo && msg.sender != manager) revert NotAllowed();\n    }\n    uint256 _maxApr = maxApr;\n    if (_maxApr != 0 && _apr > _maxApr) revert NotAllowed();\n    lastApr = _apr;\n  }\n\n  /// @notice request withdraw of underlying token from the vault\n  /// @dev we don't burn strategy tokens here, but we increase the withdraw requests\n  /// @param _amount number of tokens claimable by the user\n  /// @param _user address of the user\n  /// @param _principal principal amount backing the withdraw request\n  function requestWithdraw(uint256 _amount, address _user, uint256 _principal) external {\n    _onlyIdleCDO();\n    if (_amount == 0) return;\n    // burn strategy tokens from cdo (we don't burn future interest here, only the principal)\n    _burn(msg.sender, _principal);\n    // mint equal amount of strategy tokens to the user as receipt (interest included), useful in case of default\n    _mint(_user, _amount);\n    // Global amount that stopEpoch must source from borrower/strategy for all pending receipts.\n    pendingWithdraws += _amount;\n    // save the epoch of the last withdraw request (buffer + epochDuration is 1 epoch)\n    lastWithdrawRequest[_user] = epochNumber;\n    // APR=0 requests keep separate accounting and settle interest at stopEpoch.\n    // `_amount` here is the post-management-fee principal bucket for that flow.\n    if (unscaledApr == 0) {\n      _requestWithdrawApr0(_amount, _user);\n    } else {\n      // increase the withdraw requests for the user\n      withdrawsRequests[_user] += _amount;\n    }\n  }\n\n  /// @notice claim the withdraw request\n  /// @dev we burn the strategy tokens and transfer the underlying tokens\n  /// @param _user address of the user\n  /// @return amount number of tokens claimed\n  function claimWithdrawRequest(address _user) external returns (uint256 amount) {\n    _onlyIdleCDO();\n    // User should wait at least an epoch before claiming the withdraw. Once the epoch is over user can withdraw \n    // at any time even if a new epoch started. \n    // So if epochNumber is the same as the last withdraw request then we revert. Epoch number is increased at stopEpoch\n    // NOTE: If a user does not claim a withdraw request and instead requests another withdraw, he will have to wait\n    // for another epoch to claim both requests.\n    // NOTE 2: if borrower defaults, old withdraw requests can still be claimed\n    if (IIdleCDOEpochVariant(idleCDO).epochEndDate() != 0 && (epochNumber <= lastWithdrawRequest[_user])) {\n      revert NotAllowed();\n    }\n    // settle APR=0 requests once the related epoch has ended\n    _settleApr0(_user);\n    Apr0UserData storage _apr0User = apr0Users[_user];\n    // Claim includes:\n    // - settled APR0 principal from finalized epochs\n    // - still-open APR0 principal: if pool-close mode was used (_interest == 1), IdleCDO sets\n    //   epochEndDate = 0 and claims can be immediate, while _settleApr0 can still skip settlement\n    //   for the current request epoch (reqEpoch >= epochNumber).\n    // - settled APR0 interest\n    uint256 normalAmount = withdrawsRequests[_user];\n    uint256 apr0PrincipalAmount = _apr0User.settledPrincipal + _apr0User.principal;\n    uint256 apr0InterestAmount = _apr0User.settledInterest;\n    amount = normalAmount + apr0PrincipalAmount + apr0InterestAmount;\n    // burn strategy tokens 1:1 with the principal only (normal amount already includes interest)\n    _burn(_user, normalAmount + apr0PrincipalAmount);\n    withdrawsRequests[_user] = 0;\n    lastWithdrawRequest[_user] = 0;\n    if (apr0PrincipalAmount != 0 || apr0InterestAmount != 0) {\n      delete apr0Users[_user];\n    }\n    underlyingToken.safeTransfer(_user, amount);\n  }\n\n  /// @notice request instant withdraw of underlying token from the vault\n  /// @dev we burn strategy tokens here, and we increase the instant withdraw requests\n  /// @param _amount number of tokens to withdraw\n  /// @param _user address of the user\n  function requestInstantWithdraw(uint256 _amount, address _user) external {\n    _onlyIdleCDO();\n    // burn strategy tokens from cdo\n    _burn(msg.sender, _amount);\n  \n    // mint equal amount of strategy tokens to the user as receipt, useful in case of default\n    _mint(_user, _amount);\n\n    // increase the instant withdraw requests for the user\n    instantWithdrawsRequests[_user] += _amount;\n    // increase the total instant withdraw requests\n    pendingInstantWithdraws += _amount;\n  }\n\n  /// @notice claim the instant withdraw request\n  /// @dev we transfer the underlying tokens\n  /// @param _user address of the user\n  function claimInstantWithdrawRequest(address _user) external {\n    _onlyIdleCDO();\n    uint256 amount = instantWithdrawsRequests[_user];\n    // burn strategy tokens from user\n    _burn(_user, amount);\n\n    instantWithdrawsRequests[_user] = 0;\n    underlyingToken.safeTransfer(_user, amount);\n  }\n\n  /// @notice collect the instant withdraw funds\n  /// @dev only IdleCDO can call this function\n  /// @param _amount number of tokens to collect\n  function collectInstantWithdrawFunds(uint256 _amount) external {\n    _onlyIdleCDO();\n    pendingInstantWithdraws -= _amount;\n    underlyingToken.safeTransferFrom(idleCDO, address(this), _amount);\n  }\n\n  /// @notice collect the withdraw funds\n  /// @dev only IdleCDO can call this function\n  /// @param _amount number of tokens to collect\n  function collectWithdrawFunds(uint256 _amount) external {\n    _onlyIdleCDO();\n    pendingWithdraws -= _amount;\n    underlyingToken.safeTransferFrom(idleCDO, address(this), _amount);\n  }\n\n  /// @notice compute and apply APR=0 epoch deltas for stopEpoch\n  /// @param _interest stopEpoch override interest (0 = expected epoch interest, 1 = repay all)\n  /// @return _expInterest stopEpoch interest after APR0 adjustments\n  /// @return _adjPendingWithdrawFees pending withdraw fees after APR0 adjustments\n  function prepareStopEpochWithApr0(uint256 _interest) external returns (uint256 _expInterest, uint256 _adjPendingWithdrawFees) {\n    _onlyIdleCDO();\n    IIdleCDOEpochVariant _cdo = IIdleCDOEpochVariant(idleCDO);\n    uint256 _pendingFees = _cdo.pendingWithdrawFees();\n    uint256 _tvl = _cdo.getContractValue();\n    _expInterest = _interest > 1 ? _interest : _cdo.expectedEpochInterest();\n    _adjPendingWithdrawFees = _pendingFees;\n    // Principal currently waiting for withdraw that was requested while APR was 0,\n    // net of the upfront management fee charged at request time.\n    uint256 _principal = apr0TotalPrincipal;\n\n    // Fast path: no APR0 accounting needed.\n    if (_principal == 0) {\n      return (_expInterest, _adjPendingWithdrawFees);\n    }\n    // APR0 principal is only valid while APR is 0 for that request lifecycle.\n    if (unscaledApr != 0) {\n      revert NotAllowed();\n    }\n\n    uint256 _apr0NetInterest;\n    // APR0 allocation is computed only when stopEpoch receives a real override interest.\n    // _expectedInterest == 1 is the \"request all funds back\" sentinel and is handled in IdleCDO.\n    if (_expInterest > 1 && _expInterest > _pendingFees) {\n      // Remove already booked withdraw fees from the interest base before splitting.\n      uint256 _interestNetOfFees = _expInterest - _pendingFees;\n      // Total principal used for the pro-rata split:\n      // IdleCDO TVL (which excludes APR0 requested principal) + APR0 principal bucket.\n      uint256 _totalPrincipalForSplit = _tvl + _principal;\n      if (_totalPrincipalForSplit != 0) {\n        // APR0 users get a pro-rata share of realized interest.\n        uint256 _apr0InterestGross = _interestNetOfFees * _principal / _totalPrincipalForSplit;\n        if (_apr0InterestGross != 0) {\n          // Same fee model as normal withdraw interest.\n          uint256 _apr0Fee = _apr0InterestGross * _cdo.fee() / FULL_ALLOC;\n          _apr0NetInterest = _apr0InterestGross - _apr0Fee;\n          _adjPendingWithdrawFees += _apr0Fee;\n          _expInterest -= _apr0NetInterest;\n        }\n      }\n    }\n\n    // Finalize one-epoch APR0 interest for current epoch only.\n    if (_apr0NetInterest != 0) {\n      // Funds owed to withdraw requesters increase by APR0 net interest.\n      pendingWithdraws += _apr0NetInterest;\n      // Save per-epoch net rate; each APR0 request accrues exactly once on its request epoch.\n      apr0RateByEpoch[epochNumber] = (_apr0NetInterest * 1e18) / _principal;\n    }\n    // Close current APR0 bucket so it cannot accrue again on later stopEpoch calls.\n    apr0TotalPrincipal = 0;\n  }\n\n  /// @notice settle APR=0 requests for a user once their epoch is finalized\n  /// @param _user address of the user\n  function _settleApr0(address _user) internal {\n    Apr0UserData storage _apr0User = apr0Users[_user];\n    uint256 _principal = _apr0User.principal;\n    if (_principal == 0) {\n      return;\n    }\n    uint256 _reqEpoch = _apr0User.principalEpoch;\n    // Settle only after stopEpoch bumped epochNumber (ie after one full wait epoch).\n    if (_reqEpoch >= epochNumber) {\n      return;\n    }\n    // Move principal from \"open APR0 bucket\" to \"settled bucket\" (same principal, not duplicated).\n    _apr0User.settledPrincipal += _principal;\n    uint256 _rate = apr0RateByEpoch[_reqEpoch];\n    if (_rate != 0) {\n      // Convert per-epoch rate to claimable underlying interest.\n      _apr0User.settledInterest += (_principal * _rate) / 1e18;\n    }\n    _apr0User.principal = 0;\n    _apr0User.principalEpoch = 0;\n  }\n\n  function _requestWithdrawApr0(uint256 _amount, address _user) internal {\n    // Settle any previous APR0 request first, then start/update current epoch bucket.\n    _settleApr0(_user);\n    Apr0UserData storage _apr0User = apr0Users[_user];\n    if (_apr0User.principal == 0) {\n      _apr0User.principalEpoch = epochNumber;\n    }\n    _apr0User.principal += _amount;\n    // Epoch-level APR0 principal used only to compute stopEpoch APR0 pro-rata interest.\n    apr0TotalPrincipal += _amount;\n  }\n\n  /// @notice Send funds to the IdleCDO\n  /// @param _amount number of underlyings to transfer\n  function sendInterestAndDeposits(uint256 _amount) external {\n    _onlyIdleCDO();\n    IERC20Detailed(token).safeTransfer(idleCDO, _amount);\n  }\n\n  /// @notice Burn strategy tokens from the CDO\n  /// @param _amount number of strategy tokens (1:1 with underlyings) to burn\n  function burnStrategyTokens(uint256 _amount) external {\n    _onlyIdleCDO();\n    _burn(msg.sender, _amount);\n  }\n\n  /// @notice Get funds from IdleCDO and mint strategy tokens. Funds are not sent to the borrower here\n  /// @param _amount number of underlyings to transfer\n  function deposit(uint256 _amount)\n    external\n    virtual\n    override\n    returns (uint256) {\n    _onlyIdleCDO();\n    if (_amount > 0) {\n      underlyingToken.safeTransferFrom(msg.sender, address(this), _amount);\n      _mint(msg.sender, _amount);\n    }\n\n    if (IIdleCDOEpochVariant(idleCDO).isEpochRunning()) {\n      // deposit done on stopEpoch (before setting the var to false) so we reset the counter\n      totEpochDeposits = 0;\n      epochNumber += 1;\n    } else {\n      // deposit done between epochs so we increase the counter\n      totEpochDeposits += _amount;\n    }\n\n    return _amount;\n  }\n\n  /// @notice Mint strategy tokens to the CDO without moving underlyings\n  /// @dev Used for mid-epoch deposits that send funds directly to the borrower\n  function mintStrategyTokens(uint256 _amount) external {\n    _onlyIdleCDO();\n    _mint(msg.sender, _amount);\n  }\n  \n  /// @inheritdoc ERC20Upgradeable\n  /// @dev we don't allow transfers of strategy tokens normally, transfers are allowed only after a default\n  function _transfer(address sender, address recipient, uint256 amount) internal virtual override {\n    if (msg.sender != idleCDO && !canTransfer) {\n      revert NotAllowed();\n    }\n    super._transfer(sender, recipient, amount);\n  }\n\n  /// @notice set transferability of strategy tokens after a default\n  /// @dev Manager-controlled manual switch. Transfers stay disabled by default because\n  /// claims are address-bound and moving receipts can sever redeemability.\n  function setCanTransfer(bool _canTransfer) external {\n    if (msg.sender != manager || !IIdleCDOEpochVariant(idleCDO).defaulted()) {\n      revert NotAllowed();\n    }\n    canTransfer = _canTransfer;\n  }\n\n  /// @notice allow to update whitelisted address\n  function setWhitelistedCDO(address _cdo) external onlyOwner {\n    require(_cdo != address(0), \"IS_0\");\n    idleCDO = _cdo;\n  }\n\n  /// @notice Emergency method to rescue funds\n  /// @param _token address of the token to transfer\n  /// @param value amount of `_token` to transfer\n  /// @param _to receiver address\n  function transferToken(address _token, uint256 value, address _to) external onlyOwner {\n    IERC20Detailed(_token).safeTransfer(_to, value);\n  }\n\n  /// @notice Modifier to make sure that caller os only the idleCDO contract\n  function _onlyIdleCDO() internal view {\n    if (msg.sender != idleCDO) {\n      revert NotAllowed();\n    }\n  }\n\n  /// @notice concat 2 strings in a single one\n  /// @param a first string\n  /// @param b second string\n  /// @return new string with a and b concatenated\n  function _concat(string memory a, string memory b) internal pure returns (string memory) {\n    return string(abi.encodePacked(a, b));\n  }\n\n  /// @notice Not used as redeems happens only via requestWithdraw and requestInstantWithdraw\n  function redeem(uint256 _amount)\n    external\n    override\n    returns (uint256) {}\n\n  /// @notice Not used as redeems happens only via requestWithdraw and requestInstantWithdraw\n  function redeemUnderlying(uint256)\n    external\n    returns (uint256) {}\n\n  /// @notice not used in this strategy\n  function pullStkAAVE() \n    external \n    pure \n    override \n    returns (uint256) {}\n\n  /// @notice not used for this strategy\n  function getRewardTokens()\n    external\n    view\n    override\n    returns (address[] memory) {}\n\n  /// @notice not used for this strategy\n  function redeemRewards(bytes calldata)\n    external\n    override\n    returns (uint256[] memory rewards) {}\n}\n","deployed_bytecode":"0x608060405234801561001057600080fd5b50600436106103eb5760003560e01c806397e3f6331161021a578063db006a7511610135578063f16c6bf1116100c8578063f640d50811610097578063f815c4ff1161007c578063f815c4ff1461093b578063fc0c546a14610944578063ff4b7a261461096457600080fd5b8063f640d50814610915578063f7c691871461092857600080fd5b8063f16c6bf1146108d3578063f25b1140146108e6578063f2fde38b146108f9578063f4145a831461090c57600080fd5b8063df68c1a211610104578063df68c1a2146108a1578063e3b34174146108ae578063efda7e07146108c1578063f1578918146108ca57600080fd5b8063db006a751461060b578063dc2a57ac14610835578063dd62ed3e14610848578063df06e3641461088e57600080fd5b8063b6b55f25116101ad578063cdfbe9c51161017c578063cdfbe9c5146107f2578063d0ebdbe7146107f9578063d4090fb81461080c578063d7bff5381461082c57600080fd5b8063b6b55f2514610795578063bb42b773146107a8578063c4f59f9b146107d0578063c762d5f7146107df57600080fd5b8063a457c2d7116101e9578063a457c2d714610746578063a9059cbb14610759578063a9a949681461076c578063acfd7dce1461077557600080fd5b806397e3f633146106c05780639bf5bbe714610715578063a035b1fe14610735578063a27eccc11461073d57600080fd5b8063715018a61161030a5780638b80c89d1161029d5780638fd310ea1161026c5780638fd310ea1461067c57806392093b361461068f57806393f88d4c1461069857806395d89b41146106b857600080fd5b80638b80c89d1461061f5780638da5cb5b146106325780638de021a9146106505780638ec71e0c1461065957600080fd5b80637df1f1b9116102d95780637df1f1b9146105d857806383914540146105f8578063845bc80414610603578063852a12e31461060b57600080fd5b8063715018a6146105a7578063747efea1146105af57806374ae8657146105b557806375ae267d146105c557600080fd5b80633950935111610382578063481c6a7511610351578063481c6a751461052b57806359cee29c1461054b5780635a4f7c531461055e57806370a082311461057157600080fd5b806339509351146104e95780633b97e856146104fc5780633e81a733146105055780633ec701eb1461051857600080fd5b806323b872dd116103be57806323b872dd146104675780632495a5991461047a578063286631fc146104bf578063313ce567146104d457600080fd5b806306fdde03146103f0578063095ea7b31461040e578063112595091461043157806318160ddd1461045f575b600080fd5b6103f8610977565b60405161040591906130db565b60405180910390f35b61042161041c366004613155565b610a09565b6040519015158152602001610405565b61045161043f36600461317f565b60dc6020526000908152604090205481565b604051908152602001610405565b606754610451565b610421610475366004613198565b610a23565b60cc5461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610405565b6104d26104cd3660046131d4565b610a47565b005b60ca5460405160ff9091168152602001610405565b6104216104f7366004613155565b610aba565b61045160ca5481565b6104d261051336600461317f565b610b06565b6104d261052636600461317f565b610b1b565b60d05461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b6104d261055936600461317f565b610b2d565b6104d261056c366004613200565b610c10565b61045161057f366004613222565b73ffffffffffffffffffffffffffffffffffffffff1660009081526065602052604090205490565b6104d2610c22565b3061049a565b6104516801158e460913d0000081565b6104d26105d3366004613252565b610c36565b60cf5461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b6104516301e1338081565b60ce54610451565b61045161061936600461317f565b50600090565b6104d261062d36600461317f565b610d53565b60335473ffffffffffffffffffffffffffffffffffffffff1661049a565b61045160da5481565b61066f61066736600461326f565b606092915050565b60405161040591906132e1565b6104d261068a366004613222565b610d9d565b61045160dd5481565b6104516106a6366004613222565b60d76020526000908152604090205481565b6103f8610e0b565b6106f56106ce366004613222565b60db6020526000908152604090208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610405565b610451610723366004613222565b60d26020526000908152604090205481565b60cb54610451565b61045160cb5481565b610421610754366004613155565b610e1a565b610421610767366004613155565b610ef0565b61045160d35481565b610451610783366004613222565b60d16020526000908152604090205481565b6104516107a336600461317f565b610efe565b6107bb6107b636600461317f565b611015565b60408051928352602083019190915201610405565b60606040516104059190613325565b6104d26107ed366004613222565b61136c565b6000610451565b6104d2610807366004613222565b61143a565b60cd5461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b61045160d95481565b610451610843366004613222565b611489565b610451610856366004613373565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260666020908152604080832093909416825291909152205490565b6104d261089c3660046133cc565b6116bd565b60d6546104219060ff1681565b6104d26108bc36600461317f565b611a74565b61045160d55481565b61045160d45481565b6104d26108e13660046134e6565b611a81565b6104d26108f436600461317f565b611b3c565b6104d2610907366004613222565b611b56565b61045160d85481565b6104d261092336600461350b565b611c0a565b6104d2610936366004613222565b611c33565b61045160ce5481565b60c95461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b6104d261097236600461317f565b611d01565b60606068805461098690613547565b80601f01602080910402602001604051908101604052809291908181526020018280546109b290613547565b80156109ff5780601f106109d4576101008083540402835291602001916109ff565b820191906000526020600020905b8154815290600101906020018083116109e257829003601f168201915b5050505050905090565b600033610a17818585611d33565b60019150505b92915050565b600033610a31858285611ee6565b610a3c858585611fbd565b506001949350505050565b610a4f61202a565b610a59338361207b565b610a638183612241565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d2602052604081208054849290610a989084906135ca565b925050819055508160d46000828254610ab191906135ca565b90915550505050565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610a179082908690610b019087906135ca565b611d33565b610b0e61202a565b610b18338261207b565b50565b610b2361202a565b610b183382612241565b60cd5473ffffffffffffffffffffffffffffffffffffffff168015610bc1573373ffffffffffffffffffffffffffffffffffffffff821614801590610b8a575060d05473ffffffffffffffffffffffffffffffffffffffff163314155b15610bc1576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60dd548015801590610bd257508083115b15610c09576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505060ce55565b60d9829055610c1e81610b2d565b5050565b610c2a612336565b610c3460006123b7565b565b60d05473ffffffffffffffffffffffffffffffffffffffff1633141580610ceb575060cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166369e25ec16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce991906135e2565b155b15610d22576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b610d5b61202a565b8060d36000828254610d6d91906135ff565b909155505060cd5460cc54610b189173ffffffffffffffffffffffffffffffffffffffff9182169116308461242e565b610da561202a565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d26020526040902054610dd5828261207b565b73ffffffffffffffffffffffffffffffffffffffff808316600090815260d2602052604081205560cc54610c1e9116838361250a565b60606069805461098690613547565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610ee3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610a3c8286868403611d33565b600033610a17818585611fbd565b6000610f0861202a565b8115610f3d5760cc54610f339073ffffffffffffffffffffffffffffffffffffffff1633308561242e565b610f3d3383612241565b60cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c5c750986040518163ffffffff1660e01b8152600401602060405180830381865afa158015610faa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fce91906135e2565b15610ff957600060d581905550600160d86000828254610fee91906135ca565b909155506110119050565b8160d5600082825461100b91906135ca565b90915550505b5090565b60008061102061202a565b60cd54604080517f655c9a53000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921691600091839163655c9a53916004808201926020929091908290030181865afa158015611095573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b99190613616565b905060008273ffffffffffffffffffffffffffffffffffffffff1663dc82697c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c9190613616565b9050600186116111aa578273ffffffffffffffffffffffffffffffffffffffff1663e2988e6e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611181573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a59190613616565b6111ac565b855b60da549095509193508391806111c55750505050915091565b60d954156111ff576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018711801561121057508387115b1561130c57600061122185896135ff565b9050600061122f84866135ca565b9050801561130957600081611244868561362f565b61124e919061366c565b90508015611307576000620186a08973ffffffffffffffffffffffffffffffffffffffff1663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb9190613616565b6112d5908461362f565b6112df919061366c565b90506112eb81836135ff565b94506112f7818b6135ca565b9950611303858c6135ff565b9a50505b505b50505b801561135a578060d3600082825461132491906135ca565b9091555082905061133d82670de0b6b3a764000061362f565b611347919061366c565b60d854600090815260dc60205260409020555b600060da819055505050505050915091565b611374612336565b73ffffffffffffffffffffffffffffffffffffffff81166113f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eda9060208082526004908201527f49535f3000000000000000000000000000000000000000000000000000000000604082015260600190565b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611442612336565b60d080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061149361202a565b60cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166375d1497b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611500573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115249190613616565b15801590611559575073ffffffffffffffffffffffffffffffffffffffff8216600090815260d7602052604090205460d85411155b15611590576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61159982612560565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260db6020908152604080832060d190925282205481546002830154929391926115de91906135ca565b6003840154909150806115f183856135ca565b6115fb91906135ca565b94506116108661160b84866135ca565b61207b565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260d16020908152604080832083905560d79091528120558115158061165057508015155b156116905773ffffffffffffffffffffffffffffffffffffffff8616600090815260db602052604081208181556001810182905560028101829055600301555b60cc546116b49073ffffffffffffffffffffffffffffffffffffffff16878761250a565b50505050919050565b600054610100900460ff16158080156116dd5750600054600160ff909116105b806116f75750303b1580156116f7575060005460ff166001145b611783576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610eda565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156117e157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6117e961261d565b6117f16126bc565b60c95473ffffffffffffffffffffffffffffffffffffffff1615611871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546f6b656e20697320616c726561647920696e697469616c697a6564000000006044820152606401610eda565b60c9805473ffffffffffffffffffffffffffffffffffffffff89167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811790925560cc805490911682179055604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa158015611914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119389190613616565b60ca81905561194890600a6137c7565b60cb5560cf805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560d08054928816929091169190911790556801158e460913d0000060dd5560ce82905560d982905560408051808201909152601481527f50617265746f20437265646974205661756c742000000000000000000000000060208201526119ff906119f9908561275b565b84612787565b611a0886611b56565b8015611a6b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b611a7c612336565b60dd55565b611a8961202a565b82611a9357505050565b611a9d338261207b565b611aa78284612241565b8260d36000828254611ab991906135ca565b909155505060d85473ffffffffffffffffffffffffffffffffffffffff8316600090815260d7602052604090205560d954611afd57611af88383612828565b505050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260d1602052604081208054859290611b329084906135ca565b9091555050505050565b611b4461202a565b8060d46000828254610d6d91906135ff565b611b5e612336565b73ffffffffffffffffffffffffffffffffffffffff8116611c01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610eda565b610b18816123b7565b611c12612336565b611af873ffffffffffffffffffffffffffffffffffffffff8416828461250a565b611c3b612336565b73ffffffffffffffffffffffffffffffffffffffff8116611cba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eda9060208082526004908201527f49535f3000000000000000000000000000000000000000000000000000000000604082015260600190565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611d0961202a565b60cd5460c954610b189173ffffffffffffffffffffffffffffffffffffffff91821691168361250a565b73ffffffffffffffffffffffffffffffffffffffff8316611dd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff8216611e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152606660209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611fb75781811015611faa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610eda565b611fb78484848403611d33565b50505050565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314801590611fe8575060d65460ff16155b1561201f576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af8838383612892565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314610c34576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661211e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260656020526040902054818110156121d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff831660008181526065602090815260408083208686039055606780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166122be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610eda565b80606760008282546122d091906135ca565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610eda565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611fb79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612b08565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052611af89084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612488565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260db6020526040902080548061259157505050565b600182015460d85481106125a55750505050565b818360020160008282546125b991906135ca565b9091555050600081815260dc6020526040902054801561260957670de0b6b3a76400006125e6828561362f565b6125f0919061366c565b84600301600082825461260391906135ca565b90915550505b505060008083556001909201919091555050565b600054610100900460ff166126b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c34612c17565b600054610100900460ff16612753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c34612cb7565b606082826040516020016127709291906137d3565b604051602081830303815290604052905092915050565b600054610100900460ff1661281e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c1e8282612d55565b61283181612560565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260db6020526040902080546128655760d85460018201555b8281600001600082825461287991906135ca565b925050819055508260da6000828254611b3291906135ca565b73ffffffffffffffffffffffffffffffffffffffff8316612935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff82166129d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff831660009081526065602052604090205481811015612a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612afb9086815260200190565b60405180910390a3611fb7565b6000612b6a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612e139092919063ffffffff16565b9050805160001480612b8b575080806020019051810190612b8b91906135e2565b611af8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610eda565b600054610100900460ff16612cae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c34336123b7565b600054610100900460ff16612d4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b6001609755565b600054610100900460ff16612dec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b8151612dff90606890602085019061301f565b508051611af890606990602084019061301f565b6060612e228484600085612e2a565b949350505050565b606082471015612ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610eda565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612ee59190613802565b60006040518083038185875af1925050503d8060008114612f22576040519150601f19603f3d011682016040523d82523d6000602084013e612f27565b606091505b5091509150612f3887838387612f43565b979650505050505050565b60608315612fd6578251612fcf5773ffffffffffffffffffffffffffffffffffffffff85163b612fcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610eda565b5081612e22565b612e228383815115612feb5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eda91906130db565b82805461302b90613547565b90600052602060002090601f01602090048101928261304d5760008555613093565b82601f1061306657805160ff1916838001178555613093565b82800160010185558215613093579182015b82811115613093578251825591602001919060010190613078565b506110119291505b80821115611011576000815560010161309b565b60005b838110156130ca5781810151838201526020016130b2565b83811115611fb75750506000910152565b60208152600082518060208401526130fa8160408501602087016130af565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461315057600080fd5b919050565b6000806040838503121561316857600080fd5b6131718361312c565b946020939093013593505050565b60006020828403121561319157600080fd5b5035919050565b6000806000606084860312156131ad57600080fd5b6131b68461312c565b92506131c46020850161312c565b9150604084013590509250925092565b600080604083850312156131e757600080fd5b823591506131f76020840161312c565b90509250929050565b6000806040838503121561321357600080fd5b50508035926020909101359150565b60006020828403121561323457600080fd5b61323d8261312c565b9392505050565b8015158114610b1857600080fd5b60006020828403121561326457600080fd5b813561323d81613244565b6000806020838503121561328257600080fd5b823567ffffffffffffffff8082111561329a57600080fd5b818501915085601f8301126132ae57600080fd5b8135818111156132bd57600080fd5b8660208285010111156132cf57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b81811015613319578351835292840192918401916001016132fd565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561331957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613341565b6000806040838503121561338657600080fd5b61338f8361312c565b91506131f76020840161312c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060008060008060c087890312156133e557600080fd5b6133ee8761312c565b95506133fc6020880161312c565b945061340a6040880161312c565b93506134186060880161312c565b9250608087013567ffffffffffffffff8082111561343557600080fd5b818901915089601f83011261344957600080fd5b81358181111561345b5761345b61339d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156134a1576134a161339d565b816040528281528c60208487010111156134ba57600080fd5b82602086016020830137600060208483010152809650505050505060a087013590509295509295509295565b6000806000606084860312156134fb57600080fd5b833592506131c46020850161312c565b60008060006060848603121561352057600080fd5b6135298461312c565b92506020840135915061353e6040850161312c565b90509250925092565b600181811c9082168061355b57607f821691505b60208210811415613595577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156135dd576135dd61359b565b500190565b6000602082840312156135f457600080fd5b815161323d81613244565b6000828210156136115761361161359b565b500390565b60006020828403121561362857600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156136675761366761359b565b500290565b6000826136a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181815b8085111561370057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156136e6576136e661359b565b808516156136f357918102915b93841c93908002906136ac565b509250929050565b60008261371757506001610a1d565b8161372457506000610a1d565b816001811461373a576002811461374457613760565b6001915050610a1d565b60ff8411156137555761375561359b565b50506001821b610a1d565b5060208310610133831016604e8410600b8410161715613783575081810a610a1d565b61378d83836136a7565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137bf576137bf61359b565b029392505050565b600061323d8383613708565b600083516137e58184602088016130af565b8351908301906137f98183602088016130af565b01949350505050565b600082516138148184602087016130af565b919091019291505056fea26469706673582212208fbc65a6ac27a8fd59fb61177b38967e9aba92de27f0607d4e8eaacb583bcd0264736f6c634300080a0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"london","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":999999},"outputSelection":{"*":{"":["*"],"*":["*"]}}},"optimization_runs":999999,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.10+commit.fc410830","is_verified_via_verifier_alliance":false,"verified_at":"2026-06-18T08:40:45.239435Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x608060405234801561001057600080fd5b5060c980546001600160a01b0319166001179055613854806100336000396000f3fe608060405234801561001057600080fd5b50600436106103eb5760003560e01c806397e3f6331161021a578063db006a7511610135578063f16c6bf1116100c8578063f640d50811610097578063f815c4ff1161007c578063f815c4ff1461093b578063fc0c546a14610944578063ff4b7a261461096457600080fd5b8063f640d50814610915578063f7c691871461092857600080fd5b8063f16c6bf1146108d3578063f25b1140146108e6578063f2fde38b146108f9578063f4145a831461090c57600080fd5b8063df68c1a211610104578063df68c1a2146108a1578063e3b34174146108ae578063efda7e07146108c1578063f1578918146108ca57600080fd5b8063db006a751461060b578063dc2a57ac14610835578063dd62ed3e14610848578063df06e3641461088e57600080fd5b8063b6b55f25116101ad578063cdfbe9c51161017c578063cdfbe9c5146107f2578063d0ebdbe7146107f9578063d4090fb81461080c578063d7bff5381461082c57600080fd5b8063b6b55f2514610795578063bb42b773146107a8578063c4f59f9b146107d0578063c762d5f7146107df57600080fd5b8063a457c2d7116101e9578063a457c2d714610746578063a9059cbb14610759578063a9a949681461076c578063acfd7dce1461077557600080fd5b806397e3f633146106c05780639bf5bbe714610715578063a035b1fe14610735578063a27eccc11461073d57600080fd5b8063715018a61161030a5780638b80c89d1161029d5780638fd310ea1161026c5780638fd310ea1461067c57806392093b361461068f57806393f88d4c1461069857806395d89b41146106b857600080fd5b80638b80c89d1461061f5780638da5cb5b146106325780638de021a9146106505780638ec71e0c1461065957600080fd5b80637df1f1b9116102d95780637df1f1b9146105d857806383914540146105f8578063845bc80414610603578063852a12e31461060b57600080fd5b8063715018a6146105a7578063747efea1146105af57806374ae8657146105b557806375ae267d146105c557600080fd5b80633950935111610382578063481c6a7511610351578063481c6a751461052b57806359cee29c1461054b5780635a4f7c531461055e57806370a082311461057157600080fd5b806339509351146104e95780633b97e856146104fc5780633e81a733146105055780633ec701eb1461051857600080fd5b806323b872dd116103be57806323b872dd146104675780632495a5991461047a578063286631fc146104bf578063313ce567146104d457600080fd5b806306fdde03146103f0578063095ea7b31461040e578063112595091461043157806318160ddd1461045f575b600080fd5b6103f8610977565b60405161040591906130db565b60405180910390f35b61042161041c366004613155565b610a09565b6040519015158152602001610405565b61045161043f36600461317f565b60dc6020526000908152604090205481565b604051908152602001610405565b606754610451565b610421610475366004613198565b610a23565b60cc5461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610405565b6104d26104cd3660046131d4565b610a47565b005b60ca5460405160ff9091168152602001610405565b6104216104f7366004613155565b610aba565b61045160ca5481565b6104d261051336600461317f565b610b06565b6104d261052636600461317f565b610b1b565b60d05461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b6104d261055936600461317f565b610b2d565b6104d261056c366004613200565b610c10565b61045161057f366004613222565b73ffffffffffffffffffffffffffffffffffffffff1660009081526065602052604090205490565b6104d2610c22565b3061049a565b6104516801158e460913d0000081565b6104d26105d3366004613252565b610c36565b60cf5461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b6104516301e1338081565b60ce54610451565b61045161061936600461317f565b50600090565b6104d261062d36600461317f565b610d53565b60335473ffffffffffffffffffffffffffffffffffffffff1661049a565b61045160da5481565b61066f61066736600461326f565b606092915050565b60405161040591906132e1565b6104d261068a366004613222565b610d9d565b61045160dd5481565b6104516106a6366004613222565b60d76020526000908152604090205481565b6103f8610e0b565b6106f56106ce366004613222565b60db6020526000908152604090208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610405565b610451610723366004613222565b60d26020526000908152604090205481565b60cb54610451565b61045160cb5481565b610421610754366004613155565b610e1a565b610421610767366004613155565b610ef0565b61045160d35481565b610451610783366004613222565b60d16020526000908152604090205481565b6104516107a336600461317f565b610efe565b6107bb6107b636600461317f565b611015565b60408051928352602083019190915201610405565b60606040516104059190613325565b6104d26107ed366004613222565b61136c565b6000610451565b6104d2610807366004613222565b61143a565b60cd5461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b61045160d95481565b610451610843366004613222565b611489565b610451610856366004613373565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260666020908152604080832093909416825291909152205490565b6104d261089c3660046133cc565b6116bd565b60d6546104219060ff1681565b6104d26108bc36600461317f565b611a74565b61045160d55481565b61045160d45481565b6104d26108e13660046134e6565b611a81565b6104d26108f436600461317f565b611b3c565b6104d2610907366004613222565b611b56565b61045160d85481565b6104d261092336600461350b565b611c0a565b6104d2610936366004613222565b611c33565b61045160ce5481565b60c95461049a9073ffffffffffffffffffffffffffffffffffffffff1681565b6104d261097236600461317f565b611d01565b60606068805461098690613547565b80601f01602080910402602001604051908101604052809291908181526020018280546109b290613547565b80156109ff5780601f106109d4576101008083540402835291602001916109ff565b820191906000526020600020905b8154815290600101906020018083116109e257829003601f168201915b5050505050905090565b600033610a17818585611d33565b60019150505b92915050565b600033610a31858285611ee6565b610a3c858585611fbd565b506001949350505050565b610a4f61202a565b610a59338361207b565b610a638183612241565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d2602052604081208054849290610a989084906135ca565b925050819055508160d46000828254610ab191906135ca565b90915550505050565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610a179082908690610b019087906135ca565b611d33565b610b0e61202a565b610b18338261207b565b50565b610b2361202a565b610b183382612241565b60cd5473ffffffffffffffffffffffffffffffffffffffff168015610bc1573373ffffffffffffffffffffffffffffffffffffffff821614801590610b8a575060d05473ffffffffffffffffffffffffffffffffffffffff163314155b15610bc1576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60dd548015801590610bd257508083115b15610c09576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505060ce55565b60d9829055610c1e81610b2d565b5050565b610c2a612336565b610c3460006123b7565b565b60d05473ffffffffffffffffffffffffffffffffffffffff1633141580610ceb575060cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166369e25ec16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce991906135e2565b155b15610d22576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b610d5b61202a565b8060d36000828254610d6d91906135ff565b909155505060cd5460cc54610b189173ffffffffffffffffffffffffffffffffffffffff9182169116308461242e565b610da561202a565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d26020526040902054610dd5828261207b565b73ffffffffffffffffffffffffffffffffffffffff808316600090815260d2602052604081205560cc54610c1e9116838361250a565b60606069805461098690613547565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610ee3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610a3c8286868403611d33565b600033610a17818585611fbd565b6000610f0861202a565b8115610f3d5760cc54610f339073ffffffffffffffffffffffffffffffffffffffff1633308561242e565b610f3d3383612241565b60cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c5c750986040518163ffffffff1660e01b8152600401602060405180830381865afa158015610faa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fce91906135e2565b15610ff957600060d581905550600160d86000828254610fee91906135ca565b909155506110119050565b8160d5600082825461100b91906135ca565b90915550505b5090565b60008061102061202a565b60cd54604080517f655c9a53000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921691600091839163655c9a53916004808201926020929091908290030181865afa158015611095573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b99190613616565b905060008273ffffffffffffffffffffffffffffffffffffffff1663dc82697c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c9190613616565b9050600186116111aa578273ffffffffffffffffffffffffffffffffffffffff1663e2988e6e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611181573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a59190613616565b6111ac565b855b60da549095509193508391806111c55750505050915091565b60d954156111ff576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018711801561121057508387115b1561130c57600061122185896135ff565b9050600061122f84866135ca565b9050801561130957600081611244868561362f565b61124e919061366c565b90508015611307576000620186a08973ffffffffffffffffffffffffffffffffffffffff1663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb9190613616565b6112d5908461362f565b6112df919061366c565b90506112eb81836135ff565b94506112f7818b6135ca565b9950611303858c6135ff565b9a50505b505b50505b801561135a578060d3600082825461132491906135ca565b9091555082905061133d82670de0b6b3a764000061362f565b611347919061366c565b60d854600090815260dc60205260409020555b600060da819055505050505050915091565b611374612336565b73ffffffffffffffffffffffffffffffffffffffff81166113f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eda9060208082526004908201527f49535f3000000000000000000000000000000000000000000000000000000000604082015260600190565b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611442612336565b60d080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061149361202a565b60cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166375d1497b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611500573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115249190613616565b15801590611559575073ffffffffffffffffffffffffffffffffffffffff8216600090815260d7602052604090205460d85411155b15611590576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61159982612560565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260db6020908152604080832060d190925282205481546002830154929391926115de91906135ca565b6003840154909150806115f183856135ca565b6115fb91906135ca565b94506116108661160b84866135ca565b61207b565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260d16020908152604080832083905560d79091528120558115158061165057508015155b156116905773ffffffffffffffffffffffffffffffffffffffff8616600090815260db602052604081208181556001810182905560028101829055600301555b60cc546116b49073ffffffffffffffffffffffffffffffffffffffff16878761250a565b50505050919050565b600054610100900460ff16158080156116dd5750600054600160ff909116105b806116f75750303b1580156116f7575060005460ff166001145b611783576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610eda565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156117e157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6117e961261d565b6117f16126bc565b60c95473ffffffffffffffffffffffffffffffffffffffff1615611871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546f6b656e20697320616c726561647920696e697469616c697a6564000000006044820152606401610eda565b60c9805473ffffffffffffffffffffffffffffffffffffffff89167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811790925560cc805490911682179055604080517f313ce567000000000000000000000000000000000000000000000000000000008152905163313ce567916004808201926020929091908290030181865afa158015611914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119389190613616565b60ca81905561194890600a6137c7565b60cb5560cf805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560d08054928816929091169190911790556801158e460913d0000060dd5560ce82905560d982905560408051808201909152601481527f50617265746f20437265646974205661756c742000000000000000000000000060208201526119ff906119f9908561275b565b84612787565b611a0886611b56565b8015611a6b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b611a7c612336565b60dd55565b611a8961202a565b82611a9357505050565b611a9d338261207b565b611aa78284612241565b8260d36000828254611ab991906135ca565b909155505060d85473ffffffffffffffffffffffffffffffffffffffff8316600090815260d7602052604090205560d954611afd57611af88383612828565b505050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260d1602052604081208054859290611b329084906135ca565b9091555050505050565b611b4461202a565b8060d46000828254610d6d91906135ff565b611b5e612336565b73ffffffffffffffffffffffffffffffffffffffff8116611c01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610eda565b610b18816123b7565b611c12612336565b611af873ffffffffffffffffffffffffffffffffffffffff8416828461250a565b611c3b612336565b73ffffffffffffffffffffffffffffffffffffffff8116611cba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eda9060208082526004908201527f49535f3000000000000000000000000000000000000000000000000000000000604082015260600190565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611d0961202a565b60cd5460c954610b189173ffffffffffffffffffffffffffffffffffffffff91821691168361250a565b73ffffffffffffffffffffffffffffffffffffffff8316611dd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff8216611e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152606660209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611fb75781811015611faa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610eda565b611fb78484848403611d33565b50505050565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314801590611fe8575060d65460ff16155b1561201f576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af8838383612892565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314610c34576040517f3d693ada00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661211e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260656020526040902054818110156121d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff831660008181526065602090815260408083208686039055606780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166122be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610eda565b80606760008282546122d091906135ca565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610eda565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611fb79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612b08565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052611af89084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612488565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260db6020526040902080548061259157505050565b600182015460d85481106125a55750505050565b818360020160008282546125b991906135ca565b9091555050600081815260dc6020526040902054801561260957670de0b6b3a76400006125e6828561362f565b6125f0919061366c565b84600301600082825461260391906135ca565b90915550505b505060008083556001909201919091555050565b600054610100900460ff166126b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c34612c17565b600054610100900460ff16612753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c34612cb7565b606082826040516020016127709291906137d3565b604051602081830303815290604052905092915050565b600054610100900460ff1661281e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c1e8282612d55565b61283181612560565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260db6020526040902080546128655760d85460018201555b8281600001600082825461287991906135ca565b925050819055508260da6000828254611b3291906135ca565b73ffffffffffffffffffffffffffffffffffffffff8316612935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff82166129d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff831660009081526065602052604090205481811015612a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610eda565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612afb9086815260200190565b60405180910390a3611fb7565b6000612b6a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612e139092919063ffffffff16565b9050805160001480612b8b575080806020019051810190612b8b91906135e2565b611af8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610eda565b600054610100900460ff16612cae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b610c34336123b7565b600054610100900460ff16612d4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b6001609755565b600054610100900460ff16612dec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610eda565b8151612dff90606890602085019061301f565b508051611af890606990602084019061301f565b6060612e228484600085612e2a565b949350505050565b606082471015612ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610eda565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612ee59190613802565b60006040518083038185875af1925050503d8060008114612f22576040519150601f19603f3d011682016040523d82523d6000602084013e612f27565b606091505b5091509150612f3887838387612f43565b979650505050505050565b60608315612fd6578251612fcf5773ffffffffffffffffffffffffffffffffffffffff85163b612fcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610eda565b5081612e22565b612e228383815115612feb5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eda91906130db565b82805461302b90613547565b90600052602060002090601f01602090048101928261304d5760008555613093565b82601f1061306657805160ff1916838001178555613093565b82800160010185558215613093579182015b82811115613093578251825591602001919060010190613078565b506110119291505b80821115611011576000815560010161309b565b60005b838110156130ca5781810151838201526020016130b2565b83811115611fb75750506000910152565b60208152600082518060208401526130fa8160408501602087016130af565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461315057600080fd5b919050565b6000806040838503121561316857600080fd5b6131718361312c565b946020939093013593505050565b60006020828403121561319157600080fd5b5035919050565b6000806000606084860312156131ad57600080fd5b6131b68461312c565b92506131c46020850161312c565b9150604084013590509250925092565b600080604083850312156131e757600080fd5b823591506131f76020840161312c565b90509250929050565b6000806040838503121561321357600080fd5b50508035926020909101359150565b60006020828403121561323457600080fd5b61323d8261312c565b9392505050565b8015158114610b1857600080fd5b60006020828403121561326457600080fd5b813561323d81613244565b6000806020838503121561328257600080fd5b823567ffffffffffffffff8082111561329a57600080fd5b818501915085601f8301126132ae57600080fd5b8135818111156132bd57600080fd5b8660208285010111156132cf57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b81811015613319578351835292840192918401916001016132fd565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561331957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613341565b6000806040838503121561338657600080fd5b61338f8361312c565b91506131f76020840161312c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060008060008060c087890312156133e557600080fd5b6133ee8761312c565b95506133fc6020880161312c565b945061340a6040880161312c565b93506134186060880161312c565b9250608087013567ffffffffffffffff8082111561343557600080fd5b818901915089601f83011261344957600080fd5b81358181111561345b5761345b61339d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156134a1576134a161339d565b816040528281528c60208487010111156134ba57600080fd5b82602086016020830137600060208483010152809650505050505060a087013590509295509295509295565b6000806000606084860312156134fb57600080fd5b833592506131c46020850161312c565b60008060006060848603121561352057600080fd5b6135298461312c565b92506020840135915061353e6040850161312c565b90509250925092565b600181811c9082168061355b57607f821691505b60208210811415613595577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156135dd576135dd61359b565b500190565b6000602082840312156135f457600080fd5b815161323d81613244565b6000828210156136115761361161359b565b500390565b60006020828403121561362857600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156136675761366761359b565b500290565b6000826136a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181815b8085111561370057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156136e6576136e661359b565b808516156136f357918102915b93841c93908002906136ac565b509250929050565b60008261371757506001610a1d565b8161372457506000610a1d565b816001811461373a576002811461374457613760565b6001915050610a1d565b60ff8411156137555761375561359b565b50506001821b610a1d565b5060208310610133831016604e8410600b8410161715613783575081810a610a1d565b61378d83836136a7565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156137bf576137bf61359b565b029392505050565b600061323d8383613708565b600083516137e58184602088016130af565b8351908301906137f98183602088016130af565b01949350505050565b600082516138148184602087016130af565b919091019291505056fea26469706673582212208fbc65a6ac27a8fd59fb61177b38967e9aba92de27f0607d4e8eaacb583bcd0264736f6c634300080a0033","name":"IdleCreditVault","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"london","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"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 {Initializable} from \"../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/ERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC20_init_unchained(name_, symbol_);\n    }\n\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\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[45] private __gap;\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20PermitUpgradeable {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n    using AddressUpgradeable for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20PermitUpgradeable token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n    }\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/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/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 {Initializable} from \"../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/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../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    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\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":"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol","source_code":"pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n    function factory() external pure returns (address);\n    function WETH() external pure returns (address);\n\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint amountADesired,\n        uint amountBDesired,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountA, uint amountB, uint liquidity);\n    function addLiquidityETH(\n        address token,\n        uint amountTokenDesired,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint liquidity,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountA, uint amountB);\n    function removeLiquidityETH(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountToken, uint amountETH);\n    function removeLiquidityWithPermit(\n        address tokenA,\n        address tokenB,\n        uint liquidity,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline,\n        bool approveMax, uint8 v, bytes32 r, bytes32 s\n    ) external returns (uint amountA, uint amountB);\n    function removeLiquidityETHWithPermit(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline,\n        bool approveMax, uint8 v, bytes32 r, bytes32 s\n    ) external returns (uint amountToken, uint amountETH);\n    function swapExactTokensForTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n    function swapTokensForExactTokens(\n        uint amountOut,\n        uint amountInMax,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n        external\n        payable\n        returns (uint[] memory amounts);\n    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n        external\n        returns (uint[] memory amounts);\n    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n        external\n        returns (uint[] memory amounts);\n    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n        external\n        payable\n        returns (uint[] memory amounts);\n\n    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n"},{"file_path":"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol","source_code":"pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n    function removeLiquidityETHSupportingFeeOnTransferTokens(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountETH);\n    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline,\n        bool approveMax, uint8 v, bytes32 r, bytes32 s\n    ) external returns (uint amountETH);\n\n    function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external;\n    function swapExactETHForTokensSupportingFeeOnTransferTokens(\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external payable;\n    function swapExactTokensForETHSupportingFeeOnTransferTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external;\n}\n"},{"file_path":"contracts/interfaces/IERC20Detailed.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.10;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IERC20Detailed is IERC20Upgradeable {\n  function name() external view returns(string memory);\n  function symbol() external view returns(string memory);\n  function decimals() external view returns(uint256);\n}\n"},{"file_path":"contracts/interfaces/IIdleCDOStrategy.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.10;\n\ninterface IIdleCDOStrategy {\n  function strategyToken() external view returns(address);\n  function token() external view returns(address);\n  function tokenDecimals() external view returns(uint256);\n  function oneToken() external view returns(uint256);\n  function redeemRewards(bytes calldata _extraData) external returns(uint256[] memory);\n  function pullStkAAVE() external returns(uint256);\n  function price() external view returns(uint256);\n  function getRewardTokens() external view returns(address[] memory);\n  function deposit(uint256 _amount) external returns(uint256);\n  // _amount in `strategyToken`\n  function redeem(uint256 _amount) external returns(uint256);\n  // _amount in `token`\n  function redeemUnderlying(uint256 _amount) external returns(uint256);\n  function getApr() external view returns(uint256);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","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":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_MAX_APR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"apr0RateByEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apr0TotalPrincipal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"apr0Users","outputs":[{"internalType":"uint256","name":"principal","type":"uint256"},{"internalType":"uint256","name":"principalEpoch","type":"uint256"},{"internalType":"uint256","name":"settledPrincipal","type":"uint256"},{"internalType":"uint256","name":"settledInterest","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"borrower","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnStrategyTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"claimInstantWithdrawRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"claimWithdrawRequest","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"collectInstantWithdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"collectWithdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epochNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"idleCDO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_underlyingToken","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_manager","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"string","name":"borrowerName","type":"string"},{"internalType":"uint256","name":"_apr","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"instantWithdrawsRequests","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastWithdrawRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintStrategyTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oneToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingInstantWithdraws","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingWithdraws","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_interest","type":"uint256"}],"name":"prepareStopEpochWithApr0","outputs":[{"internalType":"uint256","name":"_expInterest","type":"uint256"},{"internalType":"uint256","name":"_adjPendingWithdrawFees","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pullStkAAVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"redeemRewards","outputs":[{"internalType":"uint256[]","name":"rewards","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"requestInstantWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_principal","type":"uint256"}],"name":"requestWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"sendInterestAndDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_apr","type":"uint256"}],"name":"setApr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unscaledApr","type":"uint256"},{"internalType":"uint256","name":"_apr","type":"uint256"}],"name":"setAprs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"setBorrower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_canTransfer","type":"bool"}],"name":"setCanTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxApr","type":"uint256"}],"name":"setMaxApr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_cdo","type":"address"}],"name":"setWhitelistedCDO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategyToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totEpochDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"transferToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlyingToken","outputs":[{"internalType":"contract IERC20Detailed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unscaledApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawsRequests","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}