{"file_path":"Position.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\nimport './Ownable.sol';\r\nimport './MathUtil.sol';\r\n\r\nimport './IERC20.sol';\r\nimport './ILeadrate.sol';\r\nimport './IReserve.sol';\r\nimport './IFrankencoin.sol';\r\n\r\nimport './IPosition.sol';\r\n\r\n/**\r\n * @title Position\r\n * @notice A collateralized minting position.\r\n */\r\ncontract Position is Ownable, IPosition, MathUtil {\r\n\t/**\r\n\t * @notice Note that this contract is intended to be cloned. All clones will share the same values for\r\n\t * the constant and immutable fields, but have their own values for the other fields.\r\n\t */\r\n\r\n\t/**\r\n\t * @notice The zchf price per unit of the collateral below which challenges succeed, (36 - collateral.decimals) decimals\r\n\t */\r\n\tuint256 public price;\r\n\r\n\t/**\r\n\t * @notice Net minted amount, including reserve.\r\n\t */\r\n\tuint256 public minted;\r\n\r\n\t/**\r\n\t * @notice How much has been minted in total. This variable is only used in the parent position.\r\n\t */\r\n\tuint256 private totalMinted;\r\n\r\n\tuint256 public immutable limit;\r\n\r\n\t/**\r\n\t * @notice Amount of the collateral that is currently under a challenge.\r\n\t * Used to figure out whether there are pending challenges.\r\n\t */\r\n\tuint256 public challengedAmount;\r\n\r\n\t/**\r\n\t * @notice Challenge period in seconds.\r\n\t */\r\n\tuint40 public immutable challengePeriod;\r\n\r\n\t/**\r\n\t * @notice Timestamp when minting can start and the position no longer denied.\r\n\t */\r\n\tuint40 public immutable start;\r\n\r\n\t/**\r\n\t * @notice End of the latest cooldown. If this is in the future, minting is suspended.\r\n\t */\r\n\tuint40 public cooldown;\r\n\r\n\t/**\r\n\t * @notice Timestamp of the expiration of the position. After expiration, challenges cannot be averted\r\n\t * any more. This is also the basis for fee calculations.\r\n\t */\r\n\tuint40 public expiration;\r\n\r\n\tbool private closed;\r\n\r\n\t/**\r\n\t * @notice The original position to help identifying clones.\r\n\t */\r\n\taddress public immutable original;\r\n\r\n\t/**\r\n\t * @notice Pointer to the minting hub.\r\n\t */\r\n\taddress public immutable hub;\r\n\r\n\t/**\r\n\t * @notice The Frankencoin contract.\r\n\t */\r\n\tIFrankencoin public immutable zchf;\r\n\r\n\t/**\r\n\t * @notice The collateral token.\r\n\t */\r\n\tIERC20 public immutable override collateral;\r\n\r\n\t/**\r\n\t * @notice Minimum acceptable collateral amount to prevent dust.\r\n\t */\r\n\tuint256 public immutable override minimumCollateral;\r\n\r\n\t/**\r\n\t * @notice The interest in parts per million per year that is deducted when minting Frankencoins.\r\n\t * To be paid upfront.\r\n\t */\r\n\tuint24 public immutable riskPremiumPPM;\r\n\r\n\t/**\r\n\t * @notice The reserve contribution in parts per million of the minted amount.\r\n\t */\r\n\tuint24 public immutable reserveContribution;\r\n\r\n\tevent MintingUpdate(uint256 collateral, uint256 price, uint256 minted);\r\n\tevent PositionDenied(address indexed sender, string message); // emitted if closed by governance\r\n\r\n\terror InsufficientCollateral(uint256 needed, uint256 available);\r\n\terror TooLate();\r\n\terror RepaidTooMuch(uint256 excess);\r\n\terror LimitExceeded(uint256 tried, uint256 available);\r\n\terror ChallengeTooSmall();\r\n\terror Expired(uint40 time, uint40 expiration);\r\n\terror Alive();\r\n\terror Closed();\r\n\terror Hot();\r\n\terror Challenged();\r\n\terror NotHub();\r\n\terror NotOriginal();\r\n\terror InvalidExpiration();\r\n\terror AlreadyInitialized();\r\n\r\n\tmodifier alive() {\r\n\t\tif (block.timestamp >= expiration) revert Expired(uint40(block.timestamp), expiration);\r\n\t\t_;\r\n\t}\r\n\r\n\t// requires that the position has always been backed by a minimal amount of collateral\r\n\tmodifier backed() {\r\n\t\tif (isClosed()) revert Closed();\r\n\t\t_;\r\n\t}\r\n\r\n\tmodifier expired() {\r\n\t\tif (block.timestamp < expiration) revert Alive();\r\n\t\t_;\r\n\t}\r\n\r\n\tmodifier noCooldown() {\r\n\t\tif (block.timestamp <= cooldown) revert Hot();\r\n\t\t_;\r\n\t}\r\n\r\n\tmodifier noChallenge() {\r\n\t\tif (challengedAmount > 0) revert Challenged();\r\n\t\t_;\r\n\t}\r\n\r\n\tmodifier onlyHub() {\r\n\t\tif (msg.sender != address(hub)) revert NotHub();\r\n\t\t_;\r\n\t}\r\n\r\n\tmodifier ownerOrRoller() {\r\n\t\tif (msg.sender != address(IHub(hub).roller())) _requireOwner(msg.sender);\r\n\t\t_;\r\n\t}\r\n\r\n\t/**\r\n\t * @dev See MintingHub.openPosition\r\n\t */\r\n\tconstructor(\r\n\t\taddress _owner,\r\n\t\taddress _hub,\r\n\t\taddress _zchf,\r\n\t\taddress _collateral,\r\n\t\tuint256 _minCollateral,\r\n\t\tuint256 _initialLimit,\r\n\t\tuint40 _initPeriod,\r\n\t\tuint40 _duration,\r\n\t\tuint40 _challengePeriod,\r\n\t\tuint24 _riskPremiumPPM,\r\n\t\tuint256 _liqPrice,\r\n\t\tuint24 _reservePPM\r\n\t) {\r\n\t\trequire(_initPeriod >= 3 days); // must be at least three days, recommended to use higher values\r\n\t\t_setOwner(_owner);\r\n\t\toriginal = address(this);\r\n\t\thub = _hub;\r\n\t\tzchf = IFrankencoin(_zchf);\r\n\t\tcollateral = IERC20(_collateral);\r\n\t\triskPremiumPPM = _riskPremiumPPM;\r\n\t\treserveContribution = _reservePPM;\r\n\t\tminimumCollateral = _minCollateral;\r\n\t\tchallengePeriod = _challengePeriod;\r\n\t\tstart = uint40(block.timestamp) + _initPeriod; // at least three days time to deny the position\r\n\t\tcooldown = start;\r\n\t\texpiration = start + _duration;\r\n\t\tlimit = _initialLimit;\r\n\t\t_setPrice(_liqPrice, _initialLimit);\r\n\t}\r\n\r\n\t/**\r\n\t * Initialization method for clones.\r\n\t * Can only be called once. Should be called immediately after creating the clone.\r\n\t */\r\n\tfunction initialize(address parent, uint40 _expiration) external onlyHub {\r\n\t\tif (expiration != 0) revert AlreadyInitialized();\r\n\t\tif (_expiration < block.timestamp || _expiration > Position(original).expiration()) revert InvalidExpiration(); // expiration must not be later than original\r\n\t\texpiration = _expiration;\r\n\t\tprice = Position(parent).price();\r\n\t\t_setOwner(hub);\r\n\t}\r\n\r\n\t/**\r\n\t * Cloning a position is only allowed if the position is not challenged, not expired and not in cooldown.\r\n\t */\r\n\tfunction assertCloneable() external noChallenge noCooldown alive backed {}\r\n\r\n\t/**\r\n\t * Notify the original that some amount has been minted.\r\n\t */\r\n\tfunction notifyMint(uint256 mint_) external {\r\n\t\tif (zchf.getPositionParent(msg.sender) != hub) revert NotHub();\r\n\t\ttotalMinted += mint_;\r\n\t}\r\n\r\n\tfunction notifyRepaid(uint256 repaid_) external {\r\n\t\tif (zchf.getPositionParent(msg.sender) != hub) revert NotHub();\r\n\t\ttotalMinted -= repaid_;\r\n\t}\r\n\r\n\t/**\r\n\t * Should only be called on the original position.\r\n\t * Better use 'availableForMinting'.\r\n\t */\r\n\tfunction availableForClones() external view returns (uint256) {\r\n\t\t// reserve capacity for the original to the extent the owner provided collateral\r\n\t\tuint256 potential = (_collateralBalance() * price) / ONE_DEC18;\r\n\t\tuint256 unusedPotential = minted > potential ? 0 : potential - minted;\r\n\t\tif (totalMinted + unusedPotential >= limit) {\r\n\t\t\treturn 0;\r\n\t\t} else {\r\n\t\t\treturn limit - totalMinted - unusedPotential;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * The amount available for minting in this position family.\r\n\t *\r\n\t * Does not check if positions are challenged, closed, or under cooldown.\r\n\t */\r\n\tfunction availableForMinting() public view returns (uint256) {\r\n\t\tif (address(this) == original) {\r\n\t\t\treturn limit - totalMinted;\r\n\t\t} else {\r\n\t\t\treturn Position(original).availableForClones();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Qualified pool share holders can call this method to immediately expire a freshly proposed position.\r\n\t */\r\n\tfunction deny(address[] calldata helpers, string calldata message) external {\r\n\t\tif (block.timestamp >= start) revert TooLate();\r\n\t\tIReserve(zchf.reserve()).checkQualified(msg.sender, helpers);\r\n\t\t_close();\r\n\t\temit PositionDenied(msg.sender, message);\r\n\t}\r\n\r\n\t/**\r\n\t * Closes the position by putting it into eternal cooldown.\r\n\t * This allows the users to still withdraw the collateral that is left, but never to mint again.\r\n\t */\r\n\tfunction _close() internal {\r\n\t\tclosed = true;\r\n\t}\r\n\r\n\tfunction isClosed() public view returns (bool) {\r\n\t\treturn closed;\r\n\t}\r\n\r\n\t/**\r\n\t * @notice This is how much the minter can actually use when minting ZCHF, with the rest being used\r\n\t * assigned to the minter reserve or (if applicable) fees.\r\n\t */\r\n\tfunction getUsableMint(uint256 totalMint, bool afterFees) public view returns (uint256) {\r\n\t\tif (afterFees) {\r\n\t\t\treturn (totalMint * (1000_000 - reserveContribution - calculateCurrentFee())) / 1000_000;\r\n\t\t} else {\r\n\t\t\treturn (totalMint * (1000_000 - reserveContribution)) / 1000_000;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the corresponding mint amount (disregarding the limit).\r\n\t */\r\n\tfunction getMintAmount(uint256 usableMint) external view returns (uint256) {\r\n\t\treturn usableMint == 0 ? 0 : (usableMint * 1000_000 - 1) / (1000_000 - reserveContribution - calculateCurrentFee()) + 1;\r\n\t}\r\n\r\n\t/**\r\n\t * @notice \"All in one\" function to adjust the outstanding amount of ZCHF, the collateral amount,\r\n\t * and the price in one transaction.\r\n\t */\r\n\tfunction adjust(uint256 newMinted, uint256 newCollateral, uint256 newPrice) external onlyOwner {\r\n\t\tuint256 colbal = _collateralBalance();\r\n\t\tif (newCollateral > colbal) {\r\n\t\t\tcollateral.transferFrom(msg.sender, address(this), newCollateral - colbal);\r\n\t\t}\r\n\t\t// Must be called after collateral deposit, but before withdrawal\r\n\t\tif (newMinted < minted) {\r\n\t\t\tzchf.burnFromWithReserve(msg.sender, minted - newMinted, reserveContribution);\r\n\t\t\t_notifyRepaid(minted - newMinted);\r\n\t\t}\r\n\t\tif (newCollateral < colbal) {\r\n\t\t\t_withdrawCollateral(msg.sender, colbal - newCollateral);\r\n\t\t}\r\n\t\t// Must be called after collateral withdrawal\r\n\t\tif (newMinted > minted) {\r\n\t\t\t_mint(msg.sender, newMinted - minted, newCollateral);\r\n\t\t}\r\n\t\tif (newPrice != price) {\r\n\t\t\t_adjustPrice(newPrice);\r\n\t\t}\r\n\t\temit MintingUpdate(newCollateral, newPrice, newMinted);\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Allows the position owner to adjust the liquidation price as long as there is no pending challenge.\r\n\t * Lowering the liquidation price can be done with immediate effect, given that there is enough collateral.\r\n\t * Increasing the liquidation price triggers a cooldown period of 3 days, during which minting is suspended.\r\n\t */\r\n\tfunction adjustPrice(uint256 newPrice) public onlyOwner {\r\n\t\t_adjustPrice(newPrice);\r\n\t\temit MintingUpdate(_collateralBalance(), price, minted);\r\n\t}\r\n\r\n\tfunction _adjustPrice(uint256 newPrice) internal noChallenge alive backed {\r\n\t\tif (newPrice > price) {\r\n\t\t\t_restrictMinting(3 days);\r\n\t\t} else {\r\n\t\t\t_checkCollateral(_collateralBalance(), newPrice);\r\n\t\t}\r\n\t\t_setPrice(newPrice, minted + availableForMinting());\r\n\t}\r\n\r\n\tfunction _setPrice(uint256 newPrice, uint256 bounds) internal {\r\n\t\trequire(newPrice * minimumCollateral <= bounds * ONE_DEC18); // sanity check\r\n\t\tprice = newPrice;\r\n\t}\r\n\r\n\tfunction _collateralBalance() internal view returns (uint256) {\r\n\t\treturn IERC20(collateral).balanceOf(address(this));\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Mint ZCHF as long as there is no open challenge, the position is not subject to a cooldown,\r\n\t * and there is sufficient collateral.\r\n\t */\r\n\tfunction mint(address target, uint256 amount) public ownerOrRoller {\r\n\t\tuint256 collateralBalance = _collateralBalance();\r\n\t\t_mint(target, amount, collateralBalance);\r\n\t\temit MintingUpdate(collateralBalance, price, minted);\r\n\t}\r\n\r\n\t/**\r\n\t * The applicable upfront fee in ppm when minting more Frankencoins based on the annual interest rate and\r\n\t * the expiration of the position.\r\n\t */\r\n\tfunction calculateCurrentFee() public view returns (uint24) {\r\n\t\treturn calculateFee(expiration);\r\n\t}\r\n\r\n\t/**\r\n\t * The applicable interest rate in ppm when minting more Frankencoins.\r\n\t * It consists on the globally valid interest plus an individual risk premium.\r\n\t */\r\n\tfunction annualInterestPPM() public view returns (uint24) {\r\n\t\treturn IHub(hub).rate().currentRatePPM() + riskPremiumPPM;\r\n\t}\r\n\r\n\t/**\r\n\t * The fee in ppm when cloning and minting with the given expiration date.\r\n\t */\r\n\tfunction calculateFee(uint256 exp) public view returns (uint24) {\r\n\t\tuint256 time = block.timestamp < start ? start : block.timestamp;\r\n\t\tuint256 timePassed = exp - time;\r\n\t\t// Time resolution is in the range of minutes for typical interest rates.\r\n\t\tuint256 feePPM = (timePassed * annualInterestPPM()) / 365 days;\r\n\t\treturn uint24(feePPM > 1000000 ? 1000000 : feePPM); // fee cannot exceed 100%\r\n\t}\r\n\r\n\tfunction _mint(address target, uint256 amount, uint256 collateral_) internal noChallenge noCooldown alive backed {\r\n\t\tif (amount > availableForMinting()) revert LimitExceeded(amount, availableForMinting());\r\n\t\tPosition(original).notifyMint(amount);\r\n\t\tzchf.mintWithReserve(target, amount, reserveContribution, calculateCurrentFee());\r\n\t\tminted += amount;\r\n\t\t_checkCollateral(collateral_, price);\r\n\t}\r\n\r\n\tfunction _restrictMinting(uint40 period) internal {\r\n\t\tuint40 horizon = uint40(block.timestamp) + period;\r\n\t\tif (horizon > cooldown) {\r\n\t\t\tcooldown = horizon;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Repay some ZCHF. If too much is repaid, the call fails.\r\n\t * It is possible to repay while there are challenges, but the collateral is locked until all is clear again.\r\n\t *\r\n\t * The repaid amount should fulfill the following equation in order to close the position,\r\n\t * i.e. bring the minted amount to 0:\r\n\t * minted = amount + zchf.calculateAssignedReserve(amount, reservePPM)\r\n\t *\r\n\t * Under normal circumstances, this implies:\r\n\t * amount = minted * (1000000 - reservePPM)\r\n\t *\r\n\t * E.g. if minted is 50 and reservePPM is 200000, it is necessary to repay 40 to be able to close the position.\r\n\t */\r\n\tfunction repay(uint256 amount) public returns (uint256) {\r\n\t\tIERC20(zchf).transferFrom(msg.sender, address(this), amount);\r\n\t\tuint256 actuallyRepaid = IFrankencoin(zchf).burnWithReserve(amount, reserveContribution);\r\n\t\t_notifyRepaid(actuallyRepaid);\r\n\t\temit MintingUpdate(_collateralBalance(), price, minted);\r\n\t\treturn actuallyRepaid;\r\n\t}\r\n\r\n\tfunction _notifyRepaid(uint256 amount) internal {\r\n\t\tif (amount > minted) revert RepaidTooMuch(amount - minted);\r\n\t\tPosition(original).notifyRepaid(amount);\r\n\t\tminted -= amount;\r\n\t}\r\n\r\n\t/**\r\n\t * Force the sale of some collateral after the position is expired.\r\n\t *\r\n\t * Can only be called by the minting hub and the minting hub is trusted to calculate the price correctly.\r\n\t * The proceeds from the sale are first used to repay the outstanding balance and then (if anything is left)\r\n\t * it is sent to the owner of the position.\r\n\t *\r\n\t * Do not allow a forced sale as long as there is an open challenge. Otherwise, a forced sale by the owner\r\n\t * himself could remove any incentive to launch challenges shortly before the expiration. (CS-ZCHF2-001)\r\n\t */\r\n\tfunction forceSale(address buyer, uint256 collAmount, uint256 proceeds) external onlyHub expired noChallenge {\r\n\t\t// send collateral to buyer\r\n\t\tuint256 remainingCollateral = _sendCollateral(buyer, collAmount);\r\n\t\tif (minted > 0) {\r\n\t\t\tuint256 availableReserve = zchf.calculateAssignedReserve(minted, reserveContribution);\r\n\t\t\tif (proceeds + availableReserve >= minted) {\r\n\t\t\t\t// repay everything from the buyer's account\r\n\t\t\t\tuint256 returnedReserve = zchf.burnFromWithReserve(buyer, minted, reserveContribution);\r\n\t\t\t\tassert(returnedReserve == availableReserve);\r\n\t\t\t\t// transfer the remaining purchase price from the buyer to the owner\r\n\t\t\t\tzchf.transferFrom(buyer, owner, proceeds + returnedReserve - minted);\r\n\t\t\t\t_notifyRepaid(minted);\r\n\t\t\t} else {\r\n\t\t\t\t// we can only repay a part, nothing left to pay to owner\r\n\t\t\t\tzchf.transferFrom(buyer, address(this), proceeds);\r\n\t\t\t\tif (remainingCollateral == 0) {\r\n\t\t\t\t\t// CS-ZCHF2-002, bad debt should be properly handled. In this case, the proceeds from\r\n\t\t\t\t\t// the forced sale did not suffice to repay the position and there is a loss\r\n\t\t\t\t\tzchf.coverLoss(address(this), minted - proceeds); // more than we need, but returned again on next line\r\n\t\t\t\t\tzchf.burnWithoutReserve(minted, reserveContribution);\r\n\t\t\t\t\t_notifyRepaid(minted);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tuint256 repaid = zchf.burnWithReserve(proceeds, reserveContribution);\r\n\t\t\t\t\t_notifyRepaid(repaid);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// wire funds directly to owner\r\n\t\t\tzchf.transferFrom(buyer, owner, proceeds);\r\n\t\t}\r\n\t\temit MintingUpdate(_collateralBalance(), price, minted);\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Withdraw any ERC20 token that might have ended up on this address.\r\n\t * Withdrawing collateral is subject to the same restrictions as withdrawCollateral(...).\r\n\t */\r\n\tfunction withdraw(address token, address target, uint256 amount) external onlyOwner {\r\n\t\tif (token == address(collateral)) {\r\n\t\t\twithdrawCollateral(target, amount);\r\n\t\t} else {\r\n\t\t\tuint256 balance = _collateralBalance();\r\n\t\t\tIERC20(token).transfer(target, amount);\r\n\t\t\trequire(balance == _collateralBalance()); // guard against double-entry-point tokens\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Withdraw collateral from the position up to the extent that it is still well collateralized afterwards.\r\n\t * Not possible as long as there is an open challenge or the contract is subject to a cooldown.\r\n\t *\r\n\t * Withdrawing collateral below the minimum collateral amount formally closes the position.\r\n\t */\r\n\tfunction withdrawCollateral(address target, uint256 amount) public ownerOrRoller {\r\n\t\tuint256 balance = _withdrawCollateral(target, amount);\r\n\t\temit MintingUpdate(balance, price, minted);\r\n\t}\r\n\r\n\tfunction _withdrawCollateral(address target, uint256 amount) internal noChallenge returns (uint256) {\r\n\t\tif (block.timestamp <= cooldown) revert Hot();\r\n\t\tuint256 balance = _sendCollateral(target, amount);\r\n\t\t_checkCollateral(balance, price);\r\n\t\treturn balance;\r\n\t}\r\n\r\n\tfunction _sendCollateral(address target, uint256 amount) internal returns (uint256) {\r\n\t\tif (amount > 0) {\r\n\t\t\t// Some weird tokens fail when trying to transfer 0 amounts\r\n\t\t\tIERC20(collateral).transfer(target, amount);\r\n\t\t}\r\n\t\tuint256 balance = _collateralBalance();\r\n\t\tif (balance < minimumCollateral) {\r\n\t\t\t_close();\r\n\t\t}\r\n\t\treturn balance;\r\n\t}\r\n\r\n\t/**\r\n\t * @notice This invariant must always hold and must always be checked when any of the three\r\n\t * variables change in an adverse way.\r\n\t */\r\n\tfunction _checkCollateral(uint256 collateralReserve, uint256 atPrice) internal view {\r\n\t\tuint256 relevantCollateral = collateralReserve < minimumCollateral ? 0 : collateralReserve;\r\n\t\tif (relevantCollateral * atPrice < minted * ONE_DEC18)\r\n\t\t\trevert InsufficientCollateral(relevantCollateral * atPrice, minted * ONE_DEC18);\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Returns the liquidation price and the durations for phase1 and phase2 of the challenge.\r\n\t * Both phases are usually of equal duration, but near expiration, phase one is adjusted such that\r\n\t * it cannot last beyond the expiration date of the position.\r\n\t */\r\n\tfunction challengeData() external view returns (uint256 liqPrice, uint40 phase) {\r\n\t\treturn (price, challengePeriod);\r\n\t}\r\n\r\n\tfunction notifyChallengeStarted(uint256 size) external onlyHub alive {\r\n\t\t// Require minimum size. Collateral balance can be below minimum if it was partially challenged before.\r\n\t\tif (size < minimumCollateral && size < _collateralBalance()) revert ChallengeTooSmall();\r\n\t\tif (size == 0) revert ChallengeTooSmall();\r\n\t\tchallengedAmount += size;\r\n\t}\r\n\r\n\t/**\r\n\t * @param size   amount of collateral challenged (dec18)\r\n\t */\r\n\tfunction notifyChallengeAverted(uint256 size) external onlyHub {\r\n\t\tchallengedAmount -= size;\r\n\r\n\t\t// Don't allow minter to close the position immediately so challenge can be repeated before\r\n\t\t// the owner has a chance to mint more on an undercollateralized position\r\n\t\t_restrictMinting(1 days);\r\n\t}\r\n\r\n\t/**\r\n\t * @notice Notifies the position that a challenge was successful.\r\n\t * Triggers the payout of the challenged part of the collateral.\r\n\t * Everything else is assumed to be handled by the hub.\r\n\t *\r\n\t * @param _bidder   address of the bidder that receives the collateral\r\n\t * @param _size     amount of the collateral bid for\r\n\t * @return (position owner, effective challenge size in ZCHF, amount to be repaid, reserve ppm)\r\n\t */\r\n\tfunction notifyChallengeSucceeded(address _bidder, uint256 _size) external onlyHub returns (address, uint256, uint256, uint32) {\r\n\t\tchallengedAmount -= _size;\r\n\t\tuint256 colBal = _collateralBalance();\r\n\t\tif (colBal < _size) {\r\n\t\t\t_size = colBal;\r\n\t\t}\r\n\t\tuint256 repayment = colBal == 0 ? 0 : (minted * _size) / colBal; // for enormous colBal, this could be rounded to 0, which is ok\r\n\t\t_notifyRepaid(repayment); // we assume the caller takes care of the actual repayment\r\n\r\n\t\t// Give time for additional challenges before the owner can mint again. In particular,\r\n\t\t// the owner might have added collateral only seconds before the challenge ended, preventing a close.\r\n\t\t_restrictMinting(3 days);\r\n\r\n\t\tuint256 newBalance = _sendCollateral(_bidder, _size); // transfer collateral to the bidder and emit update\r\n\r\n\t\temit MintingUpdate(newBalance, price, minted);\r\n\r\n\t\treturn (owner, _size, repayment, reserveContribution);\r\n\t}\r\n}\r\n\r\ninterface IHub {\r\n\tfunction rate() external view returns (ILeadrate);\r\n\r\n\tfunction roller() external view returns (address);\r\n}\r\n","deployed_bytecode":"0x608060405234801561001057600080fd5b50600436106102535760003560e01c80636d4749fa11610146578063a4d66daf116100c3578063c4d4803a11610087578063c4d4803a146105e6578063cfb636f01461060d578063d8dfeb4514610620578063d9caed1214610647578063f2fde38b1461065a578063f3f480d91461066d57600080fd5b8063a4d66daf1461054c578063a8a3e31d14610573578063babe7c741461057b578063be9a6555146105a2578063c2b6b58c146105c957600080fd5b80637bd6fb9b1161010a5780637bd6fb9b146105025780638da5cb5b1461050a57806399a5d7471461051d5780639de2f79614610530578063a035b1fe1461054357600080fd5b80636d4749fa146104915780636f871cec146104a457806372bf079e146104b7578063730d48b7146104ca578063787a08a6146104f157600080fd5b8063371fd8e6116101d45780634665096d116101985780634665096d1461040d57806346c715fa1461043b57806349746f10146104625780634f02c420146104755780635be980f51461047e57600080fd5b8063371fd8e614610391578063383ef46e146103a45780633a7c29fb146103c057806340c10f19146103e757806342d02041146103fa57600080fd5b806324e657fe1161021b57806324e657fe146102f15780632a37eeae146102fa578063329864aa14610302578063350c35e91461033f578063365a86fc1461035257600080fd5b806308262940146102585780630e49d77e1461027e5780631bbea34c1461028857806320aa9e721461029b578063211d7983146102de575b600080fd5b61026b610266366004612981565b610694565b6040519081526020015b60405180910390f35b610286610733565b005b6102866102963660046129b1565b6107fc565b6102ae6102a9366004612a8b565b610985565b604080516001600160a01b03909516855260208501939093529183015263ffffffff166060820152608001610275565b6102866102ec366004612ab7565b610ac6565b61026b60045481565b61026b61117c565b6001546040805191825264ffffffffff7f000000000000000000000000000000000000000000000000000000000005460016602083015201610275565b61028661034d366004612a8b565b611262565b6103797f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca65355781565b6040516001600160a01b039091168152602001610275565b61026b61039f366004612aec565b61134d565b6103ac6114e9565b60405162ffffff9091168152602001610275565b6103ac7f0000000000000000000000000000000000000000000000000000000000061a8081565b6102866103f5366004612a8b565b611506565b610286610408366004612aec565b6115f0565b60055461042590600160281b900464ffffffffff1681565b60405164ffffffffff9091168152602001610275565b6103797f000000000000000000000000224bc870a661cc77742d63b6c1fe82df1841e0d581565b610286610470366004612aec565b611714565b61026b60025481565b61028661048c366004612aec565b611784565b61028661049f366004612b18565b61186b565b6102866104b2366004612b46565b611a57565b6102866104c5366004612aec565b611c88565b6103ac7f0000000000000000000000000000000000000000000000000000000000000bb881565b6005546104259064ffffffffff1681565b6103ac611cd8565b600054610379906001600160a01b031681565b6103ac61052b366004612aec565b611de8565b61026b61053e366004612aec565b611ea0565b61026b60015481565b61026b7f00000000000000000000000000000000000000000000d3c21bcecceda100000081565b61026b611f27565b61026b7f00000000000000000000000000000000000000000000000000000000000001f481565b6104257f00000000000000000000000000000000000000000000000000000000698c8e6b81565b600554600160501b900460ff166040519015158152602001610275565b6103797f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb81565b61028661061b366004612aec565b611ff3565b6103797f000000000000000000000000343324f53cbeee3ee6d171f2a20f005964c9804781565b610286610655366004612b72565b6120da565b610286610668366004612bb3565b6121c6565b6104257f000000000000000000000000000000000000000000000000000000000005460081565b600081156106ff57620f42406106a86114e9565b6106d57f0000000000000000000000000000000000000000000000000000000000061a80620f4240612be6565b6106df9190612be6565b6106ee9062ffffff1685612c09565b6106f89190612c20565b905061072d565b620f42406106df7f0000000000000000000000000000000000000000000000000000000000061a8082612be6565b92915050565b600454156107545760405163d26e2de960e01b815260040160405180910390fd5b60055464ffffffffff16421161077d57604051631c02820f60e21b815260040160405180910390fd5b600554600160281b900464ffffffffff1642106107cf576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044015b60405180910390fd5b600554600160501b900460ff16156107fa57604051631cdde67b60e01b815260040160405180910390fd5b565b7f00000000000000000000000000000000000000000000000000000000698c8e6b64ffffffffff1642106108435760405163ecdd1c2960e01b815260040160405180910390fd5b7f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b031663cd3293de6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c59190612c42565b6001600160a01b031663352e3a833386866040518463ffffffff1660e01b81526004016108f493929190612c5f565b60006040518083038186803b15801561090c57600080fd5b505afa158015610920573d6000803e3d6000fd5b5050505061093c6005805460ff60501b1916600160501b179055565b336001600160a01b03167faca80c800ec0d2aa9d9d31b7f886a1dd3067d4676abc637626a18ffb9381653d8383604051610977929190612cbb565b60405180910390a250505050565b6000808080336001600160a01b037f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca65355716146109d3576040516313bd2e8360e31b815260040160405180910390fd5b84600460008282546109e59190612cea565b90915550600090506109f56121d8565b905085811015610a03578095505b60008115610a29578187600254610a1a9190612c09565b610a249190612c20565b610a2c565b60005b9050610a378161223f565b610a436203f4806122fe565b6000610a4f898961233f565b600154600254604080518481526020810193909352820152909150600080516020612dfd8339815191529060600160405180910390a1506000546001600160a01b031698969750957f0000000000000000000000000000000000000000000000000000000000061a8062ffffff1695509350505050565b336001600160a01b037f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca6535571614610b0f576040516313bd2e8360e31b815260040160405180910390fd5b600554600160281b900464ffffffffff16421015610b40576040516302de694d60e41b815260040160405180910390fd5b60045415610b615760405163d26e2de960e01b815260040160405180910390fd5b6000610b6d848461233f565b600254909150156110a1576002546040516302dc1ca760e31b8152600481019190915262ffffff7f0000000000000000000000000000000000000000000000000000000000061a801660248201526000907f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b0316906316e0e53890604401602060405180830381865afa158015610c0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c339190612cfd565b600254909150610c438285612d16565b10610de4576002546040516318af9f3960e11b81526001600160a01b038781166004830152602482019290925262ffffff7f0000000000000000000000000000000000000000000000000000000000061a801660448201526000917f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb169063315f3e72906064016020604051808303816000875af1158015610ce9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0d9190612cfd565b9050818114610d1e57610d1e612d29565b6000546002546001600160a01b037f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb8116926323b872dd928a929190911690610d67868a612d16565b610d719190612cea565b6040518463ffffffff1660e01b8152600401610d8f93929190612d3f565b6020604051808303816000875af1158015610dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd29190612d63565b50610dde60025461223f565b5061109b565b6040516323b872dd60e01b81526001600160a01b037f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb16906323b872dd90610e3490889030908890600401612d3f565b6020604051808303816000875af1158015610e53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e779190612d63565b5081600003610fd5577f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b031663d1fa5e983085600254610ebe9190612cea565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610f0457600080fd5b505af1158015610f18573d6000803e3d6000fd5b50506002546040516363b20c3360e11b8152600481019190915262ffffff7f0000000000000000000000000000000000000000000000000000000000061a801660248201527f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b0316925063c76418669150604401600060405180830381600087803b158015610fad57600080fd5b505af1158015610fc1573d6000803e3d6000fd5b50505050610fd060025461223f565b61109b565b60405163a47d75ad60e01b81526004810184905262ffffff7f0000000000000000000000000000000000000000000000000000000000061a801660248201526000907f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b03169063a47d75ad906044016020604051808303816000875af115801561106a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108e9190612cfd565b90506110998161223f565b505b5061113a565b6000546040516323b872dd60e01b81526001600160a01b037f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb8116926323b872dd926110f592899216908790600401612d3f565b6020604051808303816000875af1158015611114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111389190612d63565b505b600080516020612dfd8339815191526111516121d8565b600154600254604080519384526020840192909252908201526060015b60405180910390a150505050565b60006001600160a01b037f000000000000000000000000224bc870a661cc77742d63b6c1fe82df1841e0d51630036111e0576003546111db907f00000000000000000000000000000000000000000000d3c21bcecceda1000000612cea565b905090565b7f000000000000000000000000224bc870a661cc77742d63b6c1fe82df1841e0d56001600160a01b031663a8a3e31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561123e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111db9190612cfd565b7f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca6535576001600160a01b0316632f09177d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190612c42565b6001600160a01b0316336001600160a01b031614611305576113053361242f565b60006113118383612475565b600154600254604080518481526020810193909352820152909150600080516020612dfd833981519152906060015b60405180910390a1505050565b6040516323b872dd60e01b81526000906001600160a01b037f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb16906323b872dd906113a090339030908790600401612d3f565b6020604051808303816000875af11580156113bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e39190612d63565b5060405163a47d75ad60e01b81526004810183905262ffffff7f0000000000000000000000000000000000000000000000000000000000061a801660248201526000907f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b03169063a47d75ad906044016020604051808303816000875af1158015611479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149d9190612cfd565b90506114a88161223f565b600080516020612dfd8339815191526114bf6121d8565b6001546002546040805193845260208401929092529082015260600160405180910390a192915050565b6005546000906111db90600160281b900464ffffffffff16611de8565b7f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca6535576001600160a01b0316632f09177d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611564573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115889190612c42565b6001600160a01b0316336001600160a01b0316146115a9576115a93361242f565b60006115b36121d8565b90506115c08383836124dc565b600154600254604080518481526020810193909352820152600080516020612dfd83398151915290606001611340565b336001600160a01b037f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca6535571614611639576040516313bd2e8360e31b815260040160405180910390fd5b600554600160281b900464ffffffffff164210611686576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044016107c6565b7f00000000000000000000000000000000000000000000000000000000000001f4811080156116bb57506116b86121d8565b81105b156116d957604051633c80636b60e21b815260040160405180910390fd5b806000036116fa57604051633c80636b60e21b815260040160405180910390fd5b806004600082825461170c9190612d16565b909155505050565b336001600160a01b037f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca653557161461175d576040516313bd2e8360e31b815260040160405180910390fd5b806004600082825461176f9190612cea565b909155506117819050620151806122fe565b50565b60405163aa5dd7f160e01b81523360048201526001600160a01b037f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca6535578116917f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb9091169063aa5dd7f190602401602060405180830381865afa15801561180e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118329190612c42565b6001600160a01b031614611859576040516313bd2e8360e31b815260040160405180910390fd5b806003600082825461170c9190612cea565b336001600160a01b037f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca65355716146118b4576040516313bd2e8360e31b815260040160405180910390fd5b600554600160281b900464ffffffffff16156118e25760405162dc149f60e41b815260040160405180910390fd5b428164ffffffffff16108061198557507f000000000000000000000000224bc870a661cc77742d63b6c1fe82df1841e0d56001600160a01b0316634665096d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611950573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119749190612d80565b64ffffffffff168164ffffffffff16115b156119a357604051637d9533a960e11b815260040160405180910390fd5b806005806101000a81548164ffffffffff021916908364ffffffffff160217905550816001600160a01b031663a035b1fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a279190612cfd565b600155611a537f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca653557612744565b5050565b611a603361242f565b6000611a6a6121d8565b905080831115611b12576001600160a01b037f000000000000000000000000343324f53cbeee3ee6d171f2a20f005964c98047166323b872dd3330611aaf8588612cea565b6040518463ffffffff1660e01b8152600401611acd93929190612d3f565b6020604051808303816000875af1158015611aec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b109190612d63565b505b600254841015611c0b577f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b031663315f3e723386600254611b5a9190612cea565b6040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015262ffffff7f0000000000000000000000000000000000000000000000000000000000061a801660448201526064016020604051808303816000875af1158015611bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf49190612cfd565b50611c0b84600254611c069190612cea565b61223f565b80831015611c2857611c2633611c218584612cea565b612475565b505b600254841115611c4a57611c4a3360025486611c449190612cea565b856124dc565b6001548214611c5c57611c5c826127a7565b6040805184815260208101849052908101859052600080516020612dfd8339815191529060600161116e565b611c913361242f565b611c9a816127a7565b600080516020612dfd833981519152611cb16121d8565b6001546002546040805193845260208401929092529082015260600160405180910390a150565b60007f0000000000000000000000000000000000000000000000000000000000000bb87f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca6535576001600160a01b0316632c4e722e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7d9190612c42565b6001600160a01b03166306a7b3766040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dde9190612d9d565b6111db9190612dc2565b6000807f00000000000000000000000000000000000000000000000000000000698c8e6b64ffffffffff164210611e1f5742611e48565b7f00000000000000000000000000000000000000000000000000000000698c8e6b64ffffffffff165b90506000611e568285612cea565b905060006301e13380611e67611cd8565b611e769062ffffff1684612c09565b611e809190612c20565b9050620f42408111611e925780611e97565b620f42405b95945050505050565b60008115611f1f57611eb06114e9565b611edd7f0000000000000000000000000000000000000000000000000000000000061a80620f4240612be6565b611ee79190612be6565b62ffffff166001611efb84620f4240612c09565b611f059190612cea565b611f0f9190612c20565b611f1a906001612d16565b61072d565b600092915050565b600080670de0b6b3a7640000600154611f3e6121d8565b611f489190612c09565b611f529190612c20565b905060008160025411611f7157600254611f6c9083612cea565b611f74565b60005b90507f00000000000000000000000000000000000000000000d3c21bcecceda100000081600354611fa59190612d16565b10611fb35760009250505090565b806003547f00000000000000000000000000000000000000000000d3c21bcecceda1000000611fe29190612cea565b611fec9190612cea565b9250505090565b60405163aa5dd7f160e01b81523360048201526001600160a01b037f000000000000000000000000de12b620a8a714476a97efd14e6f7180ca6535578116917f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb9091169063aa5dd7f190602401602060405180830381865afa15801561207d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a19190612c42565b6001600160a01b0316146120c8576040516313bd2e8360e31b815260040160405180910390fd5b806003600082825461170c9190612d16565b6120e33361242f565b7f000000000000000000000000343324f53cbeee3ee6d171f2a20f005964c980476001600160a01b0316836001600160a01b03160361212b576121268282611262565b505050565b60006121356121d8565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529192509085169063a9059cbb906044016020604051808303816000875af1158015612188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ac9190612d63565b506121b56121d8565b81146121c057600080fd5b50505050565b6121cf3361242f565b61178181612744565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000343324f53cbeee3ee6d171f2a20f005964c980476001600160a01b0316906370a0823190602401602060405180830381865afa15801561123e573d6000803e3d6000fd5b600254811115612272576002546122569082612cea565b604051635795d46960e11b81526004016107c691815260200190565b604051635be980f560e01b8152600481018290527f000000000000000000000000224bc870a661cc77742d63b6c1fe82df1841e0d56001600160a01b031690635be980f590602401600060405180830381600087803b1580156122d457600080fd5b505af11580156122e8573d6000803e3d6000fd5b50505050806002600082825461170c9190612cea565b600061230a8242612dde565b60055490915064ffffffffff9081169082161115611a53576005805464ffffffffff831664ffffffffff199091161790555050565b600081156123dc5760405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f000000000000000000000000343324f53cbeee3ee6d171f2a20f005964c98047169063a9059cbb906044016020604051808303816000875af11580156123b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123da9190612d63565b505b60006123e66121d8565b90507f00000000000000000000000000000000000000000000000000000000000001f4811015612428576124286005805460ff60501b1916600160501b179055565b9392505050565b6000546001600160a01b0382811691161480159061245757506000546001600160a01b031615155b15611781576040516330cd747160e01b815260040160405180910390fd5b600454600090156124995760405163d26e2de960e01b815260040160405180910390fd5b60055464ffffffffff1642116124c257604051631c02820f60e21b815260040160405180910390fd5b60006124ce848461233f565b90506124288160015461288a565b600454156124fd5760405163d26e2de960e01b815260040160405180910390fd5b60055464ffffffffff16421161252657604051631c02820f60e21b815260040160405180910390fd5b600554600160281b900464ffffffffff164210612573576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044016107c6565b600554600160501b900460ff161561259e57604051631cdde67b60e01b815260040160405180910390fd5b6125a661117c565b8211156125d857816125b661117c565b604051634779077960e11b8152600481019290925260248201526044016107c6565b604051630cfb636f60e41b8152600481018390527f000000000000000000000000224bc870a661cc77742d63b6c1fe82df1841e0d56001600160a01b03169063cfb636f090602401600060405180830381600087803b15801561263a57600080fd5b505af115801561264e573d6000803e3d6000fd5b505050507f000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb6001600160a01b0316638112eb2b84847f0000000000000000000000000000000000000000000000000000000000061a806126ac6114e9565b6040516001600160e01b031960e087901b1681526001600160a01b039094166004850152602484019290925262ffffff9081166044840152166064820152608401600060405180830381600087803b15801561270757600080fd5b505af115801561271b573d6000803e3d6000fd5b5050505081600260008282546127319190612d16565b925050819055506121268160015461288a565b6001600160a01b03811661275757600080fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600454156127c85760405163d26e2de960e01b815260040160405180910390fd5b600554600160281b900464ffffffffff164210612815576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044016107c6565b600554600160501b900460ff161561284057604051631cdde67b60e01b815260040160405180910390fd5b60015481111561285b576128566203f4806122fe565b61286c565b61286c6128666121d8565b8261288a565b6117818161287861117c565b6002546128859190612d16565b612926565b60007f00000000000000000000000000000000000000000000000000000000000001f483106128b957826128bc565b60005b9050670de0b6b3a76400006002546128d49190612c09565b6128de8383612c09565b1015612126576128ee8282612c09565b670de0b6b3a76400006002546129049190612c09565b604051632c1f8ef160e21b8152600481019290925260248201526044016107c6565b612938670de0b6b3a764000082612c09565b6129627f00000000000000000000000000000000000000000000000000000000000001f484612c09565b111561296d57600080fd5b50600155565b801515811461178157600080fd5b6000806040838503121561299457600080fd5b8235915060208301356129a681612973565b809150509250929050565b600080600080604085870312156129c757600080fd5b843567ffffffffffffffff808211156129df57600080fd5b818701915087601f8301126129f357600080fd5b813581811115612a0257600080fd5b8860208260051b8501011115612a1757600080fd5b602092830196509450908601359080821115612a3257600080fd5b818701915087601f830112612a4657600080fd5b813581811115612a5557600080fd5b886020828501011115612a6757600080fd5b95989497505060200194505050565b6001600160a01b038116811461178157600080fd5b60008060408385031215612a9e57600080fd5b8235612aa981612a76565b946020939093013593505050565b600080600060608486031215612acc57600080fd5b8335612ad781612a76565b95602085013595506040909401359392505050565b600060208284031215612afe57600080fd5b5035919050565b64ffffffffff8116811461178157600080fd5b60008060408385031215612b2b57600080fd5b8235612b3681612a76565b915060208301356129a681612b05565b600080600060608486031215612b5b57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215612b8757600080fd5b8335612b9281612a76565b92506020840135612ba281612a76565b929592945050506040919091013590565b600060208284031215612bc557600080fd5b813561242881612a76565b634e487b7160e01b600052601160045260246000fd5b62ffffff828116828216039080821115612c0257612c02612bd0565b5092915050565b808202811582820484141761072d5761072d612bd0565b600082612c3d57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215612c5457600080fd5b815161242881612a76565b6001600160a01b03848116825260406020808401829052908301849052600091859160608501845b87811015612cae578435612c9a81612a76565b841682529382019390820190600101612c87565b5098975050505050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b8181038181111561072d5761072d612bd0565b600060208284031215612d0f57600080fd5b5051919050565b8082018082111561072d5761072d612bd0565b634e487b7160e01b600052600160045260246000fd5b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215612d7557600080fd5b815161242881612973565b600060208284031215612d9257600080fd5b815161242881612b05565b600060208284031215612daf57600080fd5b815162ffffff8116811461242857600080fd5b62ffffff818116838216019080821115612c0257612c02612bd0565b64ffffffffff818116838216019080821115612c0257612c02612bd056fe9483a26ad376f30b5199a79e75df3bb05158c4ee32a348f53e83245a5e50c86ea26469706673582212203d0e7cc7b31f042803c803a5def335273b3b31f8d50db1473e0cc88de51eebc764736f6c63430008140033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}}},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":[["0x01DD57a2C68B5e6819EbDe2cEc64f4000438d9BB",{"internalType":"address","name":"_owner","type":"address"}],["0xDe12B620A8a714476A97EfD14E6F7180Ca653557",{"internalType":"address","name":"_hub","type":"address"}],["0xB58E61C3098d85632Df34EecfB899A1Ed80921cB",{"internalType":"address","name":"_zchf","type":"address"}],["0x343324F53CBEEE3Ee6d171f2a20F005964C98047",{"internalType":"address","name":"_collateral","type":"address"}],["500",{"internalType":"uint256","name":"_minCollateral","type":"uint256"}],["1000000000000000000000000",{"internalType":"uint256","name":"_initialLimit","type":"uint256"}],["432000",{"internalType":"uint40","name":"_initPeriod","type":"uint40"}],["31104000",{"internalType":"uint40","name":"_duration","type":"uint40"}],["345600",{"internalType":"uint40","name":"_challengePeriod","type":"uint40"}],["3000",{"internalType":"uint24","name":"_riskPremiumPPM","type":"uint24"}],["20000000000000000000000000000000000000",{"internalType":"uint256","name":"_liqPrice","type":"uint256"}],["400000",{"internalType":"uint24","name":"_reservePPM","type":"uint24"}]],"compiler_version":"v0.8.20+commit.a1b79de6","is_verified_via_verifier_alliance":false,"verified_at":"2026-02-06T14:19:12.097580Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x6101c06040523480156200001257600080fd5b5060405162003398380380620033988339810160408190526200003591620001fc565b6203f4808664ffffffffff1610156200004d57600080fd5b620000588c6200011b565b3060e0526001600160a01b038b8116610100528a81166101205289166101405262ffffff8084166101805281166101a05261016088905264ffffffffff841660a052620000a68642620002ec565b64ffffffffff1660c08190526005805464ffffffffff191682179055620000cf908690620002ec565b6005805464ffffffffff92909216650100000000000264ffffffffff60281b1990921691909117905560808790526200010982886200017f565b50505050505050505050505062000334565b6001600160a01b0381166200012f57600080fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b62000193670de0b6b3a76400008262000314565b61016051620001a3908462000314565b1115620001af57600080fd5b50600155565b80516001600160a01b0381168114620001cd57600080fd5b919050565b805164ffffffffff81168114620001cd57600080fd5b805162ffffff81168114620001cd57600080fd5b6000806000806000806000806000806000806101808d8f0312156200022057600080fd5b6200022b8d620001b5565b9b506200023b60208e01620001b5565b9a506200024b60408e01620001b5565b99506200025b60608e01620001b5565b985060808d0151975060a08d015196506200027960c08e01620001d2565b95506200028960e08e01620001d2565b94506200029a6101008e01620001d2565b9350620002ab6101208e01620001e8565b92506101408d01519150620002c46101608e01620001e8565b90509295989b509295989b509295989b565b634e487b7160e01b600052601160045260246000fd5b64ffffffffff8181168382160190808211156200030d576200030d620002d6565b5092915050565b80820281158282048414176200032e576200032e620002d6565b92915050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a051612e5262000546600039600081816103c5015281816106ad0152818161070801528181610a9901528181610b9601528181610c7601528181610f3801528181610fef015281816113fe01528181611b8901528181611eb501526126850152600081816104cf0152611cdc01526000818161058001528181611688015281816123ea0152818161288e015261293d01526000818161062501528181611a7e015281816120e5015281816121f0015261236d0152600081816105eb0152818161084501528181610bc001528181610ca001528181610d2e01528181610dfb01528181610e8201528181610f5f01528181611019015281816110bb0152818161136701528181611428015281816117c501528181611b1e0152818161203401526126540152600081816103570152818161099501528181610ad10152818161126401528181611508015281816115fb0152818161171f015281816117a10152818161187601528181611a2f01528181611cfd015261201001526000818161044001528181611188015281816111e2015281816118f40152818161228801526125ee0152600081816105a7015281816107fe01528181611ded0152611e210152600081816103140152610672015260008181610551015281816111b701528181611f780152611fb90152612e526000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c80636d4749fa11610146578063a4d66daf116100c3578063c4d4803a11610087578063c4d4803a146105e6578063cfb636f01461060d578063d8dfeb4514610620578063d9caed1214610647578063f2fde38b1461065a578063f3f480d91461066d57600080fd5b8063a4d66daf1461054c578063a8a3e31d14610573578063babe7c741461057b578063be9a6555146105a2578063c2b6b58c146105c957600080fd5b80637bd6fb9b1161010a5780637bd6fb9b146105025780638da5cb5b1461050a57806399a5d7471461051d5780639de2f79614610530578063a035b1fe1461054357600080fd5b80636d4749fa146104915780636f871cec146104a457806372bf079e146104b7578063730d48b7146104ca578063787a08a6146104f157600080fd5b8063371fd8e6116101d45780634665096d116101985780634665096d1461040d57806346c715fa1461043b57806349746f10146104625780634f02c420146104755780635be980f51461047e57600080fd5b8063371fd8e614610391578063383ef46e146103a45780633a7c29fb146103c057806340c10f19146103e757806342d02041146103fa57600080fd5b806324e657fe1161021b57806324e657fe146102f15780632a37eeae146102fa578063329864aa14610302578063350c35e91461033f578063365a86fc1461035257600080fd5b806308262940146102585780630e49d77e1461027e5780631bbea34c1461028857806320aa9e721461029b578063211d7983146102de575b600080fd5b61026b610266366004612981565b610694565b6040519081526020015b60405180910390f35b610286610733565b005b6102866102963660046129b1565b6107fc565b6102ae6102a9366004612a8b565b610985565b604080516001600160a01b03909516855260208501939093529183015263ffffffff166060820152608001610275565b6102866102ec366004612ab7565b610ac6565b61026b60045481565b61026b61117c565b6001546040805191825264ffffffffff7f000000000000000000000000000000000000000000000000000000000000000016602083015201610275565b61028661034d366004612a8b565b611262565b6103797f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610275565b61026b61039f366004612aec565b61134d565b6103ac6114e9565b60405162ffffff9091168152602001610275565b6103ac7f000000000000000000000000000000000000000000000000000000000000000081565b6102866103f5366004612a8b565b611506565b610286610408366004612aec565b6115f0565b60055461042590600160281b900464ffffffffff1681565b60405164ffffffffff9091168152602001610275565b6103797f000000000000000000000000000000000000000000000000000000000000000081565b610286610470366004612aec565b611714565b61026b60025481565b61028661048c366004612aec565b611784565b61028661049f366004612b18565b61186b565b6102866104b2366004612b46565b611a57565b6102866104c5366004612aec565b611c88565b6103ac7f000000000000000000000000000000000000000000000000000000000000000081565b6005546104259064ffffffffff1681565b6103ac611cd8565b600054610379906001600160a01b031681565b6103ac61052b366004612aec565b611de8565b61026b61053e366004612aec565b611ea0565b61026b60015481565b61026b7f000000000000000000000000000000000000000000000000000000000000000081565b61026b611f27565b61026b7f000000000000000000000000000000000000000000000000000000000000000081565b6104257f000000000000000000000000000000000000000000000000000000000000000081565b600554600160501b900460ff166040519015158152602001610275565b6103797f000000000000000000000000000000000000000000000000000000000000000081565b61028661061b366004612aec565b611ff3565b6103797f000000000000000000000000000000000000000000000000000000000000000081565b610286610655366004612b72565b6120da565b610286610668366004612bb3565b6121c6565b6104257f000000000000000000000000000000000000000000000000000000000000000081565b600081156106ff57620f42406106a86114e9565b6106d57f0000000000000000000000000000000000000000000000000000000000000000620f4240612be6565b6106df9190612be6565b6106ee9062ffffff1685612c09565b6106f89190612c20565b905061072d565b620f42406106df7f000000000000000000000000000000000000000000000000000000000000000082612be6565b92915050565b600454156107545760405163d26e2de960e01b815260040160405180910390fd5b60055464ffffffffff16421161077d57604051631c02820f60e21b815260040160405180910390fd5b600554600160281b900464ffffffffff1642106107cf576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044015b60405180910390fd5b600554600160501b900460ff16156107fa57604051631cdde67b60e01b815260040160405180910390fd5b565b7f000000000000000000000000000000000000000000000000000000000000000064ffffffffff1642106108435760405163ecdd1c2960e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663cd3293de6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c59190612c42565b6001600160a01b031663352e3a833386866040518463ffffffff1660e01b81526004016108f493929190612c5f565b60006040518083038186803b15801561090c57600080fd5b505afa158015610920573d6000803e3d6000fd5b5050505061093c6005805460ff60501b1916600160501b179055565b336001600160a01b03167faca80c800ec0d2aa9d9d31b7f886a1dd3067d4676abc637626a18ffb9381653d8383604051610977929190612cbb565b60405180910390a250505050565b6000808080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109d3576040516313bd2e8360e31b815260040160405180910390fd5b84600460008282546109e59190612cea565b90915550600090506109f56121d8565b905085811015610a03578095505b60008115610a29578187600254610a1a9190612c09565b610a249190612c20565b610a2c565b60005b9050610a378161223f565b610a436203f4806122fe565b6000610a4f898961233f565b600154600254604080518481526020810193909352820152909150600080516020612dfd8339815191529060600160405180910390a1506000546001600160a01b031698969750957f000000000000000000000000000000000000000000000000000000000000000062ffffff1695509350505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b0f576040516313bd2e8360e31b815260040160405180910390fd5b600554600160281b900464ffffffffff16421015610b40576040516302de694d60e41b815260040160405180910390fd5b60045415610b615760405163d26e2de960e01b815260040160405180910390fd5b6000610b6d848461233f565b600254909150156110a1576002546040516302dc1ca760e31b8152600481019190915262ffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906316e0e53890604401602060405180830381865afa158015610c0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c339190612cfd565b600254909150610c438285612d16565b10610de4576002546040516318af9f3960e11b81526001600160a01b038781166004830152602482019290925262ffffff7f00000000000000000000000000000000000000000000000000000000000000001660448201526000917f0000000000000000000000000000000000000000000000000000000000000000169063315f3e72906064016020604051808303816000875af1158015610ce9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0d9190612cfd565b9050818114610d1e57610d1e612d29565b6000546002546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116926323b872dd928a929190911690610d67868a612d16565b610d719190612cea565b6040518463ffffffff1660e01b8152600401610d8f93929190612d3f565b6020604051808303816000875af1158015610dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd29190612d63565b50610dde60025461223f565b5061109b565b6040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90610e3490889030908890600401612d3f565b6020604051808303816000875af1158015610e53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e779190612d63565b5081600003610fd5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d1fa5e983085600254610ebe9190612cea565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610f0457600080fd5b505af1158015610f18573d6000803e3d6000fd5b50506002546040516363b20c3360e11b8152600481019190915262ffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316925063c76418669150604401600060405180830381600087803b158015610fad57600080fd5b505af1158015610fc1573d6000803e3d6000fd5b50505050610fd060025461223f565b61109b565b60405163a47d75ad60e01b81526004810184905262ffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a47d75ad906044016020604051808303816000875af115801561106a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108e9190612cfd565b90506110998161223f565b505b5061113a565b6000546040516323b872dd60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116926323b872dd926110f592899216908790600401612d3f565b6020604051808303816000875af1158015611114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111389190612d63565b505b600080516020612dfd8339815191526111516121d8565b600154600254604080519384526020840192909252908201526060015b60405180910390a150505050565b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036111e0576003546111db907f0000000000000000000000000000000000000000000000000000000000000000612cea565b905090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a8a3e31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561123e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111db9190612cfd565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632f09177d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190612c42565b6001600160a01b0316336001600160a01b031614611305576113053361242f565b60006113118383612475565b600154600254604080518481526020810193909352820152909150600080516020612dfd833981519152906060015b60405180910390a1505050565b6040516323b872dd60e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906113a090339030908790600401612d3f565b6020604051808303816000875af11580156113bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e39190612d63565b5060405163a47d75ad60e01b81526004810183905262ffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a47d75ad906044016020604051808303816000875af1158015611479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149d9190612cfd565b90506114a88161223f565b600080516020612dfd8339815191526114bf6121d8565b6001546002546040805193845260208401929092529082015260600160405180910390a192915050565b6005546000906111db90600160281b900464ffffffffff16611de8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632f09177d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611564573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115889190612c42565b6001600160a01b0316336001600160a01b0316146115a9576115a93361242f565b60006115b36121d8565b90506115c08383836124dc565b600154600254604080518481526020810193909352820152600080516020612dfd83398151915290606001611340565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611639576040516313bd2e8360e31b815260040160405180910390fd5b600554600160281b900464ffffffffff164210611686576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044016107c6565b7f0000000000000000000000000000000000000000000000000000000000000000811080156116bb57506116b86121d8565b81105b156116d957604051633c80636b60e21b815260040160405180910390fd5b806000036116fa57604051633c80636b60e21b815260040160405180910390fd5b806004600082825461170c9190612d16565b909155505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461175d576040516313bd2e8360e31b815260040160405180910390fd5b806004600082825461176f9190612cea565b909155506117819050620151806122fe565b50565b60405163aa5dd7f160e01b81523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116917f00000000000000000000000000000000000000000000000000000000000000009091169063aa5dd7f190602401602060405180830381865afa15801561180e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118329190612c42565b6001600160a01b031614611859576040516313bd2e8360e31b815260040160405180910390fd5b806003600082825461170c9190612cea565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146118b4576040516313bd2e8360e31b815260040160405180910390fd5b600554600160281b900464ffffffffff16156118e25760405162dc149f60e41b815260040160405180910390fd5b428164ffffffffff16108061198557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634665096d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611950573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119749190612d80565b64ffffffffff168164ffffffffff16115b156119a357604051637d9533a960e11b815260040160405180910390fd5b806005806101000a81548164ffffffffff021916908364ffffffffff160217905550816001600160a01b031663a035b1fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a279190612cfd565b600155611a537f0000000000000000000000000000000000000000000000000000000000000000612744565b5050565b611a603361242f565b6000611a6a6121d8565b905080831115611b12576001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166323b872dd3330611aaf8588612cea565b6040518463ffffffff1660e01b8152600401611acd93929190612d3f565b6020604051808303816000875af1158015611aec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b109190612d63565b505b600254841015611c0b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663315f3e723386600254611b5a9190612cea565b6040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015262ffffff7f00000000000000000000000000000000000000000000000000000000000000001660448201526064016020604051808303816000875af1158015611bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf49190612cfd565b50611c0b84600254611c069190612cea565b61223f565b80831015611c2857611c2633611c218584612cea565b612475565b505b600254841115611c4a57611c4a3360025486611c449190612cea565b856124dc565b6001548214611c5c57611c5c826127a7565b6040805184815260208101849052908101859052600080516020612dfd8339815191529060600161116e565b611c913361242f565b611c9a816127a7565b600080516020612dfd833981519152611cb16121d8565b6001546002546040805193845260208401929092529082015260600160405180910390a150565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632c4e722e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7d9190612c42565b6001600160a01b03166306a7b3766040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dde9190612d9d565b6111db9190612dc2565b6000807f000000000000000000000000000000000000000000000000000000000000000064ffffffffff164210611e1f5742611e48565b7f000000000000000000000000000000000000000000000000000000000000000064ffffffffff165b90506000611e568285612cea565b905060006301e13380611e67611cd8565b611e769062ffffff1684612c09565b611e809190612c20565b9050620f42408111611e925780611e97565b620f42405b95945050505050565b60008115611f1f57611eb06114e9565b611edd7f0000000000000000000000000000000000000000000000000000000000000000620f4240612be6565b611ee79190612be6565b62ffffff166001611efb84620f4240612c09565b611f059190612cea565b611f0f9190612c20565b611f1a906001612d16565b61072d565b600092915050565b600080670de0b6b3a7640000600154611f3e6121d8565b611f489190612c09565b611f529190612c20565b905060008160025411611f7157600254611f6c9083612cea565b611f74565b60005b90507f000000000000000000000000000000000000000000000000000000000000000081600354611fa59190612d16565b10611fb35760009250505090565b806003547f0000000000000000000000000000000000000000000000000000000000000000611fe29190612cea565b611fec9190612cea565b9250505090565b60405163aa5dd7f160e01b81523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116917f00000000000000000000000000000000000000000000000000000000000000009091169063aa5dd7f190602401602060405180830381865afa15801561207d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a19190612c42565b6001600160a01b0316146120c8576040516313bd2e8360e31b815260040160405180910390fd5b806003600082825461170c9190612d16565b6120e33361242f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03160361212b576121268282611262565b505050565b60006121356121d8565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529192509085169063a9059cbb906044016020604051808303816000875af1158015612188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ac9190612d63565b506121b56121d8565b81146121c057600080fd5b50505050565b6121cf3361242f565b61178181612744565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561123e573d6000803e3d6000fd5b600254811115612272576002546122569082612cea565b604051635795d46960e11b81526004016107c691815260200190565b604051635be980f560e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635be980f590602401600060405180830381600087803b1580156122d457600080fd5b505af11580156122e8573d6000803e3d6000fd5b50505050806002600082825461170c9190612cea565b600061230a8242612dde565b60055490915064ffffffffff9081169082161115611a53576005805464ffffffffff831664ffffffffff199091161790555050565b600081156123dc5760405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156123b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123da9190612d63565b505b60006123e66121d8565b90507f0000000000000000000000000000000000000000000000000000000000000000811015612428576124286005805460ff60501b1916600160501b179055565b9392505050565b6000546001600160a01b0382811691161480159061245757506000546001600160a01b031615155b15611781576040516330cd747160e01b815260040160405180910390fd5b600454600090156124995760405163d26e2de960e01b815260040160405180910390fd5b60055464ffffffffff1642116124c257604051631c02820f60e21b815260040160405180910390fd5b60006124ce848461233f565b90506124288160015461288a565b600454156124fd5760405163d26e2de960e01b815260040160405180910390fd5b60055464ffffffffff16421161252657604051631c02820f60e21b815260040160405180910390fd5b600554600160281b900464ffffffffff164210612573576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044016107c6565b600554600160501b900460ff161561259e57604051631cdde67b60e01b815260040160405180910390fd5b6125a661117c565b8211156125d857816125b661117c565b604051634779077960e11b8152600481019290925260248201526044016107c6565b604051630cfb636f60e41b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cfb636f090602401600060405180830381600087803b15801561263a57600080fd5b505af115801561264e573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638112eb2b84847f00000000000000000000000000000000000000000000000000000000000000006126ac6114e9565b6040516001600160e01b031960e087901b1681526001600160a01b039094166004850152602484019290925262ffffff9081166044840152166064820152608401600060405180830381600087803b15801561270757600080fd5b505af115801561271b573d6000803e3d6000fd5b5050505081600260008282546127319190612d16565b925050819055506121268160015461288a565b6001600160a01b03811661275757600080fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600454156127c85760405163d26e2de960e01b815260040160405180910390fd5b600554600160281b900464ffffffffff164210612815576005546040516238ddd760e41b815264ffffffffff4281166004830152600160281b9092049190911660248201526044016107c6565b600554600160501b900460ff161561284057604051631cdde67b60e01b815260040160405180910390fd5b60015481111561285b576128566203f4806122fe565b61286c565b61286c6128666121d8565b8261288a565b6117818161287861117c565b6002546128859190612d16565b612926565b60007f000000000000000000000000000000000000000000000000000000000000000083106128b957826128bc565b60005b9050670de0b6b3a76400006002546128d49190612c09565b6128de8383612c09565b1015612126576128ee8282612c09565b670de0b6b3a76400006002546129049190612c09565b604051632c1f8ef160e21b8152600481019290925260248201526044016107c6565b612938670de0b6b3a764000082612c09565b6129627f000000000000000000000000000000000000000000000000000000000000000084612c09565b111561296d57600080fd5b50600155565b801515811461178157600080fd5b6000806040838503121561299457600080fd5b8235915060208301356129a681612973565b809150509250929050565b600080600080604085870312156129c757600080fd5b843567ffffffffffffffff808211156129df57600080fd5b818701915087601f8301126129f357600080fd5b813581811115612a0257600080fd5b8860208260051b8501011115612a1757600080fd5b602092830196509450908601359080821115612a3257600080fd5b818701915087601f830112612a4657600080fd5b813581811115612a5557600080fd5b886020828501011115612a6757600080fd5b95989497505060200194505050565b6001600160a01b038116811461178157600080fd5b60008060408385031215612a9e57600080fd5b8235612aa981612a76565b946020939093013593505050565b600080600060608486031215612acc57600080fd5b8335612ad781612a76565b95602085013595506040909401359392505050565b600060208284031215612afe57600080fd5b5035919050565b64ffffffffff8116811461178157600080fd5b60008060408385031215612b2b57600080fd5b8235612b3681612a76565b915060208301356129a681612b05565b600080600060608486031215612b5b57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215612b8757600080fd5b8335612b9281612a76565b92506020840135612ba281612a76565b929592945050506040919091013590565b600060208284031215612bc557600080fd5b813561242881612a76565b634e487b7160e01b600052601160045260246000fd5b62ffffff828116828216039080821115612c0257612c02612bd0565b5092915050565b808202811582820484141761072d5761072d612bd0565b600082612c3d57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215612c5457600080fd5b815161242881612a76565b6001600160a01b03848116825260406020808401829052908301849052600091859160608501845b87811015612cae578435612c9a81612a76565b841682529382019390820190600101612c87565b5098975050505050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b8181038181111561072d5761072d612bd0565b600060208284031215612d0f57600080fd5b5051919050565b8082018082111561072d5761072d612bd0565b634e487b7160e01b600052600160045260246000fd5b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215612d7557600080fd5b815161242881612973565b600060208284031215612d9257600080fd5b815161242881612b05565b600060208284031215612daf57600080fd5b815162ffffff8116811461242857600080fd5b62ffffff818116838216019080821115612c0257612c02612bd0565b64ffffffffff818116838216019080821115612c0257612c02612bd056fe9483a26ad376f30b5199a79e75df3bb05158c4ee32a348f53e83245a5e50c86ea26469706673582212203d0e7cc7b31f042803c803a5def335273b3b31f8d50db1473e0cc88de51eebc764736f6c6343000814003300000000000000000000000001dd57a2c68b5e6819ebde2cec64f4000438d9bb000000000000000000000000de12b620a8a714476a97efd14e6f7180ca653557000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb000000000000000000000000343324f53cbeee3ee6d171f2a20f005964c9804700000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000d3c21bcecceda100000000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000001da9c0000000000000000000000000000000000000000000000000000000000000546000000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000f0bdc21abb48db201e86d40000000000000000000000000000000000000000000000000000000000000000000061a80","name":"Position","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"paris","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"IReserve.sol","source_code":"// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\nimport \"./IERC20.sol\";\r\n\r\ninterface IReserve is IERC20 {\r\n   function invest(uint256 amount, uint256 expected) external returns (uint256);\r\n   function checkQualified(address sender, address[] calldata helpers) external view;\r\n}"},{"file_path":"IFrankencoin.sol","source_code":"// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\nimport \"./IERC20.sol\";\r\nimport \"./IReserve.sol\";\r\n\r\ninterface IFrankencoin is IERC20 {\r\n    function suggestMinter(address _minter, uint256 _applicationPeriod, uint256 _applicationFee, string calldata _message) external;\r\n\r\n    function registerPosition(address position) external;\r\n\r\n    function denyMinter(address minter, address[] calldata helpers, string calldata message) external;\r\n\r\n    function reserve() external view returns (IReserve);\r\n\r\n    function minterReserve() external view returns (uint256);\r\n\r\n    function calculateAssignedReserve(uint256 mintedAmount, uint32 _reservePPM) external view returns (uint256);\r\n\r\n    function calculateFreedAmount(uint256 amountExcludingReserve, uint32 reservePPM) external view returns (uint256);\r\n\r\n    function equity() external view returns (uint256);\r\n\r\n    function isMinter(address minter) external view returns (bool);\r\n\r\n    function getPositionParent(address position) external view returns (address);\r\n\r\n    function mint(address target, uint256 amount) external;\r\n\r\n    function mintWithReserve(address target, uint256 amount, uint32 reservePPM, uint32 feePPM) external;\r\n\r\n    function burnFrom(address target, uint256 amount) external;\r\n\r\n    function burnWithoutReserve(uint256 amountIncludingReserve, uint32 reservePPM) external;\r\n\r\n    function burnFromWithReserve(address payer, uint256 targetTotalBurnAmount, uint32 _reservePPM) external returns (uint256);\r\n\r\n    function burnWithReserve(uint256 amountExcludingReserve, uint32 reservePPM) external returns (uint256);\r\n\r\n    function coverLoss(address source, uint256 amount) external;\r\n\r\n    function collectProfits(address source, uint256 _amount) external;\r\n}\r\n"},{"file_path":"IERC20.sol","source_code":"/**\r\n * SPDX-License-Identifier: MIT\r\n *\r\n * Copyright (c) 2016-2019 zOS Global Limited\r\n *\r\n */\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\r\n * the optional functions; to access them see `ERC20Detailed`.\r\n */\r\n\r\ninterface IERC20 {\r\n    function name() external view returns (string memory);\r\n\r\n    function symbol() external view returns (string memory);\r\n\r\n    function decimals() external view returns (uint8);\r\n\r\n    /**\r\n     * @dev Returns the amount of tokens in existence.\r\n     */\r\n    function totalSupply() external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Returns the amount of tokens owned by `account`.\r\n     */\r\n    function balanceOf(address account) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\r\n     *\r\n     * Returns always true. Throws error on failure.\r\n     *\r\n     * Emits a `Transfer` event.\r\n     */\r\n    function transfer(address recipient, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Returns the remaining number of tokens that `spender` will be\r\n     * allowed to spend on behalf of `owner` through `transferFrom`. This is\r\n     * zero by default.\r\n     *\r\n     * This value can change when `approve` or `transferFrom` are called.\r\n     */\r\n    function allowance(address owner, address spender) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\r\n     *\r\n     * Returns a boolean value indicating whether the operation succeeded.\r\n     *\r\n     * > Beware that changing an allowance with this method brings the risk\r\n     * that someone may use both the old and the new allowance by unfortunate\r\n     * transaction ordering. One possible solution to mitigate this race\r\n     * condition is to first reduce the spender's allowance to 0 and set the\r\n     * desired value afterwards:\r\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n     *\r\n     * Emits an `Approval` event.\r\n     */\r\n    function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\r\n     * allowance mechanism. `amount` is then deducted from the caller's\r\n     * allowance.\r\n     *\r\n     * Returns always true. Throws error on failure.\r\n     *\r\n     * Emits a `Transfer` event.\r\n     */\r\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n     * another (`to`).\r\n     *\r\n     * Note that `value` may be zero.\r\n     */\r\n    event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n    /**\r\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n     * a call to `approve`. `value` is the new allowance.\r\n     */\r\n    event Approval(address indexed owner, address indexed spender, uint256 value);\r\n}\r\n"},{"file_path":"ILeadrate.sol","source_code":"// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\ninterface ILeadrate {\r\n   function currentRatePPM() external view returns (uint24);\r\n   function currentTicks() external view returns (uint64);\r\n}"},{"file_path":"IPosition.sol","source_code":"// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\nimport './IERC20.sol';\r\n\r\ninterface IPosition {\r\n\tfunction hub() external view returns (address);\r\n\r\n\tfunction collateral() external view returns (IERC20);\r\n\r\n\tfunction minimumCollateral() external view returns (uint256);\r\n\r\n\tfunction price() external view returns (uint256);\r\n\r\n\tfunction minted() external view returns (uint256);\r\n\r\n\tfunction challengedAmount() external view returns (uint256);\r\n\r\n\tfunction original() external view returns (address);\r\n\r\n\tfunction expiration() external view returns (uint40);\r\n\r\n\tfunction cooldown() external view returns (uint40);\r\n\r\n\tfunction limit() external view returns (uint256);\r\n\r\n\tfunction challengePeriod() external view returns (uint40);\r\n\r\n\tfunction start() external view returns (uint40);\r\n\r\n\tfunction riskPremiumPPM() external view returns (uint24);\r\n\r\n\tfunction reserveContribution() external view returns (uint24);\r\n\r\n\tfunction initialize(address parent, uint40 _expiration) external;\r\n\r\n\tfunction assertCloneable() external;\r\n\r\n\tfunction notifyMint(uint256 mint_) external;\r\n\r\n\tfunction notifyRepaid(uint256 repaid_) external;\r\n\r\n\tfunction availableForClones() external view returns (uint256);\r\n\r\n\tfunction availableForMinting() external view returns (uint256);\r\n\r\n\tfunction deny(address[] calldata helpers, string calldata message) external;\r\n\r\n\tfunction getUsableMint(uint256 totalMint, bool afterFees) external view returns (uint256);\r\n\r\n\tfunction getMintAmount(uint256 usableMint) external view returns (uint256);\r\n\r\n\tfunction adjust(uint256 newMinted, uint256 newCollateral, uint256 newPrice) external;\r\n\r\n\tfunction adjustPrice(uint256 newPrice) external;\r\n\r\n\tfunction mint(address target, uint256 amount) external;\r\n\r\n\tfunction calculateCurrentFee() external view returns (uint24);\r\n\r\n\tfunction annualInterestPPM() external view returns (uint24);\r\n\r\n\tfunction calculateFee(uint256 exp) external view returns (uint24);\r\n\r\n\tfunction repay(uint256 amount) external returns (uint256);\r\n\r\n\tfunction forceSale(address buyer, uint256 collAmount, uint256 proceeds) external;\r\n\r\n\tfunction withdraw(address token, address target, uint256 amount) external;\r\n\r\n\tfunction withdrawCollateral(address target, uint256 amount) external;\r\n\r\n\tfunction challengeData() external view returns (uint256 liqPrice, uint40 phase);\r\n\r\n\tfunction notifyChallengeStarted(uint256 size) external;\r\n\r\n\tfunction notifyChallengeAverted(uint256 size) external;\r\n\r\n\tfunction notifyChallengeSucceeded(address _bidder, uint256 _size) external returns (address, uint256, uint256, uint32);\r\n}\r\n"},{"file_path":"MathUtil.sol","source_code":"// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @title Functions for share valuation\r\n */\r\ncontract MathUtil {\r\n    uint256 internal constant ONE_DEC18 = 10 ** 18;\r\n\r\n    // Let's go for 12 digits of precision (18-6)\r\n    uint256 internal constant THRESH_DEC18 = 10 ** 6;\r\n\r\n    /**\r\n     * @notice Cubic root with Halley approximation\r\n     *         Number 1e18 decimal\r\n     * @param _v     number for which we calculate x**(1/3)\r\n     * @return returns _v**(1/3)\r\n     */\r\n    function _cubicRoot(uint256 _v) internal pure returns (uint256) {\r\n        // Good first guess for _v slightly above 1.0, which is often the case in the Frankencoin system\r\n        uint256 x = _v > ONE_DEC18 && _v < 10 ** 19 ? (_v - ONE_DEC18) / 3 + ONE_DEC18 : ONE_DEC18;\r\n        uint256 diff;\r\n        do {\r\n            uint256 powX3 = _mulD18(_mulD18(x, x), x);\r\n            uint256 xnew = x * (powX3 + 2 * _v) / (2 * powX3 + _v);\r\n            diff = xnew > x ? xnew - x : x - xnew;\r\n            x = xnew;\r\n        } while (diff > THRESH_DEC18);\r\n        return x;\r\n    }\r\n\r\n    function _mulD18(uint256 _a, uint256 _b) internal pure returns (uint256) {\r\n        return (_a * _b) / ONE_DEC18;\r\n    }\r\n\r\n    function _divD18(uint256 _a, uint256 _b) internal pure returns (uint256) {\r\n        return (_a * ONE_DEC18) / _b;\r\n    }\r\n\r\n    function _power3(uint256 _x) internal pure returns (uint256) {\r\n        return _mulD18(_mulD18(_x, _x), _x);\r\n    }\r\n\r\n    function _min(uint256 a, uint256 b) internal pure returns (uint256) {\r\n        return a < b ? a : b;\r\n    }\r\n}\r\n"},{"file_path":"Ownable.sol","source_code":"// SPDX-License-Identifier: MIT\r\n//\r\n// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\r\n//\r\n// Modifications:\r\n// - Replaced Context._msgSender() with msg.sender\r\n// - Made leaner\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * By default, the owner account will be the one that deploys the contract. This\r\n * can later be changed with {transferOwnership}.\r\n */\r\ncontract Ownable {\r\n\r\n    address public owner;\r\n\r\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n    error NotOwner();\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Can only be called by the current owner.\r\n     */\r\n    function transferOwnership(address newOwner) public onlyOwner {\r\n        _setOwner(newOwner);\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Internal function without access restriction.\r\n     */\r\n    function _setOwner(address newOwner) internal {\r\n        require(newOwner != address(0x0)); // ensure initialization can only done once\r\n        address oldOwner = owner;\r\n        owner = newOwner;\r\n        emit OwnershipTransferred(oldOwner, newOwner);\r\n    }\r\n\r\n    function _requireOwner(address sender) internal view {\r\n        if (owner != sender && owner != address(0x0)) revert NotOwner();\r\n    }\r\n\r\n    modifier onlyOwner() {\r\n        _requireOwner(msg.sender);\r\n        _;\r\n    }\r\n}\r\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_hub","type":"address"},{"internalType":"address","name":"_zchf","type":"address"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"uint256","name":"_minCollateral","type":"uint256"},{"internalType":"uint256","name":"_initialLimit","type":"uint256"},{"internalType":"uint40","name":"_initPeriod","type":"uint40"},{"internalType":"uint40","name":"_duration","type":"uint40"},{"internalType":"uint40","name":"_challengePeriod","type":"uint40"},{"internalType":"uint24","name":"_riskPremiumPPM","type":"uint24"},{"internalType":"uint256","name":"_liqPrice","type":"uint256"},{"internalType":"uint24","name":"_reservePPM","type":"uint24"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Alive","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ChallengeTooSmall","type":"error"},{"inputs":[],"name":"Challenged","type":"error"},{"inputs":[],"name":"Closed","type":"error"},{"inputs":[{"internalType":"uint40","name":"time","type":"uint40"},{"internalType":"uint40","name":"expiration","type":"uint40"}],"name":"Expired","type":"error"},{"inputs":[],"name":"Hot","type":"error"},{"inputs":[{"internalType":"uint256","name":"needed","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"name":"InsufficientCollateral","type":"error"},{"inputs":[],"name":"InvalidExpiration","type":"error"},{"inputs":[{"internalType":"uint256","name":"tried","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"name":"LimitExceeded","type":"error"},{"inputs":[],"name":"NotHub","type":"error"},{"inputs":[],"name":"NotOriginal","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[{"internalType":"uint256","name":"excess","type":"uint256"}],"name":"RepaidTooMuch","type":"error"},{"inputs":[],"name":"TooLate","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"collateral","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minted","type":"uint256"}],"name":"MintingUpdate","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":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"PositionDenied","type":"event"},{"inputs":[{"internalType":"uint256","name":"newMinted","type":"uint256"},{"internalType":"uint256","name":"newCollateral","type":"uint256"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"adjust","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"adjustPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"annualInterestPPM","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assertCloneable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"availableForClones","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableForMinting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateCurrentFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"exp","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengeData","outputs":[{"internalType":"uint256","name":"liqPrice","type":"uint256"},{"internalType":"uint40","name":"phase","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengePeriod","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cooldown","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"helpers","type":"address[]"},{"internalType":"string","name":"message","type":"string"}],"name":"deny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"expiration","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"collAmount","type":"uint256"},{"internalType":"uint256","name":"proceeds","type":"uint256"}],"name":"forceSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"usableMint","type":"uint256"}],"name":"getMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"totalMint","type":"uint256"},{"internalType":"bool","name":"afterFees","type":"bool"}],"name":"getUsableMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hub","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"parent","type":"address"},{"internalType":"uint40","name":"_expiration","type":"uint40"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isClosed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"size","type":"uint256"}],"name":"notifyChallengeAverted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"size","type":"uint256"}],"name":"notifyChallengeStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bidder","type":"address"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"notifyChallengeSucceeded","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mint_","type":"uint256"}],"name":"notifyMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"repaid_","type":"uint256"}],"name":"notifyRepaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"original","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"repay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveContribution","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"riskPremiumPPM","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"zchf","outputs":[{"internalType":"contract IFrankencoin","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x00000000000000000000000001dd57a2c68b5e6819ebde2cec64f4000438d9bb000000000000000000000000de12b620a8a714476a97efd14e6f7180ca653557000000000000000000000000b58e61c3098d85632df34eecfb899a1ed80921cb000000000000000000000000343324f53cbeee3ee6d171f2a20f005964c9804700000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000d3c21bcecceda100000000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000001da9c0000000000000000000000000000000000000000000000000000000000000546000000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000f0bdc21abb48db201e86d40000000000000000000000000000000000000000000000000000000000000000000061a80"}