Source Code
Overview
FTM Balance
More Info
ContractCreator:
Multi Chain
Multichain Addresses
0 address found via
Latest 25 from a total of 14,604 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Burst | 22833464 | 1 hr 25 mins ago | IN | 1.77567739 FTM | 0.00068172 | ||||
Burst | 22832236 | 3 hrs 4 mins ago | IN | 6.55069015 FTM | 0.00082389 | ||||
Burst | 22828290 | 7 hrs 17 mins ago | IN | 0.03872171 FTM | 0.00057551 | ||||
Burst | 22827558 | 7 hrs 57 mins ago | IN | 3.46761197 FTM | 0.0007357 | ||||
Burst | 22825902 | 9 hrs 45 mins ago | IN | 3.52926195 FTM | 0.00073064 | ||||
Burst | 22823153 | 12 hrs 35 mins ago | IN | 3.59684146 FTM | 0.00081171 | ||||
Burst | 22823071 | 12 hrs 41 mins ago | IN | 3.59230451 FTM | 0.0007477 | ||||
Burst | 22823062 | 12 hrs 41 mins ago | IN | 3.59230451 FTM | 0.00073549 | ||||
Burst | 22818865 | 17 hrs 4 mins ago | IN | 3.59230451 FTM | 0.00087364 | ||||
Burst | 22811550 | 1 day 1 hr ago | IN | 3.59230451 FTM | 0.00074761 | ||||
Burst | 22808649 | 1 day 4 hrs ago | IN | 0.03878555 FTM | 0.00068163 | ||||
Burst | 22808539 | 1 day 4 hrs ago | IN | 3.59230451 FTM | 0.0010944 | ||||
Burst | 22807437 | 1 day 5 hrs ago | IN | 2.0862298 FTM | 0.00097274 | ||||
Burst | 22807436 | 1 day 5 hrs ago | IN | 2.0862298 FTM | 0.00069022 | ||||
Burst | 22804851 | 1 day 7 hrs ago | IN | 3.59230451 FTM | 0.00074767 | ||||
Burst | 22804805 | 1 day 7 hrs ago | IN | 3.59230451 FTM | 0.00074773 | ||||
Burst | 22800171 | 1 day 11 hrs ago | IN | 3.59230451 FTM | 0.00074755 | ||||
Burst | 22798737 | 1 day 13 hrs ago | IN | 2.0862298 FTM | 0.00075428 | ||||
Burst | 22798460 | 1 day 13 hrs ago | IN | 1.77567739 FTM | 0.00075787 | ||||
Burst | 22798450 | 1 day 13 hrs ago | IN | 3.59230451 FTM | 0.00073555 | ||||
Burst | 22798444 | 1 day 13 hrs ago | IN | 3.59230451 FTM | 0.00073734 | ||||
Burst | 22797684 | 1 day 14 hrs ago | IN | 3.59230451 FTM | 0.00109428 | ||||
Burst | 22792459 | 1 day 18 hrs ago | IN | 0.03842178 FTM | 0.00037408 | ||||
Burst | 22792439 | 1 day 18 hrs ago | IN | 3.59230451 FTM | 0.00059969 | ||||
Burst | 22791716 | 1 day 18 hrs ago | IN | 3.59230451 FTM | 0.00092261 |
Latest 25 internal transactions (View All)
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
22833464 | 1 hr 25 mins ago | 1.77567739 FTM | ||||
22832236 | 3 hrs 4 mins ago | 6.55069015 FTM | ||||
22828290 | 7 hrs 17 mins ago | 0.03872171 FTM | ||||
22827558 | 7 hrs 57 mins ago | 3.46761197 FTM | ||||
22825902 | 9 hrs 45 mins ago | 3.52926195 FTM | ||||
22823153 | 12 hrs 35 mins ago | 3.59684146 FTM | ||||
22823071 | 12 hrs 41 mins ago | 3.59230451 FTM | ||||
22823062 | 12 hrs 41 mins ago | 3.59230451 FTM | ||||
22818865 | 17 hrs 4 mins ago | 3.59230451 FTM | ||||
22811550 | 1 day 1 hr ago | 3.59230451 FTM | ||||
22808649 | 1 day 4 hrs ago | 0.03878555 FTM | ||||
22808539 | 1 day 4 hrs ago | 3.59230451 FTM | ||||
22807437 | 1 day 5 hrs ago | 2.0862298 FTM | ||||
22807436 | 1 day 5 hrs ago | 2.0862298 FTM | ||||
22804851 | 1 day 7 hrs ago | 3.59230451 FTM | ||||
22804805 | 1 day 7 hrs ago | 3.59230451 FTM | ||||
22800171 | 1 day 11 hrs ago | 3.59230451 FTM | ||||
22798737 | 1 day 13 hrs ago | 2.0862298 FTM | ||||
22798460 | 1 day 13 hrs ago | 1.77567739 FTM | ||||
22798450 | 1 day 13 hrs ago | 3.59230451 FTM | ||||
22798444 | 1 day 13 hrs ago | 3.59230451 FTM | ||||
22797684 | 1 day 14 hrs ago | 3.59230451 FTM | ||||
22792459 | 1 day 18 hrs ago | 0.03842178 FTM | ||||
22792439 | 1 day 18 hrs ago | 3.59230451 FTM | ||||
22791716 | 1 day 18 hrs ago | 3.59230451 FTM |
Loading...
Loading
Contract Name:
MagnetarV2
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 300 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; //OZ import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; //TAPIOCA import "./MagnetarV2Storage.sol"; import "./modules/MagnetarMarketModule.sol"; import "../interfaces/IPenrose.sol"; /* __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____ _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__ _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_ _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_ _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_ _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_ _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_ _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__ */ contract MagnetarV2 is Ownable, MagnetarV2Storage { using SafeERC20 for IERC20; using RebaseLibrary for Rebase; // ************ // // *** VARS *** // // ************ // enum Module { Market } /// @notice returns the Market module MagnetarMarketModule public marketModule; constructor(address _owner, address payable _marketModule) { transferOwnership(_owner); marketModule = MagnetarMarketModule(_marketModule); } // ******************** // // *** VIEW METHODS *** // // ******************** // /// @notice returns Singularity markets' information /// @param who user to return for /// @param markets the list of Singularity markets to query for function singularityMarketInfo( address who, ISingularity[] calldata markets ) external view returns (SingularityInfo[] memory) { return _singularityMarketInfo(who, markets); } /// @notice returns BigBang markets' information /// @param who user to return for /// @param markets the list of BigBang markets to query for function bigBangMarketInfo( address who, IBigBang[] calldata markets ) external view returns (BigBangInfo[] memory) { return _bigBangMarketInfo(who, markets); } /// @notice Calculate the collateral shares that are needed for `borrowPart`, /// taking the current exchange rate into account. /// @param market the Singularity or BigBang address /// @param borrowPart The borrow part. /// @return collateralShares The collateral shares. function getCollateralSharesForBorrowPart( IMarket market, uint256 borrowPart, uint256 liquidationMultiplierPrecision, uint256 exchangeRatePrecision ) public view returns (uint256 collateralShares) { Rebase memory _totalBorrowed; (uint128 totalBorrowElastic, uint128 totalBorrowBase) = market .totalBorrow(); _totalBorrowed = Rebase(totalBorrowElastic, totalBorrowBase); IYieldBoxBase yieldBox = IYieldBoxBase(market.yieldBox()); uint256 borrowAmount = _totalBorrowed.toElastic(borrowPart, false); return yieldBox.toShare( market.collateralId(), (borrowAmount * market.liquidationMultiplier() * market.exchangeRate()) / (liquidationMultiplierPrecision * exchangeRatePrecision), false ); } /// @notice Return the equivalent of borrow part in asset amount. /// @param market the Singularity or BigBang address /// @param borrowPart The amount of borrow part to convert. /// @return amount The equivalent of borrow part in asset amount. function getAmountForBorrowPart( IMarket market, uint256 borrowPart ) public view returns (uint256 amount) { Rebase memory _totalBorrowed; (uint128 totalBorrowElastic, uint128 totalBorrowBase) = market .totalBorrow(); _totalBorrowed = Rebase(totalBorrowElastic, totalBorrowBase); return _totalBorrowed.toElastic(borrowPart, false); } /// @notice Return the equivalent of amount in borrow part. /// @param market the Singularity or BigBang address /// @param amount The amount to convert. /// @return part The equivalent of amount in borrow part. function getBorrowPartForAmount( IMarket market, uint256 amount ) public view returns (uint256 part) { Rebase memory _totalBorrowed; (uint128 totalBorrowElastic, uint128 totalBorrowBase) = market .totalBorrow(); _totalBorrowed = Rebase(totalBorrowElastic, totalBorrowBase); return _totalBorrowed.toBase(amount, false); } /// @notice Compute the amount of `singularity.assetId` from `fraction` /// `fraction` can be `singularity.accrueInfo.feeFraction` or `singularity.balanceOf` /// @param singularity the singularity address /// @param fraction The fraction. /// @return amount The amount. function getAmountForAssetFraction( ISingularity singularity, uint256 fraction ) public view returns (uint256 amount) { (uint128 totalAssetElastic, uint128 totalAssetBase) = singularity .totalAsset(); IYieldBoxBase yieldBox = IYieldBoxBase(singularity.yieldBox()); return yieldBox.toAmount( singularity.assetId(), (fraction * totalAssetElastic) / totalAssetBase, false ); } /// @notice Compute the fraction of `singularity.assetId` from `amount` /// `fraction` can be `singularity.accrueInfo.feeFraction` or `singularity.balanceOf` /// @param singularity the singularity address /// @param amount The amount. /// @return fraction The fraction. function getFractionForAmount( ISingularity singularity, uint256 amount ) public view returns (uint256 fraction) { (uint128 totalAssetShare, uint128 totalAssetBase) = singularity .totalAsset(); (uint128 totalBorrowElastic, ) = singularity.totalBorrow(); uint256 assetId = singularity.assetId(); IYieldBoxBase yieldBox = IYieldBoxBase(singularity.yieldBox()); uint256 share = yieldBox.toShare(assetId, amount, false); uint256 allShare = totalAssetShare + yieldBox.toShare(assetId, totalBorrowElastic, true); fraction = allShare == 0 ? share : (share * totalAssetBase) / allShare; } // ********************** // // *** PUBLIC METHODS *** // // ********************** // /// @notice Batch multiple calls together /// @param calls The list of actions to perform function burst( Call[] calldata calls ) external payable returns (Result[] memory returnData) { uint256 valAccumulator; uint256 length = calls.length; returnData = new Result[](length); for (uint256 i = 0; i < length; i++) { Call calldata _action = calls[i]; if (!_action.allowFailure) { require( _action.call.length > 0, string.concat( "MagnetarV2: Missing call for action with index", string(abi.encode(i)) ) ); } unchecked { valAccumulator += _action.value; } if (_action.id == PERMIT_ALL) { _permit( _action.target, _action.call, true, _action.allowFailure ); } else if (_action.id == PERMIT) { _permit( _action.target, _action.call, false, _action.allowFailure ); } else if (_action.id == TOFT_WRAP) { WrapData memory data = abi.decode(_action.call[4:], (WrapData)); _checkSender(data.from); if (_action.value > 0) { unchecked { valAccumulator += _action.value; } ITapiocaOFT(_action.target).wrapNative{ value: _action.value }(data.to); } else { ITapiocaOFT(_action.target).wrap( msg.sender, data.to, data.amount ); } } else if (_action.id == TOFT_SEND_FROM) { ( address from, uint16 dstChainId, bytes32 to, uint256 amount, ISendFrom.LzCallParams memory lzCallParams ) = abi.decode( _action.call[4:], ( address, uint16, bytes32, uint256, (ISendFrom.LzCallParams) ) ); _checkSender(from); ISendFrom(_action.target).sendFrom{value: _action.value}( msg.sender, dstChainId, to, amount, lzCallParams ); } else if (_action.id == YB_DEPOSIT_ASSET) { YieldBoxDepositData memory data = abi.decode( _action.call[4:], (YieldBoxDepositData) ); _checkSender(data.from); (uint256 amountOut, uint256 shareOut) = IYieldBoxBase( _action.target ).depositAsset( data.assetId, msg.sender, data.to, data.amount, data.share ); returnData[i] = Result({ success: true, returnData: abi.encode(amountOut, shareOut) }); } else if (_action.id == MARKET_ADD_COLLATERAL) { SGLAddCollateralData memory data = abi.decode( _action.call[4:], (SGLAddCollateralData) ); _checkSender(data.from); IMarket(_action.target).addCollateral( msg.sender, data.to, data.skim, data.amount, data.share ); } else if (_action.id == MARKET_BORROW) { SGLBorrowData memory data = abi.decode( _action.call[4:], (SGLBorrowData) ); _checkSender(data.from); (uint256 part, uint256 share) = IMarket(_action.target).borrow( msg.sender, data.to, data.amount ); returnData[i] = Result({ success: true, returnData: abi.encode(part, share) }); } else if (_action.id == YB_WITHDRAW_TO) { ( address yieldBox, address from, uint256 assetId, uint16 dstChainId, bytes32 receiver, uint256 amount, uint256 share, bytes memory adapterParams, address payable refundAddress ) = abi.decode( _action.call[4:], ( address, address, uint256, uint16, bytes32, uint256, uint256, bytes, address ) ); _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.withdrawTo.selector, yieldBox, from, assetId, dstChainId, receiver, amount, share, adapterParams, refundAddress, _action.value ) ); } else if (_action.id == MARKET_LEND) { SGLLendData memory data = abi.decode( _action.call[4:], (SGLLendData) ); _checkSender(data.from); uint256 fraction = IMarket(_action.target).addAsset( msg.sender, data.to, data.skim, data.share ); returnData[i] = Result({ success: true, returnData: abi.encode(fraction) }); } else if (_action.id == MARKET_REPAY) { SGLRepayData memory data = abi.decode( _action.call[4:], (SGLRepayData) ); _checkSender(data.from); uint256 amount = IMarket(_action.target).repay( msg.sender, data.to, data.skim, data.part ); returnData[i] = Result({ success: true, returnData: abi.encode(amount) }); } else if (_action.id == TOFT_SEND_AND_BORROW) { ( address from, address to, uint16 lzDstChainId, bytes memory airdropAdapterParams, ITapiocaOFT.IBorrowParams memory borrowParams, ITapiocaOFT.IWithdrawParams memory withdrawParams, ITapiocaOFT.ISendOptions memory options, ITapiocaOFT.IApproval[] memory approvals ) = abi.decode( _action.call[4:], ( address, address, uint16, bytes, ITapiocaOFT.IBorrowParams, ITapiocaOFT.IWithdrawParams, ITapiocaOFT.ISendOptions, ITapiocaOFT.IApproval[] ) ); _checkSender(from); ITapiocaOFT(_action.target).sendToYBAndBorrow{ value: _action.value }( msg.sender, to, lzDstChainId, airdropAdapterParams, borrowParams, withdrawParams, options, approvals ); } else if (_action.id == TOFT_SEND_AND_LEND) { ( address from, address to, uint16 dstChainId, address zroPaymentAddress, IUSDOBase.ILendParams memory lendParams, IUSDOBase.IApproval[] memory approvals, IUSDOBase.IWithdrawParams memory withdrawParams, bytes memory adapterParams ) = abi.decode( _action.call[4:], ( address, address, uint16, address, (IUSDOBase.ILendParams), (IUSDOBase.IApproval[]), (IUSDOBase.IWithdrawParams), bytes ) ); _checkSender(from); IUSDOBase(_action.target).sendAndLendOrRepay{ value: _action.value }( msg.sender, to, dstChainId, zroPaymentAddress, lendParams, approvals, withdrawParams, adapterParams ); } else if (_action.id == TOFT_DEPOSIT_TO_STRATEGY) { TOFTSendToStrategyData memory data = abi.decode( _action.call[4:], (TOFTSendToStrategyData) ); _checkSender(data.from); ITapiocaOFT(_action.target).sendToStrategy{ value: _action.value }( msg.sender, data.to, data.amount, data.share, data.assetId, data.lzDstChainId, data.options ); } else if (_action.id == TOFT_RETRIEVE_FROM_STRATEGY) { ( address from, uint256 amount, uint256 share, uint256 assetId, uint16 lzDstChainId, address zroPaymentAddress, bytes memory airdropAdapterParam ) = abi.decode( _action.call[4:], ( address, uint256, uint256, uint256, uint16, address, bytes ) ); _checkSender(from); ITapiocaOFT(_action.target).retrieveFromStrategy{ value: _action.value }( msg.sender, amount, share, assetId, lzDstChainId, zroPaymentAddress, airdropAdapterParam ); } else if (_action.id == MARKET_YBDEPOSIT_AND_LEND) { HelperLendData memory data = abi.decode( _action.call[4:], (HelperLendData) ); _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.depositAndAddAsset.selector, data.market, data.from, data.amount, data.deposit, false ) ); } else if (_action.id == MARKET_YBDEPOSIT_COLLATERAL_AND_BORROW) { ( address market, address user, uint256 collateralAmount, uint256 borrowAmount, , bool deposit, bool withdraw, bytes memory withdrawData ) = abi.decode( _action.call[4:], ( address, address, uint256, uint256, bool, bool, bool, bytes ) ); _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule .depositAddCollateralAndBorrow .selector, market, user, collateralAmount, borrowAmount, false, deposit, withdraw, withdrawData ) ); } else if (_action.id == MARKET_REMOVE_ASSET) { HelperRemoveAssetData memory data = abi.decode( _action.call[4:], (HelperRemoveAssetData) ); _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.removeAsset.selector, data.market, data.user, data.fraction ) ); } else if (_action.id == MARKET_DEPOSIT_REPAY_REMOVE_COLLATERAL) { HelperDepositRepayRemoveCollateral memory data = abi.decode( _action.call[4:], (HelperDepositRepayRemoveCollateral) ); _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule .depositRepayAndRemoveCollateral .selector, data.market, data.user, data.depositAmount, data.repayAmount, data.collateralAmount, data.deposit, data.withdraw, data.extractFromSender ) ); } else { revert("MagnetarV2: action not valid"); } } require(msg.value == valAccumulator, "MagnetarV2: value mismatch"); } function withdrawTo( IYieldBoxBase yieldBox, address from, uint256 assetId, uint16 dstChainId, bytes32 receiver, uint256 amount, uint256 share, bytes memory adapterParams, address payable refundAddress, uint256 gas ) external payable { _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.withdrawTo.selector, yieldBox, from, assetId, dstChainId, receiver, amount, share, adapterParams, refundAddress, gas ) ); } function depositAddCollateralAndBorrow( IMarket market, address user, uint256 collateralAmount, uint256 borrowAmount, bool extractFromSender, bool deposit, bool withdraw, bytes memory withdrawData ) external payable { _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.depositAddCollateralAndBorrow.selector, market, user, collateralAmount, borrowAmount, extractFromSender, deposit, withdraw, withdrawData ) ); } function depositAndRepay( IMarket market, address user, uint256 depositAmount, uint256 repayAmount, bool deposit, bool extractFromSender ) external payable { _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.depositAndRepay.selector, market, user, depositAmount, repayAmount, deposit, extractFromSender ) ); } function depositRepayAndRemoveCollateral( IMarket market, address user, uint256 depositAmount, uint256 repayAmount, uint256 collateralAmount, bool deposit, bool withdraw, bool extractFromSender ) external payable { _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.depositRepayAndRemoveCollateral.selector, market, user, depositAmount, repayAmount, collateralAmount, deposit, withdraw, extractFromSender ) ); } function mintAndLend( ISingularity singularity, IMarket bingBang, address user, uint256 collateralAmount, uint256 borrowAmount, bool deposit, bool extractFromSender ) external payable { _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.mintAndLend.selector, singularity, bingBang, user, collateralAmount, borrowAmount, deposit, extractFromSender ) ); } function depositAndAddAsset( IMarket singularity, address user, uint256 amount, bool deposit, bool extractFromSender ) external payable { _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.depositAndAddAsset.selector, singularity, user, amount, deposit, extractFromSender ) ); } function removeAssetAndRepay( ISingularity singularity, IMarket bingBang, address user, uint256 removeShare, //slightly greater than _repayAmount to cover the interest uint256 repayAmount, uint256 collateralShare, bool withdraw, bytes calldata withdrawData ) external payable { _executeModule( Module.Market, abi.encodeWithSelector( MagnetarMarketModule.removeAssetAndRepay.selector, singularity, bingBang, user, removeShare, repayAmount, collateralShare, withdraw, withdrawData ) ); } // ********************** // // *** PRIVATE METHODS *** // // *********************** // function _commonInfo( address who, IMarket market ) private view returns (MarketInfo memory) { Rebase memory _totalBorrowed; MarketInfo memory info; info.collateral = market.collateral(); info.asset = market.asset(); info.oracle = IOracle(market.oracle()); info.oracleData = market.oracleData(); info.totalCollateralShare = market.totalCollateralShare(); info.userCollateralShare = market.userCollateralShare(who); (uint128 totalBorrowElastic, uint128 totalBorrowBase) = market .totalBorrow(); _totalBorrowed = Rebase(totalBorrowElastic, totalBorrowBase); info.totalBorrow = _totalBorrowed; info.userBorrowPart = market.userBorrowPart(who); info.currentExchangeRate = market.exchangeRate(); (, info.oracleExchangeRate) = IOracle(market.oracle()).peek( market.oracleData() ); info.spotExchangeRate = IOracle(market.oracle()).peekSpot( market.oracleData() ); info.totalBorrowCap = market.totalBorrowCap(); info.assetId = market.assetId(); info.collateralId = market.collateralId(); IYieldBoxBase yieldBox = IYieldBoxBase(market.yieldBox()); ( info.totalYieldBoxCollateralShare, info.totalYieldBoxCollateralAmount ) = yieldBox.assetTotals(info.collateralId); (info.totalYieldBoxAssetShare, info.totalYieldBoxAssetAmount) = yieldBox .assetTotals(info.assetId); ( info.yieldBoxCollateralTokenType, info.yieldBoxCollateralContractAddress, info.yieldBoxCollateralStrategyAddress, info.yieldBoxCollateralTokenId ) = yieldBox.assets(info.collateralId); ( info.yieldBoxAssetTokenType, info.yieldBoxAssetContractAddress, info.yieldBoxAssetStrategyAddress, info.yieldBoxAssetTokenId ) = yieldBox.assets(info.assetId); return info; } function _singularityMarketInfo( address who, ISingularity[] memory markets ) private view returns (SingularityInfo[] memory) { uint256 len = markets.length; SingularityInfo[] memory result = new SingularityInfo[](len); Rebase memory _totalAsset; ISingularity.AccrueInfo memory _accrueInfo; for (uint256 i = 0; i < len; i++) { ISingularity sgl = markets[i]; result[i].market = _commonInfo(who, IMarket(address(sgl))); (uint128 totalAssetElastic, uint128 totalAssetBase) = sgl // .totalAsset(); // _totalAsset = Rebase(totalAssetElastic, totalAssetBase); // result[i].totalAsset = _totalAsset; // result[i].userAssetFraction = sgl.balanceOf(who); // ( uint64 interestPerSecond, uint64 lastBlockAccrued, uint128 feesEarnedFraction ) = sgl.accrueInfo(); _accrueInfo = ISingularity.AccrueInfo( interestPerSecond, lastBlockAccrued, feesEarnedFraction ); result[i].accrueInfo = _accrueInfo; } return result; } function _bigBangMarketInfo( address who, IBigBang[] memory markets ) private view returns (BigBangInfo[] memory) { uint256 len = markets.length; BigBangInfo[] memory result = new BigBangInfo[](len); IBigBang.AccrueInfo memory _accrueInfo; for (uint256 i = 0; i < len; i++) { IBigBang bigBang = markets[i]; result[i].market = _commonInfo(who, IMarket(address(bigBang))); (uint64 debtRate, uint64 lastAccrued) = bigBang.accrueInfo(); _accrueInfo = IBigBang.AccrueInfo(debtRate, lastAccrued); result[i].accrueInfo = _accrueInfo; result[i].minDebtRate = bigBang.minDebtRate(); result[i].maxDebtRate = bigBang.maxDebtRate(); result[i].debtRateAgainstEthMarket = bigBang.debtRateAgainstEthMarket(); result[i].currentDebtRate = bigBang.getDebtRate(); IPenrose penrose = IPenrose(bigBang.penrose()); result[i].mainBBMarket = penrose.bigBangEthMarket(); result[i].mainBBDebtRate = penrose.bigBangEthDebtRate(); } return result; } function _permit( address target, bytes calldata actionCalldata, bool permitAll, bool allowFailure ) private { if (permitAll) { PermitAllData memory permitData = abi.decode( actionCalldata[4:], (PermitAllData) ); _checkSender(permitData.owner); } else { PermitData memory permitData = abi.decode( actionCalldata[4:], (PermitData) ); _checkSender(permitData.owner); } (bool success, bytes memory returnData) = target.call(actionCalldata); if (!success && !allowFailure) { _getRevertMsg(returnData); } } function _extractModule(Module _module) private view returns (address) { address module; if (_module == Module.Market) { module = address(marketModule); } if (module == address(0)) { revert("MagnetarV2: module not found"); } return module; } function _executeModule( Module _module, bytes memory _data ) private returns (bytes memory returnData) { bool success = true; address module = _extractModule(_module); (success, returnData) = module.delegatecall(_data); if (!success) { _getRevertMsg(returnData); } } function _getRevertMsg(bytes memory _returnData) private pure { // If the _res length is less than 68, then // the transaction failed with custom error or silently (without a revert message) if (_returnData.length < 68) revert("MagnetarV2: Reason unknown"); assembly { // Slice the sighash. _returnData := add(_returnData, 0x04) } revert(abi.decode(_returnData, (string))); // All that remains is the revert string } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; struct Rebase { uint128 elastic; uint128 base; } /// @notice A rebasing library using overflow-/underflow-safe math. library RebaseLibrary { /// @notice Calculates the base value in relationship to `elastic` and `total`. function toBase( Rebase memory total, uint256 elastic, bool roundUp ) internal pure returns (uint256 base) { if (total.elastic == 0) { base = elastic; } else { base = (elastic * total.base) / total.elastic; if (roundUp && (base * total.elastic) / total.base < elastic) { base++; } } } /// @notice Calculates the elastic value in relationship to `base` and `total`. function toElastic( Rebase memory total, uint256 base, bool roundUp ) internal pure returns (uint256 elastic) { if (total.base == 0) { elastic = base; } else { elastic = (base * total.elastic) / total.base; if (roundUp && (elastic * total.base) / total.elastic < base) { elastic++; } } } /// @notice Add `elastic` to `total` and doubles `total.base`. /// @return (Rebase) The new total. /// @return base in relationship to `elastic`. function add( Rebase memory total, uint256 elastic, bool roundUp ) internal pure returns (Rebase memory, uint256 base) { base = toBase(total, elastic, roundUp); total.elastic += uint128(elastic); total.base += uint128(base); return (total, base); } /// @notice Sub `base` from `total` and update `total.elastic`. /// @return (Rebase) The new total. /// @return elastic in relationship to `base`. function sub( Rebase memory total, uint256 base, bool roundUp ) internal pure returns (Rebase memory, uint256 elastic) { elastic = toElastic(total, base, roundUp); total.elastic -= uint128(elastic); total.base -= uint128(base); return (total, elastic); } /// @notice Add `elastic` and `base` to `total`. function add( Rebase memory total, uint256 elastic, uint256 base ) internal pure returns (Rebase memory) { total.elastic += uint128(elastic); total.base += uint128(base); return total; } /// @notice Subtract `elastic` and `base` to `total`. function sub( Rebase memory total, uint256 elastic, uint256 base ) internal pure returns (Rebase memory) { total.elastic -= uint128(elastic); total.base -= uint128(base); return total; } /// @notice Add `elastic` to `total` and update storage. /// @return newElastic Returns updated `elastic`. function addElastic(Rebase storage total, uint256 elastic) internal returns (uint256 newElastic) { newElastic = total.elastic += uint128(elastic); } /// @notice Subtract `elastic` from `total` and update storage. /// @return newElastic Returns updated `elastic`. function subElastic(Rebase storage total, uint256 elastic) internal returns (uint256 newElastic) { newElastic = total.elastic -= uint128(elastic); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; interface IBigBang { struct AccrueInfo { uint64 debtRate; uint64 lastAccrued; } function accrueInfo() external view returns (uint64 debtRate, uint64 lastAccrued); function minDebtRate() external view returns (uint256); function maxDebtRate() external view returns (uint256); function debtRateAgainstEthMarket() external view returns (uint256); function penrose() external view returns (address); function getDebtRate() external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; interface IMarket { function asset() external view returns (address); function assetId() external view returns (uint256); function collateral() external view returns (address); function collateralId() external view returns (uint256); function totalBorrowCap() external view returns (uint256); function totalCollateralShare() external view returns (uint256); function userBorrowPart(address) external view returns (uint256); function userCollateralShare(address) external view returns (uint256); function totalBorrow() external view returns (uint128 elastic, uint128 base); function oracle() external view returns (address); function oracleData() external view returns (bytes memory); function exchangeRate() external view returns (uint256); function yieldBox() external view returns (address payable); function liquidationMultiplier() external view returns (uint256); function addCollateral( address from, address to, bool skim, uint256 amount, uint256 share ) external; function removeCollateral(address from, address to, uint256 share) external; function addAsset( address from, address to, bool skim, uint256 share ) external returns (uint256 fraction); function repay( address from, address to, bool skim, uint256 part ) external returns (uint256 amount); function borrow( address from, address to, uint256 amount ) external returns (uint256 part, uint256 share); function execute( bytes[] calldata calls, bool revertOnFail ) external returns (bool[] memory successes, string[] memory results); function refreshPenroseFees( address feeTo ) external returns (uint256 feeShares); function penrose() external view returns (address); function owner() external view returns (address); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; interface IOracle { // @notice Precision of the return value. function decimals() external view returns (uint8); /// @notice Get the latest exchange rate. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return success if no valid (recent) rate is available, return false else true. /// @return rate The rate of the requested asset / pair / pool. function get( bytes calldata data ) external returns (bool success, uint256 rate); /// @notice Check the last exchange rate without any state changes. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return success if no valid (recent) rate is available, return false else true. /// @return rate The rate of the requested asset / pair / pool. function peek( bytes calldata data ) external view returns (bool success, uint256 rate); /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek(). /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return rate The rate of the requested asset / pair / pool. function peekSpot(bytes calldata data) external view returns (uint256 rate); /// @notice Returns a human readable (short) name about this oracle. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return (string) A human readable symbol name about this oracle. function symbol(bytes calldata data) external view returns (string memory); /// @notice Returns a human readable name about this oracle. /// @param data Usually abi encoded, implementation specific data that contains information and arguments to & about the oracle. /// For example: /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256)); /// @return (string) A human readable name about this oracle. function name(bytes calldata data) external view returns (string memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; import "./ISwapper.sol"; interface IPenrose { /// @notice swap extra data struct SwapData { uint256 minAssetAmount; } /// @notice Used to define the MasterContract's type enum ContractType { lowRisk, mediumRisk, highRisk } /// @notice MasterContract address and type struct MasterContract { address location; ContractType risk; } function bigBangEthMarket() external view returns (address); function bigBangEthDebtRate() external view returns (uint256); function swappers(ISwapper swapper) external view returns (bool); function yieldBox() external view returns (address payable); function tapToken() external view returns (address); function tapAssetId() external view returns (uint256); function usdoToken() external view returns (address); function usdoAssetId() external view returns (uint256); function feeTo() external view returns (address); function wethToken() external view returns (address); function wethAssetId() external view returns (uint256); function isMarketRegistered(address market) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; interface ISendFrom { struct LzCallParams { address payable refundAddress; address zroPaymentAddress; bytes adapterParams; } function sendFrom( address _from, uint16 _dstChainId, bytes32 _toAddress, uint256 _amount, LzCallParams calldata _callParams ) external payable; function useCustomAdapterParams() external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; import "./IMarket.sol"; interface ISingularity is IMarket { struct AccrueInfo { uint64 interestPerSecond; uint64 lastAccrued; uint128 feesEarnedFraction; } function accrueInfo() external view returns ( uint64 interestPerSecond, uint64 lastBlockAccrued, uint128 feesEarnedFraction ); function totalAsset() external view returns (uint128 elastic, uint128 base); function removeAsset( address from, address to, uint256 fraction ) external returns (uint256 share); function name() external view returns (string memory); function nonces(address) external view returns (uint256); function permit( address owner_, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function allowance(address, address) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function balanceOf(address) external view returns (uint256); function liquidationQueue() external view returns (address payable); function computeAllowedLendShare( uint256 amount, uint256 tokenId ) external view returns (uint256 share); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; interface ISwapper { struct SwapTokensData { address tokenIn; uint256 tokenInId; address tokenOut; uint256 tokenOutId; } struct SwapAmountData { uint256 amountIn; uint256 shareIn; uint256 amountOut; uint256 shareOut; } struct YieldBoxData { bool withdrawFromYb; bool depositToYb; } struct SwapData { SwapTokensData tokensData; SwapAmountData amountData; YieldBoxData yieldBoxData; } //Add more overloads if needed function buildSwapData( address tokenIn, address tokenOut, uint256 amountIn, uint256 shareIn, bool withdrawFromYb, bool depositToYb ) external view returns (SwapData memory); function buildSwapData( uint256 tokenInId, uint256 tokenOutId, uint256 amountIn, uint256 shareIn, bool withdrawFromYb, bool depositToYb ) external view returns (SwapData memory); function getDefaultDexOptions() external view returns (bytes memory); function getOutputAmount( SwapData calldata swapData, bytes calldata dexOptions ) external view returns (uint256 amountOut); function getInputAmount( SwapData calldata swapData, bytes calldata dexOptions ) external view returns (uint256 amountIn); function swap( SwapData calldata swapData, uint256 amountOutMin, address to, bytes calldata dexOptions ) external returns (uint256 amountOut, uint256 shareOut); } interface ICurveSwapper is ISwapper { function curvePool() external view returns (address); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; import "./ISendFrom.sol"; import {IUSDOBase} from "./IUSDO.sol"; interface ITapiocaOFTBase { function hostChainID() external view returns (uint256); function wrap( address fromAddress, address toAddress, uint256 amount ) external; function wrapNative(address _toAddress) external payable; function unwrap(address _toAddress, uint256 _amount) external; function erc20() external view returns (address); function lzEndpoint() external view returns (address); } /// @dev used for generic TOFTs interface ITapiocaOFT is ISendFrom, ITapiocaOFTBase { struct ISendOptions { uint256 extraGasLimit; address zroPaymentAddress; } struct IApproval { bool permitAll; bool allowFailure; address target; bool permitBorrow; address owner; address spender; uint256 value; uint256 deadline; uint8 v; bytes32 r; bytes32 s; } struct IWithdrawParams { bool withdraw; uint256 withdrawLzFeeAmount; bool withdrawOnOtherChain; uint16 withdrawLzChainId; bytes withdrawAdapterParams; } struct IRemoveParams { uint256 share; address marketHelper; address market; } struct IBorrowParams { uint256 amount; uint256 borrowAmount; address marketHelper; address market; } function totalFees() external view returns (uint256); function erc20() external view returns (address); function wrappedAmount(uint256 _amount) external view returns (uint256); function isHostChain() external view returns (bool); function balanceOf(address _holder) external view returns (uint256); function isTrustedRemote( uint16 lzChainId, bytes calldata path ) external view returns (bool); function approve(address _spender, uint256 _amount) external returns (bool); function extractUnderlying(uint256 _amount) external; function harvestFees() external; /// OFT specific methods function sendToYBAndBorrow( address _from, address _to, uint16 lzDstChainId, bytes calldata airdropAdapterParams, IBorrowParams calldata borrowParams, IWithdrawParams calldata withdrawParams, ISendOptions calldata options, IApproval[] calldata approvals ) external payable; function sendToStrategy( address _from, address _to, uint256 amount, uint256 share, uint256 assetId, uint16 lzDstChainId, ISendOptions calldata options ) external payable; function retrieveFromStrategy( address _from, uint256 amount, uint256 share, uint256 assetId, uint16 lzDstChainId, address zroPaymentAddress, bytes memory airdropAdapterParam ) external payable; function sendForLeverage( uint256 amount, address leverageFor, IUSDOBase.ILeverageLZData calldata lzData, IUSDOBase.ILeverageSwapData calldata swapData, IUSDOBase.ILeverageExternalContractsData calldata externalData ) external payable; function removeCollateral( address from, address to, uint16 lzDstChainId, address zroPaymentAddress, ITapiocaOFT.IWithdrawParams calldata withdrawParams, ITapiocaOFT.IRemoveParams calldata removeParams, ITapiocaOFT.IApproval[] calldata approvals, bytes calldata adapterParams ) external payable; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; interface IUSDOBase { struct IWithdrawParams { bool withdraw; uint256 withdrawLzFeeAmount; bool withdrawOnOtherChain; uint16 withdrawLzChainId; bytes withdrawAdapterParams; } struct IApproval { bool permitAll; bool allowFailure; address target; bool permitBorrow; address owner; address spender; uint256 value; uint256 deadline; uint8 v; bytes32 r; bytes32 s; } struct IRemoveParams { uint256 share; address marketHelper; address market; } struct ILendParams { bool repay; uint256 depositAmount; uint256 repayAmount; address marketHelper; address market; bool removeCollateral; uint256 removeCollateralShare; } struct ISendOptions { uint256 extraGasLimit; address zroPaymentAddress; } struct ILeverageLZData { uint256 srcExtraGasLimit; uint16 lzSrcChainId; uint16 lzDstChainId; address zroPaymentAddress; bytes dstAirdropAdapterParam; bytes srcAirdropAdapterParam; address refundAddress; } struct ILeverageSwapData { address tokenOut; uint256 amountOutMin; bytes data; } struct ILeverageExternalContractsData { address swapper; address magnetar; address tOft; address srcMarket; } function mint(address _to, uint256 _amount) external; function burn(address _from, uint256 _amount) external; function sendAndLendOrRepay( address _from, address _to, uint16 lzDstChainId, address zroPaymentAddress, ILendParams calldata lendParams, IApproval[] calldata approvals, IWithdrawParams calldata withdrawParams, bytes calldata adapterParams ) external payable; function sendForLeverage( uint256 amount, address leverageFor, ILeverageLZData calldata lzData, ILeverageSwapData calldata swapData, ILeverageExternalContractsData calldata externalData ) external payable; } interface IUSDO is IUSDOBase, IERC20Metadata {}
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; import "tapioca-sdk/dist/contracts/YieldBox/contracts/enums/YieldBoxTokenType.sol"; interface IYieldBoxBase { function depositAsset( uint256 assetId, address from, address to, uint256 amount, uint256 share ) external returns (uint256 amountOut, uint256 shareOut); function withdraw( uint256 assetId, address from, address to, uint256 amount, uint256 share ) external returns (uint256 amountOut, uint256 shareOut); function transfer( address from, address to, uint256 assetId, uint256 share ) external; function isApprovedForAll( address user, address spender ) external view returns (bool); function setApprovalForAll(address spender, bool status) external; function assets( uint256 assetId ) external view returns ( TokenType tokenType, address contractAddress, address strategy, uint256 tokenId ); function assetTotals( uint256 assetId ) external view returns (uint256 totalShare, uint256 totalAmount); function toShare( uint256 assetId, uint256 amount, bool roundUp ) external view returns (uint256 share); function toAmount( uint256 assetId, uint256 share, bool roundUp ) external view returns (uint256 amount); function balanceOf( address user, uint256 assetId ) external view returns (uint256 share); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; //Boring import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol"; //TAPIOCA import "../interfaces/IOracle.sol"; import "../interfaces/ISingularity.sol"; import "../interfaces/IBigBang.sol"; import "../interfaces/ITapiocaOFT.sol"; import {IUSDOBase} from "../interfaces/IUSDO.sol"; //YIELDBOX import "tapioca-sdk/dist/contracts/YieldBox/contracts/enums/YieldBoxTokenType.sol"; contract MagnetarV2Storage { // ************ // // *** VARS *** // // ************ // mapping(address => mapping(address => bool)) public isApprovedForAll; struct MarketInfo { address collateral; uint256 collateralId; address asset; uint256 assetId; IOracle oracle; bytes oracleData; uint256 totalCollateralShare; uint256 userCollateralShare; Rebase totalBorrow; uint256 userBorrowPart; uint256 currentExchangeRate; uint256 spotExchangeRate; uint256 oracleExchangeRate; uint256 totalBorrowCap; uint256 totalYieldBoxCollateralShare; uint256 totalYieldBoxCollateralAmount; uint256 totalYieldBoxAssetShare; uint256 totalYieldBoxAssetAmount; TokenType yieldBoxCollateralTokenType; address yieldBoxCollateralContractAddress; address yieldBoxCollateralStrategyAddress; uint256 yieldBoxCollateralTokenId; TokenType yieldBoxAssetTokenType; address yieldBoxAssetContractAddress; address yieldBoxAssetStrategyAddress; uint256 yieldBoxAssetTokenId; } struct SingularityInfo { MarketInfo market; Rebase totalAsset; uint256 userAssetFraction; ISingularity.AccrueInfo accrueInfo; } struct BigBangInfo { MarketInfo market; IBigBang.AccrueInfo accrueInfo; uint256 minDebtRate; uint256 maxDebtRate; uint256 debtRateAgainstEthMarket; address mainBBMarket; uint256 mainBBDebtRate; uint256 currentDebtRate; } // --- ACTIONS DATA ---- struct Call { uint16 id; address target; uint256 value; bool allowFailure; bytes call; } struct Result { bool success; bytes returnData; } struct PermitData { address owner; address spender; uint256 value; uint256 deadline; uint8 v; bytes32 r; bytes32 s; } struct PermitAllData { address owner; address spender; uint256 deadline; uint8 v; bytes32 r; bytes32 s; } struct WrapData { address from; address to; uint256 amount; } struct WrapNativeData { address to; } struct TOFTSendAndBorrowData { address from; address to; uint16 lzDstChainId; bytes airdropAdapterParams; ITapiocaOFT.IBorrowParams borrowParams; ITapiocaOFT.IWithdrawParams withdrawParams; ITapiocaOFT.ISendOptions options; ITapiocaOFT.IApproval[] approvals; } struct TOFTSendAndLendData { address from; address to; uint16 lzDstChainId; IUSDOBase.ILendParams lendParams; IUSDOBase.ISendOptions options; IUSDOBase.IApproval[] approvals; } struct TOFTSendToStrategyData { address from; address to; uint256 amount; uint256 share; uint256 assetId; uint16 lzDstChainId; ITapiocaOFT.ISendOptions options; } struct TOFTRetrieveFromStrategyData { address from; uint256 amount; uint256 share; uint256 assetId; uint16 lzDstChainId; address zroPaymentAddress; bytes airdropAdapterParam; } struct YieldBoxDepositData { uint256 assetId; address from; address to; uint256 amount; uint256 share; } struct SGLAddCollateralData { address from; address to; bool skim; uint256 amount; uint256 share; } struct SGLBorrowData { address from; address to; uint256 amount; } struct SGLLendData { address from; address to; bool skim; uint256 share; } struct SGLRepayData { address from; address to; bool skim; uint256 part; } struct HelperRemoveAssetData { address market; address user; uint256 fraction; } struct HelperLendData { address market; address from; uint256 amount; bool deposit; bool extractFromSender; } struct HelperBorrowData { address market; address user; uint256 collateralAmount; uint256 borrowAmount; bool extractFromSender; bool deposit; bool withdraw; bytes withdrawData; } struct HelperDepositRepayRemoveCollateral { address market; address user; uint256 depositAmount; uint256 repayAmount; uint256 collateralAmount; bool deposit; bool withdraw; bool extractFromSender; } // --- ACTIONS IDS ---- uint16 internal constant PERMIT_ALL = 1; uint16 internal constant PERMIT = 2; uint16 internal constant YB_DEPOSIT_ASSET = 100; uint16 internal constant YB_WITHDRAW_TO = 102; uint16 internal constant MARKET_ADD_COLLATERAL = 200; uint16 internal constant MARKET_BORROW = 201; uint16 internal constant MARKET_LEND = 203; uint16 internal constant MARKET_REPAY = 204; uint16 internal constant MARKET_YBDEPOSIT_AND_LEND = 205; uint16 internal constant MARKET_YBDEPOSIT_COLLATERAL_AND_BORROW = 206; uint16 internal constant MARKET_REMOVE_ASSET = 207; uint16 internal constant MARKET_DEPOSIT_REPAY_REMOVE_COLLATERAL = 208; uint16 internal constant TOFT_WRAP = 300; uint16 internal constant TOFT_SEND_FROM = 301; uint16 internal constant TOFT_SEND_APPROVAL = 302; uint16 internal constant TOFT_SEND_AND_BORROW = 303; uint16 internal constant TOFT_SEND_AND_LEND = 304; uint16 internal constant TOFT_DEPOSIT_TO_STRATEGY = 305; uint16 internal constant TOFT_RETRIEVE_FROM_STRATEGY = 306; // ************** // // *** EVENTS *** // // ************** // event ApprovalForAll(address owner, address operator, bool approved); // ************************ // // *** INTERNAL METHODS *** // // ************************ // function _checkSender(address _from) internal view { require(_from == msg.sender, "MagnetarV2: operator not approved"); } receive() external payable virtual {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.18; //LZ import "tapioca-sdk/dist/contracts/libraries/LzLib.sol"; //OZ import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; //TAPIOCA import "../../interfaces/IYieldBoxBase.sol"; import "../MagnetarV2Storage.sol"; contract MagnetarMarketModule is MagnetarV2Storage { using SafeERC20 for IERC20; using RebaseLibrary for Rebase; function withdrawTo( IYieldBoxBase yieldBox, address from, uint256 assetId, uint16 dstChainId, bytes32 receiver, uint256 amount, uint256 share, bytes memory adapterParams, address payable refundAddress, uint256 gas ) external payable { _withdrawTo( yieldBox, from, assetId, dstChainId, receiver, amount, share, adapterParams, refundAddress, gas ); } function depositAddCollateralAndBorrow( IMarket market, address user, uint256 collateralAmount, uint256 borrowAmount, bool extractFromSender, bool deposit, bool withdraw, bytes memory withdrawData ) external payable { _depositAddCollateralAndBorrow( market, user, collateralAmount, borrowAmount, extractFromSender, deposit, withdraw, withdrawData ); } function depositAndRepay( IMarket market, address user, uint256 depositAmount, uint256 repayAmount, bool deposit, bool extractFromSender ) external payable { _depositAndRepay( market, user, depositAmount, repayAmount, deposit, extractFromSender ); } function depositRepayAndRemoveCollateral( IMarket market, address user, uint256 depositAmount, uint256 repayAmount, uint256 collateralAmount, bool deposit, bool withdraw, bool extractFromSender ) external payable { _depositRepayAndRemoveCollateral( market, user, depositAmount, repayAmount, collateralAmount, deposit, withdraw, extractFromSender ); } function removeAsset( ISingularity singularity, address user, uint256 fraction ) external payable { _removeAsset(singularity, user, fraction); } function mintAndLend( ISingularity singularity, IMarket bingBang, address user, uint256 collateralAmount, uint256 borrowAmount, bool deposit, bool extractFromSender ) external payable { _mintAndLend( singularity, bingBang, user, collateralAmount, borrowAmount, deposit, extractFromSender ); } function depositAndAddAsset( IMarket singularity, address user, uint256 amount, bool deposit_, bool extractFromSender ) external payable { _depositAndAddAsset( singularity, user, amount, deposit_, extractFromSender ); } function removeAssetAndRepay( ISingularity singularity, IMarket bingBang, address user, uint256 removeShare, //slightly greater than _repayAmount to cover the interest uint256 repayAmount, uint256 collateralShare, bool withdraw, bytes calldata withdrawData ) external payable { _removeAssetAndRepay( singularity, bingBang, user, removeShare, repayAmount, collateralShare, withdraw, withdrawData ); } // *********************** // // *** PRIVATE METHODS *** // // *********************** // function _depositAddCollateralAndBorrow( IMarket market, address user, uint256 collateralAmount, uint256 borrowAmount, bool extractFromSender, bool deposit, bool withdraw, bytes memory withdrawData ) private { IYieldBoxBase yieldBox = IYieldBoxBase(market.yieldBox()); uint256 collateralId = market.collateralId(); (, address collateralAddress, , ) = yieldBox.assets(collateralId); //deposit into the yieldbox uint256 _share = yieldBox.toShare( collateralId, collateralAmount, false ); if (deposit) { if (!extractFromSender) { _checkSender(user); } _extractTokens( extractFromSender ? msg.sender : user, collateralAddress, collateralAmount ); IERC20(collateralAddress).approve( address(yieldBox), collateralAmount ); yieldBox.depositAsset( collateralId, address(this), address(this), 0, _share ); } //add collateral if (collateralAmount > 0) { _setApprovalForYieldBox(market, yieldBox); market.addCollateral( deposit ? address(this) : user, user, false, collateralAmount, _share ); } //borrow if (borrowAmount > 0) { address borrowReceiver = withdraw ? address(this) : user; market.borrow(user, borrowReceiver, borrowAmount); if (withdraw) { _withdraw( borrowReceiver, withdrawData, market, yieldBox, borrowAmount, 0, false ); } } _revertYieldBoxApproval(market, yieldBox); } function _depositAndRepay( IMarket market, address user, uint256 depositAmount, uint256 repayAmount, bool deposit, bool extractFromSender ) private { uint256 assetId = market.assetId(); IYieldBoxBase yieldBox = IYieldBoxBase(market.yieldBox()); (, address assetAddress, , ) = yieldBox.assets(assetId); //deposit into the yieldbox if (deposit) { _extractTokens( extractFromSender ? msg.sender : user, assetAddress, depositAmount ); IERC20(assetAddress).approve(address(yieldBox), depositAmount); yieldBox.depositAsset( assetId, address(this), address(this), depositAmount, 0 ); } //repay if (repayAmount > 0) { _setApprovalForYieldBox(market, yieldBox); market.repay( deposit ? address(this) : user, user, false, repayAmount ); _revertYieldBoxApproval(market, yieldBox); } } function _depositRepayAndRemoveCollateral( IMarket market, address user, uint256 depositAmount, uint256 repayAmount, uint256 collateralAmount, bool deposit, bool withdraw, bool extractFromSender ) private { IYieldBoxBase yieldBox = IYieldBoxBase(market.yieldBox()); _depositAndRepay( market, user, depositAmount, repayAmount, deposit, extractFromSender ); //remove collateral if (collateralAmount > 0) { address receiver = withdraw ? address(this) : user; uint256 collateralShare = yieldBox.toShare( market.collateralId(), collateralAmount, false ); market.removeCollateral(user, receiver, collateralShare); //withdraw if (withdraw) { yieldBox.withdraw( market.collateralId(), address(this), user, collateralAmount, 0 ); } } } function _removeAsset( ISingularity singularity, address user, uint256 fraction ) private { singularity.removeAsset(user, user, fraction); } function _mintAndLend( ISingularity singularity, IMarket bingBang, address user, uint256 collateralAmount, uint256 borrowAmount, bool deposit, bool extractFromSender ) private { uint256 collateralId = bingBang.collateralId(); IYieldBoxBase yieldBox = IYieldBoxBase(singularity.yieldBox()); (, address collateralAddress, , ) = yieldBox.assets(collateralId); uint256 _share = yieldBox.toShare( collateralId, collateralAmount, false ); if (deposit) { //deposit to YieldBox _extractTokens( extractFromSender ? msg.sender : user, collateralAddress, collateralAmount ); IERC20(collateralAddress).approve( address(yieldBox), collateralAmount ); yieldBox.depositAsset( collateralId, address(this), address(this), 0, _share ); } if (collateralAmount > 0) { //add collateral to BingBang _setApprovalForYieldBox(bingBang, yieldBox); bingBang.addCollateral( address(this), user, false, collateralAmount, _share ); } //borrow from BingBang if (borrowAmount > 0) { bingBang.borrow(user, user, borrowAmount); //lend to Singularity uint256 assetId = singularity.assetId(); uint256 borrowShare = yieldBox.toShare( assetId, borrowAmount, false ); _setApprovalForYieldBox(singularity, yieldBox); singularity.addAsset(user, user, false, borrowShare); _revertYieldBoxApproval(singularity, yieldBox); } _revertYieldBoxApproval(bingBang, yieldBox); } function _depositAndAddAsset( IMarket singularity, address _user, uint256 _amount, bool deposit_, bool extractFromSender ) private { uint256 assetId = singularity.assetId(); IYieldBoxBase yieldBox = IYieldBoxBase(singularity.yieldBox()); (, address assetAddress, , ) = yieldBox.assets(assetId); uint256 _share = yieldBox.toShare(assetId, _amount, false); if (deposit_) { if (!extractFromSender) { _checkSender(_user); } //deposit into the yieldbox _extractTokens( extractFromSender ? msg.sender : _user, assetAddress, _amount ); IERC20(assetAddress).approve(address(yieldBox), _amount); yieldBox.depositAsset( assetId, address(this), address(this), 0, _share ); } //add asset _setApprovalForYieldBox(singularity, yieldBox); singularity.addAsset(address(this), _user, false, _share); _setApprovalForYieldBox(singularity, yieldBox); } function _removeAssetAndRepay( ISingularity singularity, IMarket bigBang, address user, uint256 removeShare, //slightly greater than _repayAmount to cover the interest uint256 repayAmount, uint256 collateralShare, bool withdraw, bytes calldata withdrawData ) private { IYieldBoxBase yieldBox = IYieldBoxBase(singularity.yieldBox()); //remove asset uint256 bbAssetId = bigBang.assetId(); uint256 _removeAmount = yieldBox.toAmount( bbAssetId, removeShare, false ); singularity.removeAsset(user, address(this), removeShare); //repay _setApprovalForYieldBox(bigBang, yieldBox); uint256 repayed = bigBang.repay( address(this), user, false, repayAmount ); if (repayed < _removeAmount) { yieldBox.transfer( address(this), user, bbAssetId, yieldBox.toShare(bbAssetId, _removeAmount - repayed, false) ); } //remove collateral if (collateralShare > 0) { bigBang.removeCollateral( user, withdraw ? address(this) : user, collateralShare ); //withdraw if (withdraw) { _withdraw( address(this), withdrawData, singularity, yieldBox, 0, collateralShare, true ); } } _revertYieldBoxApproval(bigBang, yieldBox); } function _withdrawTo( IYieldBoxBase yieldBox, address from, uint256 assetId, uint16 dstChainId, bytes32 receiver, uint256 amount, uint256 share, bytes memory adapterParams, address payable refundAddress, uint256 gas ) private { if (dstChainId == 0) { yieldBox.withdraw( assetId, from, LzLib.bytes32ToAddress(receiver), amount, share ); return; } (, address asset, , ) = yieldBox.assets(assetId); try IERC165(address(asset)).supportsInterface( type(ISendFrom).interfaceId ) {} catch { return; } yieldBox.withdraw(assetId, from, address(this), amount, 0); bytes memory _adapterParams; ISendFrom.LzCallParams memory callParams = ISendFrom.LzCallParams({ refundAddress: msg.value > 0 ? refundAddress : payable(this), zroPaymentAddress: address(0), adapterParams: ISendFrom(address(asset)).useCustomAdapterParams() ? adapterParams : _adapterParams }); ISendFrom(address(asset)).sendFrom{value: gas}( address(this), dstChainId, receiver, amount, callParams ); } function _withdraw( address from, bytes memory withdrawData, IMarket market, IYieldBoxBase yieldBox, uint256 amount, uint256 share, bool withdrawCollateral ) private { require(withdrawData.length > 0, "MagnetarV2: withdrawData is empty"); ( bool withdrawOnOtherChain, uint16 destChain, bytes32 receiver, bytes memory adapterParams ) = abi.decode(withdrawData, (bool, uint16, bytes32, bytes)); uint256 gas = msg.value > 0 ? msg.value : address(this).balance; _withdrawTo( yieldBox, from, withdrawCollateral ? market.collateralId() : market.assetId(), withdrawOnOtherChain ? destChain : 0, receiver, amount, share, adapterParams, gas > 0 ? payable(msg.sender) : payable(this), gas ); } function _setApprovalForYieldBox( IMarket market, IYieldBoxBase yieldBox ) private { bool isApproved = yieldBox.isApprovedForAll( address(this), address(market) ); if (!isApproved) { yieldBox.setApprovalForAll(address(market), true); } } function _revertYieldBoxApproval( IMarket market, IYieldBoxBase yieldBox ) private { bool isApproved = yieldBox.isApprovedForAll( address(this), address(market) ); if (isApproved) { yieldBox.setApprovalForAll(address(market), false); } } function _extractTokens( address _from, address _token, uint256 _amount ) private { IERC20(_token).safeTransferFrom(_from, address(this), _amount); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.6.0; pragma experimental ABIEncoderV2; library LzLib { // LayerZero communication struct CallParams { address payable refundAddress; address zroPaymentAddress; } //--------------------------------------------------------------------------- // Address type handling struct AirdropParams { uint airdropAmount; bytes32 airdropAddress; } function buildAdapterParams(LzLib.AirdropParams memory _airdropParams, uint _uaGasLimit) internal pure returns (bytes memory adapterParams) { if (_airdropParams.airdropAmount == 0 && _airdropParams.airdropAddress == bytes32(0x0)) { adapterParams = buildDefaultAdapterParams(_uaGasLimit); } else { adapterParams = buildAirdropAdapterParams(_uaGasLimit, _airdropParams); } } // Build Adapter Params function buildDefaultAdapterParams(uint _uaGas) internal pure returns (bytes memory) { // txType 1 // bytes [2 32 ] // fields [txType extraGas] return abi.encodePacked(uint16(1), _uaGas); } function buildAirdropAdapterParams(uint _uaGas, AirdropParams memory _params) internal pure returns (bytes memory) { require(_params.airdropAmount > 0, "Airdrop amount must be greater than 0"); require(_params.airdropAddress != bytes32(0x0), "Airdrop address must be set"); // txType 2 // bytes [2 32 32 bytes[] ] // fields [txType extraGas dstNativeAmt dstNativeAddress] return abi.encodePacked(uint16(2), _uaGas, _params.airdropAmount, _params.airdropAddress); } function getGasLimit(bytes memory _adapterParams) internal pure returns (uint gasLimit) { require(_adapterParams.length == 34 || _adapterParams.length > 66, "Invalid adapterParams"); assembly { gasLimit := mload(add(_adapterParams, 34)) } } // Decode Adapter Params function decodeAdapterParams(bytes memory _adapterParams) internal pure returns (uint16 txType, uint uaGas, uint airdropAmount, address payable airdropAddress) { require(_adapterParams.length == 34 || _adapterParams.length > 66, "Invalid adapterParams"); assembly { txType := mload(add(_adapterParams, 2)) uaGas := mload(add(_adapterParams, 34)) } require(txType == 1 || txType == 2, "Unsupported txType"); require(uaGas > 0, "Gas too low"); if (txType == 2) { assembly { airdropAmount := mload(add(_adapterParams, 66)) airdropAddress := mload(add(_adapterParams, 86)) } } } //--------------------------------------------------------------------------- // Address type handling function bytes32ToAddress(bytes32 _bytes32Address) internal pure returns (address _address) { return address(uint160(uint(_bytes32Address))); } function addressToBytes32(address _address) internal pure returns (bytes32 _bytes32Address) { return bytes32(uint(uint160(_address))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /// @title TokenType /// @author BoringCrypto (@Boring_Crypto) /// @notice The YieldBox can hold different types of tokens: /// Native: These are ERC1155 tokens native to YieldBox. Protocols using YieldBox should use these is possible when simple token creation is needed. /// ERC20: ERC20 tokens (including rebasing tokens) can be added to the YieldBox. /// ERC1155: ERC1155 tokens are also supported. This can also be used to add YieldBox Native tokens to strategies since they are ERC1155 tokens. enum TokenType { Native, ERC20, ERC721, ERC1155, None }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 300 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address payable","name":"_marketModule","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","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"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"contract IBigBang[]","name":"markets","type":"address[]"}],"name":"bigBangMarketInfo","outputs":[{"components":[{"components":[{"internalType":"address","name":"collateral","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"contract IOracle","name":"oracle","type":"address"},{"internalType":"bytes","name":"oracleData","type":"bytes"},{"internalType":"uint256","name":"totalCollateralShare","type":"uint256"},{"internalType":"uint256","name":"userCollateralShare","type":"uint256"},{"components":[{"internalType":"uint128","name":"elastic","type":"uint128"},{"internalType":"uint128","name":"base","type":"uint128"}],"internalType":"struct Rebase","name":"totalBorrow","type":"tuple"},{"internalType":"uint256","name":"userBorrowPart","type":"uint256"},{"internalType":"uint256","name":"currentExchangeRate","type":"uint256"},{"internalType":"uint256","name":"spotExchangeRate","type":"uint256"},{"internalType":"uint256","name":"oracleExchangeRate","type":"uint256"},{"internalType":"uint256","name":"totalBorrowCap","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxCollateralShare","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxAssetShare","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxAssetAmount","type":"uint256"},{"internalType":"enum TokenType","name":"yieldBoxCollateralTokenType","type":"uint8"},{"internalType":"address","name":"yieldBoxCollateralContractAddress","type":"address"},{"internalType":"address","name":"yieldBoxCollateralStrategyAddress","type":"address"},{"internalType":"uint256","name":"yieldBoxCollateralTokenId","type":"uint256"},{"internalType":"enum TokenType","name":"yieldBoxAssetTokenType","type":"uint8"},{"internalType":"address","name":"yieldBoxAssetContractAddress","type":"address"},{"internalType":"address","name":"yieldBoxAssetStrategyAddress","type":"address"},{"internalType":"uint256","name":"yieldBoxAssetTokenId","type":"uint256"}],"internalType":"struct MagnetarV2Storage.MarketInfo","name":"market","type":"tuple"},{"components":[{"internalType":"uint64","name":"debtRate","type":"uint64"},{"internalType":"uint64","name":"lastAccrued","type":"uint64"}],"internalType":"struct IBigBang.AccrueInfo","name":"accrueInfo","type":"tuple"},{"internalType":"uint256","name":"minDebtRate","type":"uint256"},{"internalType":"uint256","name":"maxDebtRate","type":"uint256"},{"internalType":"uint256","name":"debtRateAgainstEthMarket","type":"uint256"},{"internalType":"address","name":"mainBBMarket","type":"address"},{"internalType":"uint256","name":"mainBBDebtRate","type":"uint256"},{"internalType":"uint256","name":"currentDebtRate","type":"uint256"}],"internalType":"struct MagnetarV2Storage.BigBangInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"id","type":"uint16"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"allowFailure","type":"bool"},{"internalType":"bytes","name":"call","type":"bytes"}],"internalType":"struct MagnetarV2Storage.Call[]","name":"calls","type":"tuple[]"}],"name":"burst","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct MagnetarV2Storage.Result[]","name":"returnData","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IMarket","name":"market","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"internalType":"bool","name":"extractFromSender","type":"bool"},{"internalType":"bool","name":"deposit","type":"bool"},{"internalType":"bool","name":"withdraw","type":"bool"},{"internalType":"bytes","name":"withdrawData","type":"bytes"}],"name":"depositAddCollateralAndBorrow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IMarket","name":"singularity","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"deposit","type":"bool"},{"internalType":"bool","name":"extractFromSender","type":"bool"}],"name":"depositAndAddAsset","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IMarket","name":"market","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"bool","name":"deposit","type":"bool"},{"internalType":"bool","name":"extractFromSender","type":"bool"}],"name":"depositAndRepay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IMarket","name":"market","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"deposit","type":"bool"},{"internalType":"bool","name":"withdraw","type":"bool"},{"internalType":"bool","name":"extractFromSender","type":"bool"}],"name":"depositRepayAndRemoveCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract ISingularity","name":"singularity","type":"address"},{"internalType":"uint256","name":"fraction","type":"uint256"}],"name":"getAmountForAssetFraction","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IMarket","name":"market","type":"address"},{"internalType":"uint256","name":"borrowPart","type":"uint256"}],"name":"getAmountForBorrowPart","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IMarket","name":"market","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBorrowPartForAmount","outputs":[{"internalType":"uint256","name":"part","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IMarket","name":"market","type":"address"},{"internalType":"uint256","name":"borrowPart","type":"uint256"},{"internalType":"uint256","name":"liquidationMultiplierPrecision","type":"uint256"},{"internalType":"uint256","name":"exchangeRatePrecision","type":"uint256"}],"name":"getCollateralSharesForBorrowPart","outputs":[{"internalType":"uint256","name":"collateralShares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISingularity","name":"singularity","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getFractionForAmount","outputs":[{"internalType":"uint256","name":"fraction","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketModule","outputs":[{"internalType":"contract MagnetarMarketModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISingularity","name":"singularity","type":"address"},{"internalType":"contract IMarket","name":"bingBang","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"internalType":"bool","name":"deposit","type":"bool"},{"internalType":"bool","name":"extractFromSender","type":"bool"}],"name":"mintAndLend","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISingularity","name":"singularity","type":"address"},{"internalType":"contract IMarket","name":"bingBang","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"removeShare","type":"uint256"},{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"uint256","name":"collateralShare","type":"uint256"},{"internalType":"bool","name":"withdraw","type":"bool"},{"internalType":"bytes","name":"withdrawData","type":"bytes"}],"name":"removeAssetAndRepay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"contract ISingularity[]","name":"markets","type":"address[]"}],"name":"singularityMarketInfo","outputs":[{"components":[{"components":[{"internalType":"address","name":"collateral","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"contract IOracle","name":"oracle","type":"address"},{"internalType":"bytes","name":"oracleData","type":"bytes"},{"internalType":"uint256","name":"totalCollateralShare","type":"uint256"},{"internalType":"uint256","name":"userCollateralShare","type":"uint256"},{"components":[{"internalType":"uint128","name":"elastic","type":"uint128"},{"internalType":"uint128","name":"base","type":"uint128"}],"internalType":"struct Rebase","name":"totalBorrow","type":"tuple"},{"internalType":"uint256","name":"userBorrowPart","type":"uint256"},{"internalType":"uint256","name":"currentExchangeRate","type":"uint256"},{"internalType":"uint256","name":"spotExchangeRate","type":"uint256"},{"internalType":"uint256","name":"oracleExchangeRate","type":"uint256"},{"internalType":"uint256","name":"totalBorrowCap","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxCollateralShare","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxCollateralAmount","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxAssetShare","type":"uint256"},{"internalType":"uint256","name":"totalYieldBoxAssetAmount","type":"uint256"},{"internalType":"enum TokenType","name":"yieldBoxCollateralTokenType","type":"uint8"},{"internalType":"address","name":"yieldBoxCollateralContractAddress","type":"address"},{"internalType":"address","name":"yieldBoxCollateralStrategyAddress","type":"address"},{"internalType":"uint256","name":"yieldBoxCollateralTokenId","type":"uint256"},{"internalType":"enum TokenType","name":"yieldBoxAssetTokenType","type":"uint8"},{"internalType":"address","name":"yieldBoxAssetContractAddress","type":"address"},{"internalType":"address","name":"yieldBoxAssetStrategyAddress","type":"address"},{"internalType":"uint256","name":"yieldBoxAssetTokenId","type":"uint256"}],"internalType":"struct MagnetarV2Storage.MarketInfo","name":"market","type":"tuple"},{"components":[{"internalType":"uint128","name":"elastic","type":"uint128"},{"internalType":"uint128","name":"base","type":"uint128"}],"internalType":"struct Rebase","name":"totalAsset","type":"tuple"},{"internalType":"uint256","name":"userAssetFraction","type":"uint256"},{"components":[{"internalType":"uint64","name":"interestPerSecond","type":"uint64"},{"internalType":"uint64","name":"lastAccrued","type":"uint64"},{"internalType":"uint128","name":"feesEarnedFraction","type":"uint128"}],"internalType":"struct ISingularity.AccrueInfo","name":"accrueInfo","type":"tuple"}],"internalType":"struct MagnetarV2Storage.SingularityInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IYieldBoxBase","name":"yieldBox","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"bytes32","name":"receiver","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"share","type":"uint256"},{"internalType":"bytes","name":"adapterParams","type":"bytes"},{"internalType":"address payable","name":"refundAddress","type":"address"},{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"withdrawTo","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080346200014c57601f62004c6038819003918201601f19168301916001600160401b03831184841017620001515780849260409485528339810103126200014c5780516001600160a01b0391828216908183036200014c5760200151928084168094036200014c57620000733362000167565b33906000541603620001085715620000b457620000909062000167565b600280546001600160a01b031916919091179055604051614ab19081620001af8239f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b600080546001600160a01b039283166001600160a01b03198216811783559216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a356fe6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c8063013546e11461015b5780630e8fd73b1461015657806314ecf5a8146101515780632ed48e481461014c578063411628d914610147578063443c73a714610142578063664653ac1461013d5780636dd55c0b14610138578063715018a614610133578063815c12ea1461012e5780638da5cb5b146101295780639cc6ef1414610124578063a306dfd51461011f578063cc5e31631461011a578063cfd8b3d814610115578063dedd6b8014610110578063e4e802e81461010b578063e9212b7214610106578063e985e9c5146101015763f2fde38b0361000e57612a59565b6129fa565b612949565b6126d6565b61257a565b612553565b6124c0565b612409565b61231b565b6122dd565b61224f565b6121f1565b611e31565b611a8e565b611869565b611790565b6114b5565b611314565b611092565b610254565b9181601f84011215610190578235916001600160401b038311610190576020808501948460051b01011161019057565b600080fd5b60005b8381106101a85750506000910152565b8181015183820152602001610198565b906020916101d181518092818552858086019101610195565b601f01601f1916010190565b602080820190808352835180925260409283810182858560051b8401019601946000925b858410610212575050505050505090565b909192939495968580610243600193603f1986820301885286838d51805115158452015191818582015201906101b8565b990194019401929594939190610201565b6020806003193601126101905760049081356001600160401b038111610190576102819036908401610160565b9260009261028e85612cab565b94845b8181106102b7576102b3876102a7883414613b14565b604051918291826101dd565b0390f35b6102c2818387612d22565b606096878201906102d96102d583612d49565b1590565b611042575b6040808401358092019960016102fd6102f687612e2d565b61ffff1690565b0361034257505050816103326103389261032a61031f8961033d9897016130bb565b936080810190612d53565b929091612d49565b9261484a565b612c5e565b610291565b61ffff60028161035188612e2d565b160361037b5750505050816103756103389261032a61031f8961033d9897016130bb565b92614776565b90919295949a935061012c816103908d612e2d565b16036105025750506103ba6103b26103ab60808c018c612d53565b8091612e37565b810190612ede565b916103d46103cf84516001600160a01b031690565b614a1a565b841561047a57866103fe6103f26103f2838961040d96019e016130bb565b6001600160a01b031690565b9301516001600160a01b031690565b91803b15610190579051632479d86360e01b81526001600160a01b039092168783019081529193600092859291839182906020015b03925af19182156104755761033d9261045c575b50612c5e565b8061046961046f926115c0565b806121e6565b38610456565b612be0565b98610490919294506103f2876103f292016130bb565b816104a4878601516001600160a01b031690565b94015190803b15610190579151630c46aac760e31b8152338882019081526001600160a01b039095166020860152604085019190915292600091849182908490829060600103925af19182156104755761033d9261045c5750612c5e565b908161012d8c97936105168b96979e612e2d565b160361058f5750509061055e6001600160a01b03926105646103f26103f261054f6105476103ab60808d018d612d53565b810190613a1b565b99939d9298919a909d16614a1a565b016130bb565b92833b15610190576104428b9160009751998a978896879563695ef6bf60e01b875233908701613abb565b60648161059f8995949699612e2d565b16036106f25750509082918860006105ea6103f26103f28a60809661055e6103cf6105da6105d26103ab8c860186612d53565b8101906139dc565b9e8f01516001600160a01b031690565b92610652895191610604888c01516001600160a01b031690565b968b01519a01518751634d4d7cbd60e11b81529485019283523360208401526001600160a01b0390961660408301526060820199909952608081019490945290968793849291839160a00190565b03925af180156104755761033d9360009081926106ba575b5091518681019283526020830191909152906106949082906040015b03601f1981018352826116b3565b61069c6116d4565b6001815290858201526106af828a613871565b526104568189613871565b610694925061068691506106e390843d86116106eb575b6106db81836116b3565b810190613965565b92509061066a565b503d6106d1565b60c88161070185999495612e2d565b16036107c35750505060806107456103f26103f2896107306107286103ab878c018c612d53565b81019061397b565b9861055e6103cf8b516001600160a01b031690565b90610759888701516001600160a01b031690565b9061076685880151151590565b9387015196015193823b1561019057516374d2492960e11b815233818b019081526001600160a01b03909216602083015292151560408201526060810195909552608085019290925292600091849182908490829060a001610442565b60c9816107d38996949596612e2d565b16036108c8575050829150936108146103f26103f2610868976107ff6103b26103ab6080880188612d53565b9461055e6103cf87516001600160a01b031690565b82610828898401516001600160a01b031690565b92015183516314890dcb60e21b815233818c019081526001600160a01b039094166020850152604084019190915295869283916000918391606090910190565b03925af180156104755761033d9360009081926108a0575b509151868101928352602083019190915290610694908290604001610686565b610694925061068691506108c090843d86116106eb576106db81836116b3565b925090610880565b6066816108d789959699612e2d565b160361093f575050610456929161068661033d9661090a6109026103ab86608061093a980190612d53565b810190613885565b9790969c959195949294519c8d9b632731bbc560e21b908d01526001600160a01b03809116911660248c01613902565b6148eb565b60cb8161094e85999499612e2d565b1603610a3757505061097b6103f26103f2846107ff6109736103ab6080880188612d53565b81019061381a565b818301516001600160a01b03169561099585840151151590565b9201518451630cb0f5b760e31b815233818c019081526001600160a01b039098166020890152921515604088015260608701529094859190829060009082906080015b03925af19283156104755761033d936106869261069492600092610a08575b505187810191825292839160200190565b610a29919250883d8a11610a30575b610a2181836116b3565b810190612c01565b90386109f7565b503d610a17565b60cc81610a4385612e2d565b1603610ac9575050610a686103f26103f2846107ff6109736103ab6080880188612d53565b818301516001600160a01b031695610a8285840151151590565b920151845163cd0211eb60e01b815233818c019081526001600160a01b039098166020890152921515604088015260608701529094859190829060009082906080016109d8565b61012f81610adb859994969795612e2d565b1603610b5857505091610b2a6103f2926103f294610b0a610b026103ab60808b018b612d53565b8101906136d7565b95979699939b929c919a90949e61055e6001600160a01b03809c16614a1a565b96873b15610190576000998f9961044295519d8e9b8c9a8b99630cdc41b960e11b8b52169033908a01613776565b61013081610b6889969599612e2d565b1603610bea57505091816103f295936103f2610b98610b906103ab6080610bb8980186612d53565b81019061342b565b959c969b9397929e919a90949961055e6001600160a01b03809e16614a1a565b96873b15610190578e9b60009a8a9861044296519e8f9c8d9b8c9a635620549760e01b8c521693169033908a016135da565b61013181610bfa86979496612e2d565b1603610c9f575050608094610c3e6103f26103f28a610c29610c216103ab8c8b018b612d53565b81019061313b565b9761055e6103cf8a516001600160a01b031690565b91610c52898601516001600160a01b031690565b918086015194860151978601519060c0610c7160a089015161ffff1690565b970151853b15610190576000978d9361044293519b8c998a988997634663f85d60e11b8952339089016131b9565b61013281610cb1879596949997612e2d565b1603610d2d575050916103f2610cff9284610ce1610cd96103ab60806103f29b990184612d53565b810190613057565b949a939d929598919b909661055e6001600160a01b03809b16614a1a565b95863b1561019057600098610442938f92519c8d9a8b998a986323c8387760e11b8a521694339089016130c5565b909591925060cd81610d3e85612e2d565b1603610ded5750509261093a61045692610686610d70610d686103ab89608061033d9b0190612d53565b810190612fed565b91610d8283516001600160a01b031690565b92610da6610d998c8301516001600160a01b031690565b9683830151920151151590565b91516301bdbad760e71b8c8201526001600160a01b03948516602482015295909316604486015260648501929092529015156084840152600060a4840152829060c4820190565b909460ce82610dfb85612e2d565b1603610e5a5750509061093a61033d94610686610e2d610e256103ab876080610456990190612d53565b810190612f21565b9691949250949951998a9863411628d960e01b908a01526001600160a01b03809116911660248901612fa0565b90945060cf85610e6984612e2d565b1603610ef6575061033d93509061093a610e906103b26103ab856080610456970190612d53565b91610686610ea584516001600160a01b031690565b9180610eba8b8701516001600160a01b031690565b950151905163f4d9375360e01b8b8201526001600160a01b03938416602482015292909416604483015260648201939093529182906084820190565b929360d090610f0483612e2d565b1603610ff3579161093a866106866104569461033d9796610f38610f306103ab60809384810190612d53565b810190612e54565b90610f4a82516001600160a01b031690565b96610f5e868401516001600160a01b031690565b9184840151918401519084015191610f7960a0860151151590565b93610f9460e0610f8c60c0890151151590565b970151151590565b96519a8b9963749095b960e11b908b015260248a019693909260e09693999895929961010089019a6001600160a01b038092168a52166020890152604088015260608701526080860152151560a0850152151560c08401521515910152565b815162461bcd60e51b81526020818901818152601c918101919091527f4d61676e6574617256323a20616374696f6e206e6f742076616c696400000000604082015281906060010390fd5b0390fd5b61107c6110526080850185612d53565b905061107460405161106f816106868a8d83019190602083019252565b612d85565b901515612e01565b6102de565b6001600160a01b0381160361019057565b3461019057604080600319360112610190576004908135916110b383611081565b815163f9557ccb60e01b81526001600160a01b039384169083818481855afa9081156104755760009081926112f4575b50845163020a17bd60e61b81529585878681875afa968715610475576000976112c4575b50855163226f120560e11b81526020919082818881895afa9586156104755787916000976112a3575b50839089519283809263de40657760e01b82525afa90811561047557600091611276575b501693865194638eb22cdd60e01b9687875283878061118b6024358786840160409060009294936060820195825260208201520152565b0381855afa96871561047557600097611253575b5083949596976111d68a519b8c9586948594855284016040906001600160801b036001939594606083019683521660208201520152565b03915afa8015610475576102b39661120292600092611236575b50506001600160801b03809316612c9e565b918261121b57505050905b519081529081906020820190565b9261122b91611230941690612c26565b612c3e565b9061120d565b61124c9250803d10610a3057610a2181836116b3565b38806111f0565b849596975061126e90853d8711610a3057610a2181836116b3565b96959461119f565b6112969150833d851161129c575b61128e81836116b3565b810190612bec565b38611154565b503d611284565b849197506112bd90823d8411610a3057610a2181836116b3565b9690611130565b6112e5919750863d88116112ed575b6112dd81836116b3565b810190612bbc565b509538611107565b503d6112d3565b905061130d9150843d86116112ed576112dd81836116b3565b90386110e3565b34610190576040806003193601126101905760043561133281611081565b815163f9557ccb60e01b8152916001600160a01b039182168184600481845afa928315610475576000948594611490575b50825163de40657760e01b81526020958682600481875afa918215610475576004948891600094611471575b50865163226f120560e11b815295869182905afa801561047557611409968895600092611450575b506113db91926113d36001600160801b03809216602435612c26565b911690612c3e565b855163442c159960e01b81526004810192909252602482015260006044820152948592839182906064820190565b0392165afa918215610475576102b393600093611431575b5050519081529081906020820190565b611448929350803d10610a3057610a2181836116b3565b903880611421565b6113db925061146b90873d8911610a3057610a2181836116b3565b916113b7565b611489919450823d841161129c5761128e81836116b3565b923861138f565b9093506114ab919450823d84116112ed576112dd81836116b3565b9390939238611363565b3461019057604080600319360112610190576001600160a01b03906004356114dc81611081565b81602435916114e9612b8f565b50600482518096819363020a17bd60e61b8352165afa8015610475576102b3936000908192611568575b50835191611520836115d8565b6001600160801b0380809316918285521690816020850152156000146115525750505090519081529081906020820190565b61155f9061123094612c26565b91511690612c3e565b90506115819150833d85116112ed576112dd81836116b3565b9038611513565b359061159382611081565b565b8015150361019057565b359061159382611595565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116115d357604052565b6115aa565b604081019081106001600160401b038211176115d357604052565b61010081019081106001600160401b038211176115d357604052565b606081019081106001600160401b038211176115d357604052565b60a081019081106001600160401b038211176115d357604052565b60e081019081106001600160401b038211176115d357604052565b608081019081106001600160401b038211176115d357604052565b61012081019081106001600160401b038211176115d357604052565b61014081019081106001600160401b038211176115d357604052565b90601f801991011681019081106001600160401b038211176115d357604052565b60405190611593826115d8565b604051906115938261160f565b6040519061016082018281106001600160401b038211176115d357604052565b6040519061034082018281106001600160401b038211176115d357604052565b6001600160401b0381116115d357601f01601f191660200190565b81601f82011215610190578035906117608261172e565b9261176e60405194856116b3565b8284526020838301011161019057816000926020809301838601378301015290565b61010080600319360112610190576004356117aa81611081565b602435916117b783611081565b608435926117c484611595565b60a435916117d183611595565b60c435946117de86611595565b60e435916001600160401b038311610190576100199661093a95611809610686953690600401611749565b9360405198899763411628d960e01b60208a01526001600160a01b0380921660248a015216604488015260443560648801526064356084880152151560a4870152151560c4860152151560e48501526101048401526101248301906101b8565b3461019057608036600319011261019057600480359061188882611081565b611890612b8f565b506040805163020a17bd60e61b8152926001600160a01b039081169082858581855afa948515610475576000908196611a6c575b506118df6118d06116d4565b6001600160801b039092168252565b6118f6602096878301906001600160801b03169052565b835163de40657760e01b81529086828781875afa91821561047557600092611a49575b506119279060243590612c6d565b84516377607a1760e11b8152909287828881885afa91821561047557600092611a2a575b50855163294c4c7960e11b81529388858981895afa9485156104755788958a9261197d92600092611a12575b50612c26565b95875198898092633ba0b9a960e01b82525afa948515610475576119b189966119c5926114099a6000926119f35750612c26565b6119bf606435604435612c26565b90612c3e565b8651638eb22cdd60e01b81529485019283526020830152600060408301529295869384929091839160600190565b611a0b919250893d8b11610a3057610a2181836116b3565b9038611977565b611a0b919250843d8611610a3057610a2181836116b3565b611a42919250883d8a11610a3057610a2181836116b3565b903861194b565b611927919250611a6590883d8a1161129c5761128e81836116b3565b9190611919565b9050611a86919550833d85116112ed576112dd81836116b3565b9490386118c4565b60e036600319011261019057610019600435611aa981611081565b602435611ab581611081565b60443590611ac282611081565b60a43590611acf82611595565b60c43592611adc84611595565b6040519463199194eb60e21b60208701526001600160a01b0392838092166024880152166044860152166064840152606435608484015260843560a4840152151560c4830152151560e482015260e4815261093a8161167b565b90604060031983011261019057600435611b4f81611081565b91602435906001600160401b03821161019057611b6e91600401610160565b9091565b634e487b7160e01b600052602160045260246000fd5b906005821015611b955752565b611b72565b80516001600160a01b031682529060208201516020820152611bcc604083015160408301906001600160a01b03169052565b60608201516060820152611bf0608083015160808301906001600160a01b03169052565b610340611c0c60a08401516103608060a08601528401906101b8565b9260c081015160c084015260e081015160e0840152611c4a6101008083015190850190602090816001600160801b0391828151168552015116910152565b6101208101516101409081850152810151610160908185015281015161018090818501528101516101a090818501528101516101c090818501528101516101e09081850152810151610200908185015281015161022090818501528101516102409081850152810151611cc36102609182860190611b88565b810151611cde61028091828601906001600160a01b03169052565b810151611cf96102a091828601906001600160a01b03169052565b8101516102c09081850152810151611d176102e09182860190611b88565b810151611d3261030091828601906001600160a01b03169052565b81015190611d4e61032092838601906001600160a01b03169052565b015191015290565b602080820190808352835180925260409283810182858560051b8401019601946000925b858410611d8b575050505050505090565b909192939495968580600192603f198582030187528a5190610100611db98351610120808552840190611b9a565b9284810151856001600160401b039182815116828701520151168984015288810151606090818501528101516080908185015281015160a09081850152810151611e1060c091828601906001600160a01b03169052565b8101519060e091828501520151910152990194019401929594939190611d7a565b3461019057611e3f36611b36565b90611e4982612b78565b91604091611e59835194856116b3565b8184526020918285019060051b820191368311610190578390915b8383106121cc5750505050825190611e8b82614681565b93611e94612b8f565b5060005b838110611eac578451806102b38882611d56565b611ec96103f2611ebc8385613871565b516001600160a01b031690565b906001600160a01b03611ede8184168a613e58565b611ee8838a613871565b51528651632c9f039d60e21b81526004939088818681855afa8015610475576000918291612199575b50611f3f90611f30611f216116d4565b6001600160401b039094168452565b6001600160401b031682890152565b86611f4a858c613871565b510152875163f791395d60e01b815286818681855afa9081156104755760009161217c575b5088611f7b858c613871565b510152875163358cd68b60e11b815286818681855afa9081156104755760009161215f575b506060611fad858c613871565b510152875163bde39c5d60e01b815286818681855afa90811561047557600091612142575b506080611fdf858c613871565b510152875163c1ad5c8d60e01b815286818681855afa918215610475578592858c8a9460009361211a575b5060e09161201791613871565b5101528951636c3d8b8f60e01b815292839182905afa908115610475576000916120fd575b508751631848f2bf60e31b8152911685828581845afa918215610475578692612084916000916120e0575b5060a0612074868d613871565b5101906001600160a01b03169052565b875163e6abad4960e01b815293849182905afa8015610475576120be926000916120c3575b5060c06120b6838a613871565b510152612c5e565b611e98565b6120da9150853d8711610a3057610a2181836116b3565b386120a9565b6120f79150843d861161129c5761128e81836116b3565b38612067565b6121149150863d881161129c5761128e81836116b3565b3861203c565b6120179193509161213960e093873d8911610a3057610a2181836116b3565b9391509161200a565b6121599150873d8911610a3057610a2181836116b3565b38611fd2565b6121769150873d8911610a3057610a2181836116b3565b38611fa0565b6121939150873d8911610a3057610a2181836116b3565b38611f6f565b611f3f92506121be91508a3d8c116121c5575b6121b681836116b3565b810190614717565b9091611f11565b503d6121ac565b819083356121d981611081565b8152019101908390611e74565b600091031261019057565b346101905760008060031936011261224c5761220b612b20565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b6101003660031901126101905760043561226881611081565b60243561227481611081565b6044359161228183611081565b60c43561228d81611595565b60e435936001600160401b0393848611610190573660238701121561019057856004013594851161019057366024868801011161019057602461001996019360a435926084359260643592613b60565b346101905760003660031901126101905760206001600160a01b0360005416604051908152f35b61ffff81160361019057565b359061159382612304565b610140806003193601126101905760043561233581611081565b60243561234181611081565b6064359161234e83612304565b60e435916001600160401b03831161019057610019946123ea61237861093a953690600401611749565b6101049283359361238885611081565b61ffff604051998a98632731bbc560e21b60208b01526001600160a01b03988980921660248c01521660448a015260443560648a015216608488015260843560a488015260a43560c488015260c43560e48801528601526101648501906101b8565b916101249116818401523561014483015203601f1981018352826116b3565b346101905760408060031936011261019057806001600160a01b039160043561243181611081565b612439612b8f565b50600482518095819363020a17bd60e61b8352165afa918215610475576102b3926124919160009081926124a0575b50835191612475836115d8565b6001600160801b03809216835216602082015260243590612c6d565b90519081529081906020820190565b90506124b99150833d85116112ed576112dd81836116b3565b9038612468565b60c0366003190112610190576100196004356124db81611081565b602435906124e882611081565b6084356124f481611595565b60a4359161250183611595565b6040519363cc5e316360e01b60208601526001600160a01b03809216602486015216604484015260443560648401526064356084840152151560a4830152151560c482015260c4815261093a816115f3565b346101905760003660031901126101905760206001600160a01b0360025416604051908152f35b60a03660031901126101905761001960043561259581611081565b602435906125a282611081565b6064356125ae81611595565b608435916125bb83611595565b604051936301bdbad760e71b60208601526001600160a01b038092166024860152166044840152604435606484015215156084830152151560a482015260a4815261093a81611645565b602080820190808352835180925260409283810182858560051b8401019601946000925b85841061263a575050505050505090565b909192939495968580600192603f198582030187528a519060c06001600160801b038861266f855160e0808752860190611b9a565b946126968782015188870190602090816001600160801b0391828151168552015116910152565b81810151906060918287015201516001600160401b03808251166080870152878201511660a0860152015116910152990194019401929594939190612629565b34610190576126e436611b36565b90916126ef82612b78565b916040936126ff855194856116b3565b8184526020918285019060051b820191368311610190578390915b83831061292f575050505082519161273183613ccf565b9361273a612b8f565b50612743613cb0565b5060005b84811061275b578651806102b38882612605565b61276b6103f2611ebc8385613871565b9061277f6001600160a01b03831685613e58565b6127898289613871565b5152875163f9557ccb60e01b815260049089818381875afa801561047557600091829161290c575b506127df906127d06127c16116d4565b6001600160801b039094168452565b6001600160801b031682890152565b866127ea848b613871565b51015288516370a0823160e01b81526001600160a01b0386168282019081528790829081906020010381875afa908115610475576000916128ef575b5089612832848b613871565b510152885192838092632c9f039d60e21b825260609586935afa928315610475576128ae93600092839084926128b3575b50906128956128a4926128866128776116e1565b6001600160401b039097168752565b6001600160401b0316858b0152565b6001600160801b0316838c0152565b6120b6838a613871565b612747565b61289594506128a492506128dd9150833d85116128e8575b6128d581836116b3565b810190613d65565b919490919250612863565b503d6128cb565b6129069150873d8911610a3057610a2181836116b3565b38612826565b6127df925061292891508b3d8d116112ed576112dd81836116b3565b90916127b1565b8190833561293c81611081565b815201910190839061271a565b6101003660031901126101905761001960043561296581611081565b6024359061297282611081565b60a43561297e81611595565b60c4359061298b82611595565b60e4359261299884611595565b6040519463749095b960e11b60208701526001600160a01b0380921660248701521660448501526044356064850152606435608485015260843560a4850152151560c4840152151560e483015261010490151581830152815261093a81611697565b3461019057604036600319011261019057600435612a1781611081565b60243590612a2482611081565b6001600160a01b03809116600052600160205260406000209116600052602052602060ff604060002054166040519015158152f35b3461019057602036600319011261019057600435612a7681611081565b612a7e612b20565b6001600160a01b038091168015612acc57600080546001600160a01b03198116831782559092167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6001600160a01b03600054163303612b3457565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160401b0381116115d35760051b60200190565b60405190612b9c826115d8565b60006020838281520152565b51906001600160801b038216820361019057565b919082604091031261019057612bdd6020612bd684612ba8565b9301612ba8565b90565b6040513d6000823e3d90fd5b908160209103126101905751612bdd81611081565b90816020910312610190575190565b634e487b7160e01b600052601160045260246000fd5b81810292918115918404141715612c3957565b612c10565b8115612c48570490565b634e487b7160e01b600052601260045260246000fd5b6000198114612c395760010190565b60208101906001600160801b03908183511615600014612c8d5750505090565b612bdd938261155f92511690612c26565b91908201809211612c3957565b90612cb582612b78565b6040612cc3815192836116b3565b8382528193612cd4601f1991612b78565b0191600091825b848110612ce9575050505050565b6020908251612cf7816115d8565b85815282606081830152828601015201612cdb565b634e487b7160e01b600052603260045260246000fd5b9190811015612d445760051b81013590609e1981360301821215610190570190565b612d0c565b35612bdd81611595565b903590601e198136030182121561019057018035906001600160401b0382116101905760200191813603831361019057565b90611593604e60405180947f4d61676e6574617256323a204d697373696e672063616c6c20666f722061637460208301526d0d2dedc40eed2e8d040d2dcc8caf60931b6040830152612de08151809260208686019101610195565b810103602e8101855201836116b3565b906020612bdd9281815201906101b8565b15612e095750565b60405162461bcd60e51b81526020600482015290819061103e9060248301906101b8565b35612bdd81612304565b909291928360041161019057831161019057600401916003190190565b908161010091031261019057612ed660e060405192612e72846115f3565b8035612e7d81611081565b8452612e8b60208201611588565b6020850152604081013560408501526060810135606085015260808101356080850152612eba60a0820161159f565b60a0850152612ecb60c0820161159f565b60c08501520161159f565b60e082015290565b90816060910312610190576040805191612ef78361160f565b8035612f0281611081565b83526020810135612f1281611081565b60208401520135604082015290565b91909161010081840312610190578035612f3a81611081565b926020820135612f4981611081565b926040830135926060810135926080820135612f6481611595565b9260a0830135612f7381611595565b9260c0810135612f8281611595565b9260e08201356001600160401b03811161019057612bdd9201611749565b949290612bdd979694926001600160a01b0380921687521660208601526040850152606084015260006080840152151560a0830152151560c0820152610100908160e082015201906101b8565b908160a0910312610190576080604051916130078361162a565b803561301281611081565b8352602081013561302281611081565b602084015260408101356040840152606081013561303f81611595565b6060840152013561304f81611595565b608082015290565b9060e08282031261019057813561306d81611081565b92602083013592604081013592606082013592608083013561308e81612304565b9260a081013561309d81611081565b9260c08201356001600160401b03811161019057612bdd9201611749565b35612bdd81611081565b939460e09561ffff9294612bdd9998946001600160a01b0380971688526020880152604087015260608601521660808401521660a08201528160c082015201906101b8565b919082604091031261019057604051613122816115d8565b60208082948035845201359161313783611081565b0152565b9061010082820312610190576131b19060c06040519361315a85611645565b803561316581611081565b8552602081013561317581611081565b602086015260408101356040860152606081013560608601526080810135608086015260a08101356131a681612304565b60a08601520161310a565b60c082015290565b929460c09461ffff93999896611593989361010087019b6001600160a01b0380921688521660208701526040860152606085015260808401521660a082015201906001600160a01b036020809280518552015116910152565b91908260e09103126101905760405161322a81611645565b60c0808294803561323a81611595565b84526020810135602085015260408101356040850152606081013561325e81611081565b6060850152608081013561327181611081565b608085015260a081013561328481611595565b60a08501520135910152565b359060ff8216820361019057565b81601f82011215610190578035906132b582612b78565b926040906132c5825195866116b3565b838552602091828601918361016080970286010194818611610190578401925b8584106132f6575050505050505090565b86848303126101905784879161330a6116ee565b6133138761159f565b815261332083880161159f565b8382015261332f868801611588565b86820152606061334081890161159f565b908201526080613351818901611588565b9082015260a0613362818901611588565b9082015260c0808801359082015260e08088013590820152610100613388818901613290565b90820152610120808801359082015261014080880135908201528152019301926132e5565b919060a08382031261019057604051906133c68261162a565b819380356133d381611595565b83526020810135602084015260408101356133ed81611595565b6040840152606081013561340081612304565b60608401526080810135916001600160401b038311610190576080926134269201611749565b910152565b91906101c0838203126101905761344183611588565b9261344e60208201611588565b9261345b60408301612310565b9261346860608401611588565b926134768260808301613212565b926001600160401b0391610160810135838111610190578461349991830161329e565b9361018082013584811161019057816134b39184016133ad565b936101a083013590811161019057612bdd9201611749565b90815180825260208080930193019160005b8281106134eb575050505090565b9091929382610160600192875161350482825115159052565b808401511515828501526040818101516001600160a01b0316908301526060818101511515908301526080818101516001600160a01b03169083015260a0818101516001600160a01b03169083015260c0818101519083015260e080820151908301526101008082015160ff169083015261012081810151908301526101409081015190820152019501939291016134dd565b9060a06080612bdd938051151584526020810151602085015260408101511515604085015261ffff606082015116606085015201519181608082015201906101b8565b969394612bdd98969260c09261367e9761ffff61366f978c60206001600160a01b038097818098168452169101521660408c01521660608a01528151151560808a0152602082015160a08a01526040820151838a01528060608301511660e08a015260808201511661010089015260a0810151151561012089015201516101408701526101c0806101608801528601906134cb565b90848203610180860152613597565b916101a08184039101526101b8565b9190826080910312610190576040516136a581611660565b6060808294803584526020810135602085015260408101356136c681611081565b604085015201359161313783611081565b9061018082820312610190576136ec82611588565b926136f960208401611588565b9261370660408201612310565b926001600160401b0360608301358181116101905782613727918501611749565b93613735836080860161368d565b93610100810135838111610190578461374f9183016133ad565b9361375e81610120840161310a565b9361016083013590811161019057612bdd920161329e565b949160606137b961380c9661ffff6137ed97612bdd9d9b966001600160a01b0396878092168d521660208c01521660408a015261018080848b01528901906101b8565b9380516080890152602081015160a08901528260408201511660c089015201511660e0860152848203610100860152613597565b84516101208401526020909401516001600160a01b0316610140830152565b6101608184039101526134cb565b908160809103126101905760606040519161383483611660565b803561383f81611081565b8352602081013561384f81611081565b6020840152604081013561386281611595565b60408401520135606082015290565b8051821015612d445760209160051b010190565b90916101208284031261019057813561389d81611081565b9260208301356138ac81611081565b9260408101359260608201356138c181612304565b9260808301359260a08101359260c08201359260e08301356001600160401b03811161019057610100916138f6918501611749565b920135612bdd81611081565b9692610120989461ffff9161395997939d9c9b9d9894986001600160a01b03998a8092168c521660208b015260408a0152166060880152608087015260a086015260c08501526101408060e08601528401906101b8565b95166101008201520152565b9190826040910312610190576020825192015190565b908160a0910312610190576080604051916139958361162a565b80356139a081611081565b835260208101356139b081611081565b602084015260408101356139c381611595565b6040840152606081013560608401520135608082015290565b908160a0910312610190576080604051916139f68361162a565b803583526020810135613a0881611081565b602084015260408101356139c381611081565b91909160a081840312610190578035613a3381611081565b926020820135613a4281612304565b9260408301359260608101359260808201356001600160401b03928382116101905701906060828203126101905760405192613a7d8461160f565b8235613a8881611081565b84526020830135613a9881611081565b6020850152604083013590811161019057613ab39201611749565b604082015290565b9390612bdd95916101009461ffff6040956001600160a01b03809516895216602088015284870152606086015260a060808601528082511660a086015260208201511660c0850152015191606060e082015201906101b8565b15613b1b57565b60405162461bcd60e51b815260206004820152601a60248201527f4d61676e6574617256323a2076616c7565206d69736d617463680000000000006044820152606490fd5b96949192613bee98949161093a9794604051996340ae097560e11b60208c01526001600160a01b03928380921660248d01521660448b0152166064890152608488015260a487015260c4860152151560e4850152610100610104850152836101249180838301528061014494858401376000828201850152601f01601f1916810103908101845201826116b3565b50565b613bf961170e565b906000808352806020840152806040840152806060840152806080840152606060a08401528060c08401528060e0840152613c32612b8f565b61010084015280610120840152806101408401528061016084015280610180840152806101a0840152806101c0840152806101e08401528061020084015280610220840152806102408401528061026084015280610280840152806102a0840152806102c0840152806102e084015280610300840152610320830152565b60405190613cbd8261160f565b60006040838281528260208201520152565b90613cd982612b78565b604090613ce8825191826116b3565b8381528093613cf9601f1991612b78565b0191600091825b848110613d0e575050505050565b6020908351613d1c81611660565b613d24613bf1565b8152613d2e612b8f565b8390818301528686830152613d41613cb0565b6060830152828501015201613d00565b51906001600160401b038216820361019057565b9081606091031261019057613d7981613d51565b91612bdd6040612bd660208501613d51565b90929192613d988161172e565b91613da660405193846116b3565b829482845282820111610190576020611593930190610195565b602081830312610190578051906001600160401b03821161019057019080601f83011215610190578151612bdd92602001613d8b565b91908260409103126101905760208251613e0f81611595565b92015190565b9190826080910312610190578151600581101561019057916020810151613e3b81611081565b9160606040830151613e0f81611081565b6005821015611b955752565b613e60613bf1565b50613e69612b8f565b50613e72613bf1565b916001600160a01b03809116604080519163d8dfeb4560e01b835260209360049385818681865afa801561047557613eba91600091614664575b506001600160a01b03168852565b82516338d52e0f60e01b815285818681865afa801561047557613eef91600091614647575b506001600160a01b031688850152565b82516307dc0d1d60e41b808252909686888781875afa97881561047557600098614628575b50613f2e8360809916898b01906001600160a01b03169052565b84516374645ff360e01b80825291906000818981895afa9081156104755760009161460f575b5060a08b0152855163473e3ce760e01b815288818981895afa908115610475576000916145f2575b5060c08b01528551631c9e379b60e01b81526001600160a01b0382168882019081528990829081906020010381895afa908115610475576000916145d5575b5060e08b0152855163020a17bd60e61b81529086828981895afa90811561047557614039928a9260009182916145b2575b5061400b90613ffc6127c16116d4565b6001600160801b031682850152565b6101008d01528751809381926324720b1f60e11b83528b83019190916001600160a01b036020820193169052565b0381885afa90811561047557600091614595575b506101208a01528451633ba0b9a960e01b815287818881885afa90811561047557600091614578575b506101408a0152845182815287818881885afa9081156104755760009161455b575b5085518281526000818981895afa8015610475576140d6928892600092614540575b508987845180968195829463eeb8a8d360e01b84528301612df0565b0392165afa90811561047557600091614511575b506101808a0152845191825286828781875afa918215610475576000926144f2575b5084519081526000818781875afa908115610475578392889261414c926000916144d1575b508751948580948193630d39bbef60e41b83528c8301612df0565b0392165afa908115610475576000916144b4575b5061016088015282516340626d8b60e01b815285818681865afa90811561047557600091614497575b506101a0880152825163226f120560e11b81529480868681865afa95861561047557600096614478575b506060880195865283516377607a1760e11b815281818781875afa938415610475578691600095614457575b508290818b0195865286519283809263de40657760e01b82525afa9182156104755760009261443a575b50501690805183519084828061423163092ada2b60e31b948583528a83019190602083019252565b0381875afa90811561047557614273928692600091829161441b575b506101e08c01526101c08b01528751908251938492839283528983019190602083019252565b0381865afa80156104755760009182916143fc575b50610220890152610200880152518251630cf35bdd60e41b8082528186019283529094918790869081906020010381865afa9586156104755761431888966143309860009081908d839184906143c6575b61430e94955081610280916102a06142fd9594015201906001600160a01b03169052565b6001600160a01b03166102608d0152565b6102408b01613e4c565b51935195869485938493845283019190602083019252565b03915afa90811561047557612bdd92600092839284928592614384575b50506103208601526001600160a01b031661030085015261437a905b6001600160a01b03166102e0850152565b6102c08301613e4c565b614369955061437a94506143b1935080919250903d106143bf575b6143a981836116b3565b810190613e15565b92949193509190829061434d565b503d61439f565b5091505061430e91506142fd6143eb610280948c8d3d106143bf576143a981836116b3565b9296508695509093909250906142d9565b90506144159150843d86116106eb576106db81836116b3565b38614288565b90506144349150833d85116106eb576106db81836116b3565b3861424d565b6144509250803d1061129c5761128e81836116b3565b3880614209565b8391955061447190823d8411610a3057610a2181836116b3565b94906141df565b816144909297503d8811610a3057610a2181836116b3565b94386141b3565b6144ae9150863d8811610a3057610a2181836116b3565b38614189565b6144cb9150863d8811610a3057610a2181836116b3565b38614160565b6144ec913d8091833e6144e481836116b3565b810190613dc0565b38614131565b61450a919250873d891161129c5761128e81836116b3565b903861410c565b6145319150863d8811614539575b61452981836116b3565b810190613df6565b9050386140ea565b503d61451f565b61455491923d8091833e6144e481836116b3565b90386140ba565b6145729150883d8a1161129c5761128e81836116b3565b38614098565b61458f9150883d8a11610a3057610a2181836116b3565b38614076565b6145ac9150883d8a11610a3057610a2181836116b3565b3861404d565b61400b92506145ce91508a3d8c116112ed576112dd81836116b3565b9091613fec565b6145ec9150893d8b11610a3057610a2181836116b3565b38613fbb565b6146099150893d8b11610a3057610a2181836116b3565b38613f7c565b614622913d8091833e6144e481836116b3565b38613f54565b614640919850873d891161129c5761128e81836116b3565b9638613f14565b61465e9150873d891161129c5761128e81836116b3565b38613edf565b61467b9150873d891161129c5761128e81836116b3565b38613eac565b9061468b82612b78565b60409061469a825191826116b3565b83815280936146ab601f1991612b78565b019160005b8381106146bd5750505050565b60209082516146cb816115f3565b6146d3613bf1565b81526146dd612b8f565b8390818301526000858301526000606083015260006080830152600060a0830152600060c0830152600060e08301528286010152016146b0565b919082604091031261019057612bdd602061473184613d51565b9301613d51565b908092918237016000815290565b3d15614771573d906147578261172e565b9161476560405193846116b3565b82523d6000602084013e565b606090565b826004116101905760e0600319838581010301126101905760009283809361480f6001600160a01b036040516147ab81611645565b6004840135906147ba82611081565b81815260248501356147cb81611081565b602082015260448501356040820152606485013560608201526147f060848601613290565b608082015260a485013560a082015260c060c486013591015216614a1a565b61481e60405180948193614738565b03925af19061482b614746565b91159081614841575b5061483c5750565b614968565b90501538614834565b60c092614858818085612e37565b9080959181010312610190576040519360c08501938585106001600160401b038611176115d35761480f6001600160a01b0360009793889794889560405260a0808335936148a585611081565b84845260208101356148b681611081565b6020850152604081013560408501526148d160608201613290565b606085015260808101356080850152013591015216614a1a565b6001600160a01b0360025416801561492357816000929160208493519201905af490614915614746565b911561491d57565b50614968565b60405162461bcd60e51b815260206004820152601c60248201527f4d61676e6574617256323a206d6f64756c65206e6f7420666f756e64000000006044820152606490fd5b60448151106149d557600481015181019060208160248401930312610190576024810151906001600160401b0382116101905701816043820112156101905761103e9181604460246149bd9401519101613d8b565b60405162461bcd60e51b815291829160048301612df0565b60405162461bcd60e51b815260206004820152601a60248201527f4d61676e6574617256323a20526561736f6e20756e6b6e6f776e0000000000006044820152606490fd5b6001600160a01b0333911603614a2c57565b60405162461bcd60e51b815260206004820152602160248201527f4d61676e6574617256323a206f70657261746f72206e6f7420617070726f76656044820152601960fa1b6064820152608490fdfea26469706673582212201b9dd699ad9f6b8cfd79256a23a6fc6db67afce56354eb7fbe38f448c03d4f2264736f6c6343000812003300000000000000000000000040282d3cf4890d9806bc1853e97a59c93d8136530000000000000000000000000880d1ee15cf3d63e729e1cbb87df0e515b1af09
Deployed Bytecode
0x6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c8063013546e11461015b5780630e8fd73b1461015657806314ecf5a8146101515780632ed48e481461014c578063411628d914610147578063443c73a714610142578063664653ac1461013d5780636dd55c0b14610138578063715018a614610133578063815c12ea1461012e5780638da5cb5b146101295780639cc6ef1414610124578063a306dfd51461011f578063cc5e31631461011a578063cfd8b3d814610115578063dedd6b8014610110578063e4e802e81461010b578063e9212b7214610106578063e985e9c5146101015763f2fde38b0361000e57612a59565b6129fa565b612949565b6126d6565b61257a565b612553565b6124c0565b612409565b61231b565b6122dd565b61224f565b6121f1565b611e31565b611a8e565b611869565b611790565b6114b5565b611314565b611092565b610254565b9181601f84011215610190578235916001600160401b038311610190576020808501948460051b01011161019057565b600080fd5b60005b8381106101a85750506000910152565b8181015183820152602001610198565b906020916101d181518092818552858086019101610195565b601f01601f1916010190565b602080820190808352835180925260409283810182858560051b8401019601946000925b858410610212575050505050505090565b909192939495968580610243600193603f1986820301885286838d51805115158452015191818582015201906101b8565b990194019401929594939190610201565b6020806003193601126101905760049081356001600160401b038111610190576102819036908401610160565b9260009261028e85612cab565b94845b8181106102b7576102b3876102a7883414613b14565b604051918291826101dd565b0390f35b6102c2818387612d22565b606096878201906102d96102d583612d49565b1590565b611042575b6040808401358092019960016102fd6102f687612e2d565b61ffff1690565b0361034257505050816103326103389261032a61031f8961033d9897016130bb565b936080810190612d53565b929091612d49565b9261484a565b612c5e565b610291565b61ffff60028161035188612e2d565b160361037b5750505050816103756103389261032a61031f8961033d9897016130bb565b92614776565b90919295949a935061012c816103908d612e2d565b16036105025750506103ba6103b26103ab60808c018c612d53565b8091612e37565b810190612ede565b916103d46103cf84516001600160a01b031690565b614a1a565b841561047a57866103fe6103f26103f2838961040d96019e016130bb565b6001600160a01b031690565b9301516001600160a01b031690565b91803b15610190579051632479d86360e01b81526001600160a01b039092168783019081529193600092859291839182906020015b03925af19182156104755761033d9261045c575b50612c5e565b8061046961046f926115c0565b806121e6565b38610456565b612be0565b98610490919294506103f2876103f292016130bb565b816104a4878601516001600160a01b031690565b94015190803b15610190579151630c46aac760e31b8152338882019081526001600160a01b039095166020860152604085019190915292600091849182908490829060600103925af19182156104755761033d9261045c5750612c5e565b908161012d8c97936105168b96979e612e2d565b160361058f5750509061055e6001600160a01b03926105646103f26103f261054f6105476103ab60808d018d612d53565b810190613a1b565b99939d9298919a909d16614a1a565b016130bb565b92833b15610190576104428b9160009751998a978896879563695ef6bf60e01b875233908701613abb565b60648161059f8995949699612e2d565b16036106f25750509082918860006105ea6103f26103f28a60809661055e6103cf6105da6105d26103ab8c860186612d53565b8101906139dc565b9e8f01516001600160a01b031690565b92610652895191610604888c01516001600160a01b031690565b968b01519a01518751634d4d7cbd60e11b81529485019283523360208401526001600160a01b0390961660408301526060820199909952608081019490945290968793849291839160a00190565b03925af180156104755761033d9360009081926106ba575b5091518681019283526020830191909152906106949082906040015b03601f1981018352826116b3565b61069c6116d4565b6001815290858201526106af828a613871565b526104568189613871565b610694925061068691506106e390843d86116106eb575b6106db81836116b3565b810190613965565b92509061066a565b503d6106d1565b60c88161070185999495612e2d565b16036107c35750505060806107456103f26103f2896107306107286103ab878c018c612d53565b81019061397b565b9861055e6103cf8b516001600160a01b031690565b90610759888701516001600160a01b031690565b9061076685880151151590565b9387015196015193823b1561019057516374d2492960e11b815233818b019081526001600160a01b03909216602083015292151560408201526060810195909552608085019290925292600091849182908490829060a001610442565b60c9816107d38996949596612e2d565b16036108c8575050829150936108146103f26103f2610868976107ff6103b26103ab6080880188612d53565b9461055e6103cf87516001600160a01b031690565b82610828898401516001600160a01b031690565b92015183516314890dcb60e21b815233818c019081526001600160a01b039094166020850152604084019190915295869283916000918391606090910190565b03925af180156104755761033d9360009081926108a0575b509151868101928352602083019190915290610694908290604001610686565b610694925061068691506108c090843d86116106eb576106db81836116b3565b925090610880565b6066816108d789959699612e2d565b160361093f575050610456929161068661033d9661090a6109026103ab86608061093a980190612d53565b810190613885565b9790969c959195949294519c8d9b632731bbc560e21b908d01526001600160a01b03809116911660248c01613902565b6148eb565b60cb8161094e85999499612e2d565b1603610a3757505061097b6103f26103f2846107ff6109736103ab6080880188612d53565b81019061381a565b818301516001600160a01b03169561099585840151151590565b9201518451630cb0f5b760e31b815233818c019081526001600160a01b039098166020890152921515604088015260608701529094859190829060009082906080015b03925af19283156104755761033d936106869261069492600092610a08575b505187810191825292839160200190565b610a29919250883d8a11610a30575b610a2181836116b3565b810190612c01565b90386109f7565b503d610a17565b60cc81610a4385612e2d565b1603610ac9575050610a686103f26103f2846107ff6109736103ab6080880188612d53565b818301516001600160a01b031695610a8285840151151590565b920151845163cd0211eb60e01b815233818c019081526001600160a01b039098166020890152921515604088015260608701529094859190829060009082906080016109d8565b61012f81610adb859994969795612e2d565b1603610b5857505091610b2a6103f2926103f294610b0a610b026103ab60808b018b612d53565b8101906136d7565b95979699939b929c919a90949e61055e6001600160a01b03809c16614a1a565b96873b15610190576000998f9961044295519d8e9b8c9a8b99630cdc41b960e11b8b52169033908a01613776565b61013081610b6889969599612e2d565b1603610bea57505091816103f295936103f2610b98610b906103ab6080610bb8980186612d53565b81019061342b565b959c969b9397929e919a90949961055e6001600160a01b03809e16614a1a565b96873b15610190578e9b60009a8a9861044296519e8f9c8d9b8c9a635620549760e01b8c521693169033908a016135da565b61013181610bfa86979496612e2d565b1603610c9f575050608094610c3e6103f26103f28a610c29610c216103ab8c8b018b612d53565b81019061313b565b9761055e6103cf8a516001600160a01b031690565b91610c52898601516001600160a01b031690565b918086015194860151978601519060c0610c7160a089015161ffff1690565b970151853b15610190576000978d9361044293519b8c998a988997634663f85d60e11b8952339089016131b9565b61013281610cb1879596949997612e2d565b1603610d2d575050916103f2610cff9284610ce1610cd96103ab60806103f29b990184612d53565b810190613057565b949a939d929598919b909661055e6001600160a01b03809b16614a1a565b95863b1561019057600098610442938f92519c8d9a8b998a986323c8387760e11b8a521694339089016130c5565b909591925060cd81610d3e85612e2d565b1603610ded5750509261093a61045692610686610d70610d686103ab89608061033d9b0190612d53565b810190612fed565b91610d8283516001600160a01b031690565b92610da6610d998c8301516001600160a01b031690565b9683830151920151151590565b91516301bdbad760e71b8c8201526001600160a01b03948516602482015295909316604486015260648501929092529015156084840152600060a4840152829060c4820190565b909460ce82610dfb85612e2d565b1603610e5a5750509061093a61033d94610686610e2d610e256103ab876080610456990190612d53565b810190612f21565b9691949250949951998a9863411628d960e01b908a01526001600160a01b03809116911660248901612fa0565b90945060cf85610e6984612e2d565b1603610ef6575061033d93509061093a610e906103b26103ab856080610456970190612d53565b91610686610ea584516001600160a01b031690565b9180610eba8b8701516001600160a01b031690565b950151905163f4d9375360e01b8b8201526001600160a01b03938416602482015292909416604483015260648201939093529182906084820190565b929360d090610f0483612e2d565b1603610ff3579161093a866106866104569461033d9796610f38610f306103ab60809384810190612d53565b810190612e54565b90610f4a82516001600160a01b031690565b96610f5e868401516001600160a01b031690565b9184840151918401519084015191610f7960a0860151151590565b93610f9460e0610f8c60c0890151151590565b970151151590565b96519a8b9963749095b960e11b908b015260248a019693909260e09693999895929961010089019a6001600160a01b038092168a52166020890152604088015260608701526080860152151560a0850152151560c08401521515910152565b815162461bcd60e51b81526020818901818152601c918101919091527f4d61676e6574617256323a20616374696f6e206e6f742076616c696400000000604082015281906060010390fd5b0390fd5b61107c6110526080850185612d53565b905061107460405161106f816106868a8d83019190602083019252565b612d85565b901515612e01565b6102de565b6001600160a01b0381160361019057565b3461019057604080600319360112610190576004908135916110b383611081565b815163f9557ccb60e01b81526001600160a01b039384169083818481855afa9081156104755760009081926112f4575b50845163020a17bd60e61b81529585878681875afa968715610475576000976112c4575b50855163226f120560e11b81526020919082818881895afa9586156104755787916000976112a3575b50839089519283809263de40657760e01b82525afa90811561047557600091611276575b501693865194638eb22cdd60e01b9687875283878061118b6024358786840160409060009294936060820195825260208201520152565b0381855afa96871561047557600097611253575b5083949596976111d68a519b8c9586948594855284016040906001600160801b036001939594606083019683521660208201520152565b03915afa8015610475576102b39661120292600092611236575b50506001600160801b03809316612c9e565b918261121b57505050905b519081529081906020820190565b9261122b91611230941690612c26565b612c3e565b9061120d565b61124c9250803d10610a3057610a2181836116b3565b38806111f0565b849596975061126e90853d8711610a3057610a2181836116b3565b96959461119f565b6112969150833d851161129c575b61128e81836116b3565b810190612bec565b38611154565b503d611284565b849197506112bd90823d8411610a3057610a2181836116b3565b9690611130565b6112e5919750863d88116112ed575b6112dd81836116b3565b810190612bbc565b509538611107565b503d6112d3565b905061130d9150843d86116112ed576112dd81836116b3565b90386110e3565b34610190576040806003193601126101905760043561133281611081565b815163f9557ccb60e01b8152916001600160a01b039182168184600481845afa928315610475576000948594611490575b50825163de40657760e01b81526020958682600481875afa918215610475576004948891600094611471575b50865163226f120560e11b815295869182905afa801561047557611409968895600092611450575b506113db91926113d36001600160801b03809216602435612c26565b911690612c3e565b855163442c159960e01b81526004810192909252602482015260006044820152948592839182906064820190565b0392165afa918215610475576102b393600093611431575b5050519081529081906020820190565b611448929350803d10610a3057610a2181836116b3565b903880611421565b6113db925061146b90873d8911610a3057610a2181836116b3565b916113b7565b611489919450823d841161129c5761128e81836116b3565b923861138f565b9093506114ab919450823d84116112ed576112dd81836116b3565b9390939238611363565b3461019057604080600319360112610190576001600160a01b03906004356114dc81611081565b81602435916114e9612b8f565b50600482518096819363020a17bd60e61b8352165afa8015610475576102b3936000908192611568575b50835191611520836115d8565b6001600160801b0380809316918285521690816020850152156000146115525750505090519081529081906020820190565b61155f9061123094612c26565b91511690612c3e565b90506115819150833d85116112ed576112dd81836116b3565b9038611513565b359061159382611081565b565b8015150361019057565b359061159382611595565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116115d357604052565b6115aa565b604081019081106001600160401b038211176115d357604052565b61010081019081106001600160401b038211176115d357604052565b606081019081106001600160401b038211176115d357604052565b60a081019081106001600160401b038211176115d357604052565b60e081019081106001600160401b038211176115d357604052565b608081019081106001600160401b038211176115d357604052565b61012081019081106001600160401b038211176115d357604052565b61014081019081106001600160401b038211176115d357604052565b90601f801991011681019081106001600160401b038211176115d357604052565b60405190611593826115d8565b604051906115938261160f565b6040519061016082018281106001600160401b038211176115d357604052565b6040519061034082018281106001600160401b038211176115d357604052565b6001600160401b0381116115d357601f01601f191660200190565b81601f82011215610190578035906117608261172e565b9261176e60405194856116b3565b8284526020838301011161019057816000926020809301838601378301015290565b61010080600319360112610190576004356117aa81611081565b602435916117b783611081565b608435926117c484611595565b60a435916117d183611595565b60c435946117de86611595565b60e435916001600160401b038311610190576100199661093a95611809610686953690600401611749565b9360405198899763411628d960e01b60208a01526001600160a01b0380921660248a015216604488015260443560648801526064356084880152151560a4870152151560c4860152151560e48501526101048401526101248301906101b8565b3461019057608036600319011261019057600480359061188882611081565b611890612b8f565b506040805163020a17bd60e61b8152926001600160a01b039081169082858581855afa948515610475576000908196611a6c575b506118df6118d06116d4565b6001600160801b039092168252565b6118f6602096878301906001600160801b03169052565b835163de40657760e01b81529086828781875afa91821561047557600092611a49575b506119279060243590612c6d565b84516377607a1760e11b8152909287828881885afa91821561047557600092611a2a575b50855163294c4c7960e11b81529388858981895afa9485156104755788958a9261197d92600092611a12575b50612c26565b95875198898092633ba0b9a960e01b82525afa948515610475576119b189966119c5926114099a6000926119f35750612c26565b6119bf606435604435612c26565b90612c3e565b8651638eb22cdd60e01b81529485019283526020830152600060408301529295869384929091839160600190565b611a0b919250893d8b11610a3057610a2181836116b3565b9038611977565b611a0b919250843d8611610a3057610a2181836116b3565b611a42919250883d8a11610a3057610a2181836116b3565b903861194b565b611927919250611a6590883d8a1161129c5761128e81836116b3565b9190611919565b9050611a86919550833d85116112ed576112dd81836116b3565b9490386118c4565b60e036600319011261019057610019600435611aa981611081565b602435611ab581611081565b60443590611ac282611081565b60a43590611acf82611595565b60c43592611adc84611595565b6040519463199194eb60e21b60208701526001600160a01b0392838092166024880152166044860152166064840152606435608484015260843560a4840152151560c4830152151560e482015260e4815261093a8161167b565b90604060031983011261019057600435611b4f81611081565b91602435906001600160401b03821161019057611b6e91600401610160565b9091565b634e487b7160e01b600052602160045260246000fd5b906005821015611b955752565b611b72565b80516001600160a01b031682529060208201516020820152611bcc604083015160408301906001600160a01b03169052565b60608201516060820152611bf0608083015160808301906001600160a01b03169052565b610340611c0c60a08401516103608060a08601528401906101b8565b9260c081015160c084015260e081015160e0840152611c4a6101008083015190850190602090816001600160801b0391828151168552015116910152565b6101208101516101409081850152810151610160908185015281015161018090818501528101516101a090818501528101516101c090818501528101516101e09081850152810151610200908185015281015161022090818501528101516102409081850152810151611cc36102609182860190611b88565b810151611cde61028091828601906001600160a01b03169052565b810151611cf96102a091828601906001600160a01b03169052565b8101516102c09081850152810151611d176102e09182860190611b88565b810151611d3261030091828601906001600160a01b03169052565b81015190611d4e61032092838601906001600160a01b03169052565b015191015290565b602080820190808352835180925260409283810182858560051b8401019601946000925b858410611d8b575050505050505090565b909192939495968580600192603f198582030187528a5190610100611db98351610120808552840190611b9a565b9284810151856001600160401b039182815116828701520151168984015288810151606090818501528101516080908185015281015160a09081850152810151611e1060c091828601906001600160a01b03169052565b8101519060e091828501520151910152990194019401929594939190611d7a565b3461019057611e3f36611b36565b90611e4982612b78565b91604091611e59835194856116b3565b8184526020918285019060051b820191368311610190578390915b8383106121cc5750505050825190611e8b82614681565b93611e94612b8f565b5060005b838110611eac578451806102b38882611d56565b611ec96103f2611ebc8385613871565b516001600160a01b031690565b906001600160a01b03611ede8184168a613e58565b611ee8838a613871565b51528651632c9f039d60e21b81526004939088818681855afa8015610475576000918291612199575b50611f3f90611f30611f216116d4565b6001600160401b039094168452565b6001600160401b031682890152565b86611f4a858c613871565b510152875163f791395d60e01b815286818681855afa9081156104755760009161217c575b5088611f7b858c613871565b510152875163358cd68b60e11b815286818681855afa9081156104755760009161215f575b506060611fad858c613871565b510152875163bde39c5d60e01b815286818681855afa90811561047557600091612142575b506080611fdf858c613871565b510152875163c1ad5c8d60e01b815286818681855afa918215610475578592858c8a9460009361211a575b5060e09161201791613871565b5101528951636c3d8b8f60e01b815292839182905afa908115610475576000916120fd575b508751631848f2bf60e31b8152911685828581845afa918215610475578692612084916000916120e0575b5060a0612074868d613871565b5101906001600160a01b03169052565b875163e6abad4960e01b815293849182905afa8015610475576120be926000916120c3575b5060c06120b6838a613871565b510152612c5e565b611e98565b6120da9150853d8711610a3057610a2181836116b3565b386120a9565b6120f79150843d861161129c5761128e81836116b3565b38612067565b6121149150863d881161129c5761128e81836116b3565b3861203c565b6120179193509161213960e093873d8911610a3057610a2181836116b3565b9391509161200a565b6121599150873d8911610a3057610a2181836116b3565b38611fd2565b6121769150873d8911610a3057610a2181836116b3565b38611fa0565b6121939150873d8911610a3057610a2181836116b3565b38611f6f565b611f3f92506121be91508a3d8c116121c5575b6121b681836116b3565b810190614717565b9091611f11565b503d6121ac565b819083356121d981611081565b8152019101908390611e74565b600091031261019057565b346101905760008060031936011261224c5761220b612b20565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b6101003660031901126101905760043561226881611081565b60243561227481611081565b6044359161228183611081565b60c43561228d81611595565b60e435936001600160401b0393848611610190573660238701121561019057856004013594851161019057366024868801011161019057602461001996019360a435926084359260643592613b60565b346101905760003660031901126101905760206001600160a01b0360005416604051908152f35b61ffff81160361019057565b359061159382612304565b610140806003193601126101905760043561233581611081565b60243561234181611081565b6064359161234e83612304565b60e435916001600160401b03831161019057610019946123ea61237861093a953690600401611749565b6101049283359361238885611081565b61ffff604051998a98632731bbc560e21b60208b01526001600160a01b03988980921660248c01521660448a015260443560648a015216608488015260843560a488015260a43560c488015260c43560e48801528601526101648501906101b8565b916101249116818401523561014483015203601f1981018352826116b3565b346101905760408060031936011261019057806001600160a01b039160043561243181611081565b612439612b8f565b50600482518095819363020a17bd60e61b8352165afa918215610475576102b3926124919160009081926124a0575b50835191612475836115d8565b6001600160801b03809216835216602082015260243590612c6d565b90519081529081906020820190565b90506124b99150833d85116112ed576112dd81836116b3565b9038612468565b60c0366003190112610190576100196004356124db81611081565b602435906124e882611081565b6084356124f481611595565b60a4359161250183611595565b6040519363cc5e316360e01b60208601526001600160a01b03809216602486015216604484015260443560648401526064356084840152151560a4830152151560c482015260c4815261093a816115f3565b346101905760003660031901126101905760206001600160a01b0360025416604051908152f35b60a03660031901126101905761001960043561259581611081565b602435906125a282611081565b6064356125ae81611595565b608435916125bb83611595565b604051936301bdbad760e71b60208601526001600160a01b038092166024860152166044840152604435606484015215156084830152151560a482015260a4815261093a81611645565b602080820190808352835180925260409283810182858560051b8401019601946000925b85841061263a575050505050505090565b909192939495968580600192603f198582030187528a519060c06001600160801b038861266f855160e0808752860190611b9a565b946126968782015188870190602090816001600160801b0391828151168552015116910152565b81810151906060918287015201516001600160401b03808251166080870152878201511660a0860152015116910152990194019401929594939190612629565b34610190576126e436611b36565b90916126ef82612b78565b916040936126ff855194856116b3565b8184526020918285019060051b820191368311610190578390915b83831061292f575050505082519161273183613ccf565b9361273a612b8f565b50612743613cb0565b5060005b84811061275b578651806102b38882612605565b61276b6103f2611ebc8385613871565b9061277f6001600160a01b03831685613e58565b6127898289613871565b5152875163f9557ccb60e01b815260049089818381875afa801561047557600091829161290c575b506127df906127d06127c16116d4565b6001600160801b039094168452565b6001600160801b031682890152565b866127ea848b613871565b51015288516370a0823160e01b81526001600160a01b0386168282019081528790829081906020010381875afa908115610475576000916128ef575b5089612832848b613871565b510152885192838092632c9f039d60e21b825260609586935afa928315610475576128ae93600092839084926128b3575b50906128956128a4926128866128776116e1565b6001600160401b039097168752565b6001600160401b0316858b0152565b6001600160801b0316838c0152565b6120b6838a613871565b612747565b61289594506128a492506128dd9150833d85116128e8575b6128d581836116b3565b810190613d65565b919490919250612863565b503d6128cb565b6129069150873d8911610a3057610a2181836116b3565b38612826565b6127df925061292891508b3d8d116112ed576112dd81836116b3565b90916127b1565b8190833561293c81611081565b815201910190839061271a565b6101003660031901126101905761001960043561296581611081565b6024359061297282611081565b60a43561297e81611595565b60c4359061298b82611595565b60e4359261299884611595565b6040519463749095b960e11b60208701526001600160a01b0380921660248701521660448501526044356064850152606435608485015260843560a4850152151560c4840152151560e483015261010490151581830152815261093a81611697565b3461019057604036600319011261019057600435612a1781611081565b60243590612a2482611081565b6001600160a01b03809116600052600160205260406000209116600052602052602060ff604060002054166040519015158152f35b3461019057602036600319011261019057600435612a7681611081565b612a7e612b20565b6001600160a01b038091168015612acc57600080546001600160a01b03198116831782559092167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6001600160a01b03600054163303612b3457565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160401b0381116115d35760051b60200190565b60405190612b9c826115d8565b60006020838281520152565b51906001600160801b038216820361019057565b919082604091031261019057612bdd6020612bd684612ba8565b9301612ba8565b90565b6040513d6000823e3d90fd5b908160209103126101905751612bdd81611081565b90816020910312610190575190565b634e487b7160e01b600052601160045260246000fd5b81810292918115918404141715612c3957565b612c10565b8115612c48570490565b634e487b7160e01b600052601260045260246000fd5b6000198114612c395760010190565b60208101906001600160801b03908183511615600014612c8d5750505090565b612bdd938261155f92511690612c26565b91908201809211612c3957565b90612cb582612b78565b6040612cc3815192836116b3565b8382528193612cd4601f1991612b78565b0191600091825b848110612ce9575050505050565b6020908251612cf7816115d8565b85815282606081830152828601015201612cdb565b634e487b7160e01b600052603260045260246000fd5b9190811015612d445760051b81013590609e1981360301821215610190570190565b612d0c565b35612bdd81611595565b903590601e198136030182121561019057018035906001600160401b0382116101905760200191813603831361019057565b90611593604e60405180947f4d61676e6574617256323a204d697373696e672063616c6c20666f722061637460208301526d0d2dedc40eed2e8d040d2dcc8caf60931b6040830152612de08151809260208686019101610195565b810103602e8101855201836116b3565b906020612bdd9281815201906101b8565b15612e095750565b60405162461bcd60e51b81526020600482015290819061103e9060248301906101b8565b35612bdd81612304565b909291928360041161019057831161019057600401916003190190565b908161010091031261019057612ed660e060405192612e72846115f3565b8035612e7d81611081565b8452612e8b60208201611588565b6020850152604081013560408501526060810135606085015260808101356080850152612eba60a0820161159f565b60a0850152612ecb60c0820161159f565b60c08501520161159f565b60e082015290565b90816060910312610190576040805191612ef78361160f565b8035612f0281611081565b83526020810135612f1281611081565b60208401520135604082015290565b91909161010081840312610190578035612f3a81611081565b926020820135612f4981611081565b926040830135926060810135926080820135612f6481611595565b9260a0830135612f7381611595565b9260c0810135612f8281611595565b9260e08201356001600160401b03811161019057612bdd9201611749565b949290612bdd979694926001600160a01b0380921687521660208601526040850152606084015260006080840152151560a0830152151560c0820152610100908160e082015201906101b8565b908160a0910312610190576080604051916130078361162a565b803561301281611081565b8352602081013561302281611081565b602084015260408101356040840152606081013561303f81611595565b6060840152013561304f81611595565b608082015290565b9060e08282031261019057813561306d81611081565b92602083013592604081013592606082013592608083013561308e81612304565b9260a081013561309d81611081565b9260c08201356001600160401b03811161019057612bdd9201611749565b35612bdd81611081565b939460e09561ffff9294612bdd9998946001600160a01b0380971688526020880152604087015260608601521660808401521660a08201528160c082015201906101b8565b919082604091031261019057604051613122816115d8565b60208082948035845201359161313783611081565b0152565b9061010082820312610190576131b19060c06040519361315a85611645565b803561316581611081565b8552602081013561317581611081565b602086015260408101356040860152606081013560608601526080810135608086015260a08101356131a681612304565b60a08601520161310a565b60c082015290565b929460c09461ffff93999896611593989361010087019b6001600160a01b0380921688521660208701526040860152606085015260808401521660a082015201906001600160a01b036020809280518552015116910152565b91908260e09103126101905760405161322a81611645565b60c0808294803561323a81611595565b84526020810135602085015260408101356040850152606081013561325e81611081565b6060850152608081013561327181611081565b608085015260a081013561328481611595565b60a08501520135910152565b359060ff8216820361019057565b81601f82011215610190578035906132b582612b78565b926040906132c5825195866116b3565b838552602091828601918361016080970286010194818611610190578401925b8584106132f6575050505050505090565b86848303126101905784879161330a6116ee565b6133138761159f565b815261332083880161159f565b8382015261332f868801611588565b86820152606061334081890161159f565b908201526080613351818901611588565b9082015260a0613362818901611588565b9082015260c0808801359082015260e08088013590820152610100613388818901613290565b90820152610120808801359082015261014080880135908201528152019301926132e5565b919060a08382031261019057604051906133c68261162a565b819380356133d381611595565b83526020810135602084015260408101356133ed81611595565b6040840152606081013561340081612304565b60608401526080810135916001600160401b038311610190576080926134269201611749565b910152565b91906101c0838203126101905761344183611588565b9261344e60208201611588565b9261345b60408301612310565b9261346860608401611588565b926134768260808301613212565b926001600160401b0391610160810135838111610190578461349991830161329e565b9361018082013584811161019057816134b39184016133ad565b936101a083013590811161019057612bdd9201611749565b90815180825260208080930193019160005b8281106134eb575050505090565b9091929382610160600192875161350482825115159052565b808401511515828501526040818101516001600160a01b0316908301526060818101511515908301526080818101516001600160a01b03169083015260a0818101516001600160a01b03169083015260c0818101519083015260e080820151908301526101008082015160ff169083015261012081810151908301526101409081015190820152019501939291016134dd565b9060a06080612bdd938051151584526020810151602085015260408101511515604085015261ffff606082015116606085015201519181608082015201906101b8565b969394612bdd98969260c09261367e9761ffff61366f978c60206001600160a01b038097818098168452169101521660408c01521660608a01528151151560808a0152602082015160a08a01526040820151838a01528060608301511660e08a015260808201511661010089015260a0810151151561012089015201516101408701526101c0806101608801528601906134cb565b90848203610180860152613597565b916101a08184039101526101b8565b9190826080910312610190576040516136a581611660565b6060808294803584526020810135602085015260408101356136c681611081565b604085015201359161313783611081565b9061018082820312610190576136ec82611588565b926136f960208401611588565b9261370660408201612310565b926001600160401b0360608301358181116101905782613727918501611749565b93613735836080860161368d565b93610100810135838111610190578461374f9183016133ad565b9361375e81610120840161310a565b9361016083013590811161019057612bdd920161329e565b949160606137b961380c9661ffff6137ed97612bdd9d9b966001600160a01b0396878092168d521660208c01521660408a015261018080848b01528901906101b8565b9380516080890152602081015160a08901528260408201511660c089015201511660e0860152848203610100860152613597565b84516101208401526020909401516001600160a01b0316610140830152565b6101608184039101526134cb565b908160809103126101905760606040519161383483611660565b803561383f81611081565b8352602081013561384f81611081565b6020840152604081013561386281611595565b60408401520135606082015290565b8051821015612d445760209160051b010190565b90916101208284031261019057813561389d81611081565b9260208301356138ac81611081565b9260408101359260608201356138c181612304565b9260808301359260a08101359260c08201359260e08301356001600160401b03811161019057610100916138f6918501611749565b920135612bdd81611081565b9692610120989461ffff9161395997939d9c9b9d9894986001600160a01b03998a8092168c521660208b015260408a0152166060880152608087015260a086015260c08501526101408060e08601528401906101b8565b95166101008201520152565b9190826040910312610190576020825192015190565b908160a0910312610190576080604051916139958361162a565b80356139a081611081565b835260208101356139b081611081565b602084015260408101356139c381611595565b6040840152606081013560608401520135608082015290565b908160a0910312610190576080604051916139f68361162a565b803583526020810135613a0881611081565b602084015260408101356139c381611081565b91909160a081840312610190578035613a3381611081565b926020820135613a4281612304565b9260408301359260608101359260808201356001600160401b03928382116101905701906060828203126101905760405192613a7d8461160f565b8235613a8881611081565b84526020830135613a9881611081565b6020850152604083013590811161019057613ab39201611749565b604082015290565b9390612bdd95916101009461ffff6040956001600160a01b03809516895216602088015284870152606086015260a060808601528082511660a086015260208201511660c0850152015191606060e082015201906101b8565b15613b1b57565b60405162461bcd60e51b815260206004820152601a60248201527f4d61676e6574617256323a2076616c7565206d69736d617463680000000000006044820152606490fd5b96949192613bee98949161093a9794604051996340ae097560e11b60208c01526001600160a01b03928380921660248d01521660448b0152166064890152608488015260a487015260c4860152151560e4850152610100610104850152836101249180838301528061014494858401376000828201850152601f01601f1916810103908101845201826116b3565b50565b613bf961170e565b906000808352806020840152806040840152806060840152806080840152606060a08401528060c08401528060e0840152613c32612b8f565b61010084015280610120840152806101408401528061016084015280610180840152806101a0840152806101c0840152806101e08401528061020084015280610220840152806102408401528061026084015280610280840152806102a0840152806102c0840152806102e084015280610300840152610320830152565b60405190613cbd8261160f565b60006040838281528260208201520152565b90613cd982612b78565b604090613ce8825191826116b3565b8381528093613cf9601f1991612b78565b0191600091825b848110613d0e575050505050565b6020908351613d1c81611660565b613d24613bf1565b8152613d2e612b8f565b8390818301528686830152613d41613cb0565b6060830152828501015201613d00565b51906001600160401b038216820361019057565b9081606091031261019057613d7981613d51565b91612bdd6040612bd660208501613d51565b90929192613d988161172e565b91613da660405193846116b3565b829482845282820111610190576020611593930190610195565b602081830312610190578051906001600160401b03821161019057019080601f83011215610190578151612bdd92602001613d8b565b91908260409103126101905760208251613e0f81611595565b92015190565b9190826080910312610190578151600581101561019057916020810151613e3b81611081565b9160606040830151613e0f81611081565b6005821015611b955752565b613e60613bf1565b50613e69612b8f565b50613e72613bf1565b916001600160a01b03809116604080519163d8dfeb4560e01b835260209360049385818681865afa801561047557613eba91600091614664575b506001600160a01b03168852565b82516338d52e0f60e01b815285818681865afa801561047557613eef91600091614647575b506001600160a01b031688850152565b82516307dc0d1d60e41b808252909686888781875afa97881561047557600098614628575b50613f2e8360809916898b01906001600160a01b03169052565b84516374645ff360e01b80825291906000818981895afa9081156104755760009161460f575b5060a08b0152855163473e3ce760e01b815288818981895afa908115610475576000916145f2575b5060c08b01528551631c9e379b60e01b81526001600160a01b0382168882019081528990829081906020010381895afa908115610475576000916145d5575b5060e08b0152855163020a17bd60e61b81529086828981895afa90811561047557614039928a9260009182916145b2575b5061400b90613ffc6127c16116d4565b6001600160801b031682850152565b6101008d01528751809381926324720b1f60e11b83528b83019190916001600160a01b036020820193169052565b0381885afa90811561047557600091614595575b506101208a01528451633ba0b9a960e01b815287818881885afa90811561047557600091614578575b506101408a0152845182815287818881885afa9081156104755760009161455b575b5085518281526000818981895afa8015610475576140d6928892600092614540575b508987845180968195829463eeb8a8d360e01b84528301612df0565b0392165afa90811561047557600091614511575b506101808a0152845191825286828781875afa918215610475576000926144f2575b5084519081526000818781875afa908115610475578392889261414c926000916144d1575b508751948580948193630d39bbef60e41b83528c8301612df0565b0392165afa908115610475576000916144b4575b5061016088015282516340626d8b60e01b815285818681865afa90811561047557600091614497575b506101a0880152825163226f120560e11b81529480868681865afa95861561047557600096614478575b506060880195865283516377607a1760e11b815281818781875afa938415610475578691600095614457575b508290818b0195865286519283809263de40657760e01b82525afa9182156104755760009261443a575b50501690805183519084828061423163092ada2b60e31b948583528a83019190602083019252565b0381875afa90811561047557614273928692600091829161441b575b506101e08c01526101c08b01528751908251938492839283528983019190602083019252565b0381865afa80156104755760009182916143fc575b50610220890152610200880152518251630cf35bdd60e41b8082528186019283529094918790869081906020010381865afa9586156104755761431888966143309860009081908d839184906143c6575b61430e94955081610280916102a06142fd9594015201906001600160a01b03169052565b6001600160a01b03166102608d0152565b6102408b01613e4c565b51935195869485938493845283019190602083019252565b03915afa90811561047557612bdd92600092839284928592614384575b50506103208601526001600160a01b031661030085015261437a905b6001600160a01b03166102e0850152565b6102c08301613e4c565b614369955061437a94506143b1935080919250903d106143bf575b6143a981836116b3565b810190613e15565b92949193509190829061434d565b503d61439f565b5091505061430e91506142fd6143eb610280948c8d3d106143bf576143a981836116b3565b9296508695509093909250906142d9565b90506144159150843d86116106eb576106db81836116b3565b38614288565b90506144349150833d85116106eb576106db81836116b3565b3861424d565b6144509250803d1061129c5761128e81836116b3565b3880614209565b8391955061447190823d8411610a3057610a2181836116b3565b94906141df565b816144909297503d8811610a3057610a2181836116b3565b94386141b3565b6144ae9150863d8811610a3057610a2181836116b3565b38614189565b6144cb9150863d8811610a3057610a2181836116b3565b38614160565b6144ec913d8091833e6144e481836116b3565b810190613dc0565b38614131565b61450a919250873d891161129c5761128e81836116b3565b903861410c565b6145319150863d8811614539575b61452981836116b3565b810190613df6565b9050386140ea565b503d61451f565b61455491923d8091833e6144e481836116b3565b90386140ba565b6145729150883d8a1161129c5761128e81836116b3565b38614098565b61458f9150883d8a11610a3057610a2181836116b3565b38614076565b6145ac9150883d8a11610a3057610a2181836116b3565b3861404d565b61400b92506145ce91508a3d8c116112ed576112dd81836116b3565b9091613fec565b6145ec9150893d8b11610a3057610a2181836116b3565b38613fbb565b6146099150893d8b11610a3057610a2181836116b3565b38613f7c565b614622913d8091833e6144e481836116b3565b38613f54565b614640919850873d891161129c5761128e81836116b3565b9638613f14565b61465e9150873d891161129c5761128e81836116b3565b38613edf565b61467b9150873d891161129c5761128e81836116b3565b38613eac565b9061468b82612b78565b60409061469a825191826116b3565b83815280936146ab601f1991612b78565b019160005b8381106146bd5750505050565b60209082516146cb816115f3565b6146d3613bf1565b81526146dd612b8f565b8390818301526000858301526000606083015260006080830152600060a0830152600060c0830152600060e08301528286010152016146b0565b919082604091031261019057612bdd602061473184613d51565b9301613d51565b908092918237016000815290565b3d15614771573d906147578261172e565b9161476560405193846116b3565b82523d6000602084013e565b606090565b826004116101905760e0600319838581010301126101905760009283809361480f6001600160a01b036040516147ab81611645565b6004840135906147ba82611081565b81815260248501356147cb81611081565b602082015260448501356040820152606485013560608201526147f060848601613290565b608082015260a485013560a082015260c060c486013591015216614a1a565b61481e60405180948193614738565b03925af19061482b614746565b91159081614841575b5061483c5750565b614968565b90501538614834565b60c092614858818085612e37565b9080959181010312610190576040519360c08501938585106001600160401b038611176115d35761480f6001600160a01b0360009793889794889560405260a0808335936148a585611081565b84845260208101356148b681611081565b6020850152604081013560408501526148d160608201613290565b606085015260808101356080850152013591015216614a1a565b6001600160a01b0360025416801561492357816000929160208493519201905af490614915614746565b911561491d57565b50614968565b60405162461bcd60e51b815260206004820152601c60248201527f4d61676e6574617256323a206d6f64756c65206e6f7420666f756e64000000006044820152606490fd5b60448151106149d557600481015181019060208160248401930312610190576024810151906001600160401b0382116101905701816043820112156101905761103e9181604460246149bd9401519101613d8b565b60405162461bcd60e51b815291829160048301612df0565b60405162461bcd60e51b815260206004820152601a60248201527f4d61676e6574617256323a20526561736f6e20756e6b6e6f776e0000000000006044820152606490fd5b6001600160a01b0333911603614a2c57565b60405162461bcd60e51b815260206004820152602160248201527f4d61676e6574617256323a206f70657261746f72206e6f7420617070726f76656044820152601960fa1b6064820152608490fdfea26469706673582212201b9dd699ad9f6b8cfd79256a23a6fc6db67afce56354eb7fbe38f448c03d4f2264736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000040282d3cf4890d9806bc1853e97a59c93d8136530000000000000000000000000880d1ee15cf3d63e729e1cbb87df0e515b1af09
-----Decoded View---------------
Arg [0] : _owner (address): 0x40282d3Cf4890D9806BC1853e97a59C93D813653
Arg [1] : _marketModule (address): 0x0880d1EE15CF3D63E729e1cBb87Df0e515B1AF09
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000040282d3cf4890d9806bc1853e97a59c93d813653
Arg [1] : 0000000000000000000000000880d1ee15cf3d63e729e1cbb87df0e515b1af09
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.